/*******************************************************************************
*         McStas instrument definition URL=http://www.mcstas.org
*
* Instrument: Template monochromator Diffractometer
*
* %Identification
* Written by: E. Farhi
* Date: 13 Apr 2006
* Origin: LLB/ILL
* %INSTRUMENT_SITE: Templates
*
* Simple monochromator Diffractometer for powders
*
* %Description
* A template powder diffractometer used as a tutorial at LLB.
* Default geometry is from D20@ILL.
*
* If included after a guide, use ALPHA1=0 and L1=0 (the first collimator is then
* the guide with effective ALPHA1=m*0.1*lambda). If you prefer to include
* explicitely a collimator before the monochromator, use L1=1.2.
*
* Monochromator lattice parameter
* PG       002 DM=3.355 AA (Highly Oriented Pyrolythic Graphite)
* PG       004 DM=1.607 AA
* Heusler  111 DM=3.362 AA (Cu2MnAl)
* CoFe         DM=1.771 AA (Co0.92Fe0.08)
* Ge       111 DM=3.266 AA
* Ge       311 DM=1.714 AA
* Ge       511 DM=1.089 AA
* Ge       533 DM=0.863 AA
* Si       111 DM=3.135 AA
* Cu       111 DM=2.087 AA
* Cu       002 DM=1.807 AA
* Cu       220 DM=1.278 AA
* Cu       111 DM=2.095 AA
*
* %Example: lambda=1 Detector: Diff_BananaPSD_I=153038
*
* %Parameters
* lambda: [Angs]  Wavelength at monochromator, computed from DM and THETA_M if left as 0.
* DM: [Angs]      d-spacing of monochromator, computed from lambda and THETA_M if left as 0.
* THETA_M: [deg]  Monochromator take-off angle, computed from lambda and DM if left as 0.
* RV: [m]         Monochromator vertical curvature, 0 for flat, -1 for automatic setting
* L1: [m]         Source-Monochromator distance
* L2: [m]         Monochromator-Sample distance
* L3: [m]         Sample-Detector distance
* ALPHA1: [min]   Horizontal collimator divergence for L1 arm (before monochromator)
* ALPHA2: [min]   Horizontal collimator divergence for L2 arm (monochromator-sample)
* ALPHA3: [min]   Horizontal collimator divergence for L3 arm (sample-detector)
* ETA: [min]      Monochromator horizontal mosaic (gaussian)
* Powder: [str]   File name for powder description
* verbose: [int]  Print DIF configuration. 0 to be quiet
* SM: [int]       Scattering sense of beam from Monochromator. 1:left, -1:right
*
* %End
*******************************************************************************/
DEFINE INSTRUMENT templateDIFF(lambda=1, DM=3.355, string Powder="Na2Ca3Al2F14.laz", RV=-1, L1=17, L2=3.2, L3=1.471, ALPHA1=5,ALPHA2=60,ALPHA3=5, ETA=12, verbose=1, THETA_M=0, SM=1)

DECLARE %{
  char lmonopts[128];
%}

/* The INITIALIZE section is executed when the simulation starts     */
/* (C code). You may use them as component parameter values.         */
INITIALIZE
%{
	double L;
	double KI, Vi, EI;

	if (!THETA_M && lambda && DM)
		THETA_M =asin(lambda/(2*DM))*RAD2DEG;
	else if (THETA_M && !lambda && DM)
		lambda = fabs(sin(THETA_M*DEG2RAD))*2*DM;
	else if (THETA_M && lambda)
		DM = fabs(lambda/sin(DEG2RAD*THETA_M)/2.0);

	THETA_M *= SM; /* take-off direction left or right */

	/* test input parameters */
	if (!THETA_M || !DM || !lambda) exit(fprintf(stderr,
	      "templateDIFF: ERROR: Monochromator take-off, d-spacing or wavelength is null (THETA_M=%g, DM=%g, lambda=%g). Abort.\n",
	      THETA_M, DM, lambda));

	if (L1<1.1) L = L2;
	else        L = 1/(1/L1+1/L2);
	if (RV < 0) RV=fabs(2*L*sin(DEG2RAD*THETA_M));
	KI=2*PI/lambda;
	Vi = K2V*fabs(KI);
	EI = VS2E*Vi*Vi;

	if (ALPHA1< 0) ALPHA1=600;
	if (ALPHA2< 0) ALPHA2=600;
	if (ALPHA3< 0) ALPHA3=600;
	if (ETA<=0)    ETA   =30;

	if (verbose) {
	  printf("templateDIFF: Detailed DIF configuration\n");
	  printf("* Incoming beam: lambda=%.4g [Angs] EI=%.4g [meV]  KI=%.4g [Angs-1] Vi=%g [m/s]\n",
	    lambda, EI, KI, Vi);
	  printf("* Monochromator:  DM=%.4g [Angs] RV=%.4g [m] %s, take-off THETA_M=%.4g [deg]\n",
	    DM, RV, (!RV ? "flat" : "curved"), THETA_M*2);
	}

	RV = fabs(RV)*SM;
	
  sprintf(lmonopts,"lambda limits=[%g %g] bins=100",0.985*lambda,1.025*lambda);
%}

/* Here comes the TRACE section, where the actual      */
/* instrument is defined as a sequence of components.  */
TRACE

REMOVABLE COMPONENT Origin = Progress_bar()
  AT (0,0,0) ABSOLUTE

/* source with constant flux */
REMOVABLE COMPONENT Source = Source_gen(
    radius = 0.11, dist = L1, focus_xw = 0.1*fabs(sin(DEG2RAD*THETA_M)), focus_yh = 0.15,
    lambda0 = lambda, dlambda = lambda*0.01,
    T1=229.6,I1=5.32e13,T2=1102, I2=4.37e12, T3=437.1,I3=3.84e13)
  AT (0, 0, 0) RELATIVE Origin

/* TIP: monochromator cradle */
COMPONENT mono_cradle = Arm()
  AT (0, 0, L1) RELATIVE PREVIOUS

/* ALPHA1 collimator */
COMPONENT Alpha_One = Collimator_linear(
  xwidth = 0.07, yheight = 0.15, length = 0.70, divergence = ALPHA1, transmission = 1.0)
  WHEN (L1>1.1 && ALPHA1 > 0)
  AT (0, 0, -1.045) RELATIVE mono_cradle

COMPONENT Diff_Mono_XY = Monitor_nD(
     options="x y", bins=100,
     bins = 40, xwidth = 0.1, yheight = 0.15, restore_neutron=1)
   WHEN (L1>1.1)
   AT (0, 0, -.1) RELATIVE mono_cradle

COMPONENT Diff_Mono_Lambda = Monitor_nD(
     options=lmonopts,
     bins = 40, xwidth = 0.1, yheight = 0.15, restore_neutron=1)
  WHEN (L1>1.1)
  AT (0, 0, -0.01) RELATIVE mono_cradle

/* TIP: could use curved monochromator with NH>1 NV>1 et RH>0 RV>0 */
SPLIT COMPONENT Monok = Monochromator_curved(
    width = 0.1, height = 0.15, NH = 1, NV = 11, RV=RV,
    mosaich = ETA, mosaicv = 12, DM = DM)
  AT (0, 0, 0) RELATIVE mono_cradle
  ROTATED (0, THETA_M, 0) RELATIVE mono_cradle

/* TIP: positioning diffraction direction for monok (order 1) */
COMPONENT mono_out = Arm()
  AT (0, 0, 0) RELATIVE mono_cradle
  ROTATED (0, 2*THETA_M, 0) RELATIVE mono_cradle

/* ALPHA2 collimator */
COMPONENT Alpha_Two = Collimator_linear(
    xwidth = 0.05, yheight = 0.2, length = 0.2, divergence = ALPHA2, transmission = 1.0)
  WHEN (ALPHA2>0)
  AT (0, 0, L2-0.25) RELATIVE mono_out

COMPONENT Diff_Sample_Lambda = Monitor_nD(
     options=lmonopts,
     bins = 40, xwidth = 0.02, yheight = 0.05, restore_neutron=1)
   AT (0, 0, 0.2) RELATIVE PREVIOUS

COMPONENT Slit_Sample = Slit(xwidth = 0.01, yheight = 0.05)
  AT (0, 0, L2-0.02) RELATIVE mono_out

SPLIT COMPONENT Sample = PowderN(
    reflections = Powder, radius = 0.005,
    yheight = 0.05, d_phi=RAD2DEG*atan2(0.35, L3))
  AT (0, 0, L2) RELATIVE mono_out
EXTEND
%{
  if (!SCATTERED) ABSORB; /* TIP: perfect beamstop */
%}

/* ALPHA3 radial collimator */
COMPONENT collimador_radial = Collimator_radial(
    xwidth=0.015, yheight=.3, length=.30,
    divergence=ALPHA3,transmission=1,
    theta_min=-10, theta_max=160, radius=L3-0.3-0.01)
  WHEN (ALPHA3>0)
	AT (0, 0, 0) RELATIVE Sample

/* perfect detector: 1D(theta) */
COMPONENT Diff_BananaTheta = Monitor_nD(
    options = "banana, theta limits=[-10 160], bins=340",
    radius = L3, yheight = 0.15, restore_neutron=1)
  AT (0, 0, 0) RELATIVE Sample

/* perfect detector: 2D(theta,y) to see diffraction rings */
COMPONENT Diff_BananaPSD = Monitor_nD(
    options = "banana, theta limits=[-10 160] bins=170, y bins=25",
    radius = L3*1.005, yheight = 0.3)
  AT (0, 0, 0) RELATIVE Sample

/* The END token marks the instrument definition end */
END
