/*******************************************************************************
*         McStas instrument definition URL=http://www.mcstas.org
*
* Instrument: ILL_H22_D1A monochromator Diffractometer
*
* %Identification
* Written by: E. Farhi
* Date: 13 Apr 2006
* Origin: ILL
* %INSTRUMENT_SITE: ILL
*
* Simple monochromator Diffractometer for powders (D1A) installed on H22, with
* container/sample environment and radial collimator.
*
* %Description
* D1A is a reliable diffractometer for standard crystallographic problems. It gives
* excellent results with the Rietveld method owing to its near perfect Gaussian
* peak-shape in the 2θ-range 30° to 150°.
*
* Special features include
*   a high fixed take-off angle of 122 deg, giving high resolution at large
*     scattering angles (up to 160 deg);
*   a bank of 25 high efficiency collimators and counters;
*     an anisotropically squashed germanium monochromator focussing a 250
*     mm high beam onto only 30 mm;
*   a wide choice of wavelengths, from 1.39 Angs to 2.99 Angs, quickly available by
*     simple rotation of the focussing monochromator;
*
* The large monochromator take-off angle means that the diffraction pattern is
* focussed for the parallel geometry shown (2θ = 122°). The counter can be swept
* through 0 deg to 2θ = 160° deg for the highest angle counter, usually in steps
* of 0.05 deg.
* Monochromator           Neutron wavelength
* Ge 117 DM=0.7946 AA     1.390
* Ge 335 DM=0.8655 AA     1.514
* Ge 115 DM=1.0925 AA     1.911 (optimal)
* Ge 113 DM=1.712 AA      2.994
*
* The sample is a powder, in a container can, all positioned in an
* Al environment (e.g. cryostat/furnace shield).
*
* This instrument was installed on the H22 guide.
*
* %Example: lambda=1.911 Detector: BananaPSD_I=3.8578E+05
*
* %Parameters
* lambda: [Angs]    Wavelength at monochromator
* DM: [Angs]        d-spacing of monochromator. Use DM=0 to compute the values from the requested wavelength.
* powder: [str]     File name for powder sample description
* container: [str]  File name for container decription in Al cryostat/furnace
* dlambda: [Angs]   Wavelength-spread around lambda at source
* RV: [m]           Radius of vertical focussing. flat for 0	
*
* %End
*******************************************************************************/
DEFINE INSTRUMENT ILL_H22_D1A(lambda=1.911, dlambda=0.03, DM=0, RV=-1, string powder="Na2Ca3Al2F14.laz", string container="V.laz")

/* The DECLARE section allows us to declare variables or  small      */
/* functions in C syntax. These may be used in the whole instrument. */
DECLARE
%{
  double A1; /* rotation of monok and d-spacing */
  double RV; /* vertical curvature of monochromator */
  double verbose=1;
  double L1=0.5, L2=1.25, L3=0.5;
%}

USERVARS
%{
  double flag_container;
  double flag_sample;
  double flag_env;
%}

/* 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;

  A1 =122/2;
  if (!lambda && DM)
    lambda=sin(A1*DEG2RAD)*2*DM;
  else if (lambda && !DM)
    DM=lambda/2/sin(A1*DEG2RAD);

  if (!lambda || !DM)
    exit(printf("%s: ERROR: wavelength and DM are unset. Exit.\n", NAME_INSTRUMENT));

  L = L2; /* assume guide exit L1=Inf */
  if (RV < 0) RV=2*L*sin(DEG2RAD*A1);
  KI=2*PI/lambda;
  Vi = K2V*fabs(KI);
  EI = VS2E*Vi*Vi;
  A1 *= -1;

  if (verbose) {
    printf("%s: Detailed DIF configuration\n", NAME_INSTRUMENT);
    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 A2=%.4g [deg]\n",
      DM, RV, (!RV ? "flat" : "curved"), 2*A1);
    printf("* Sample: %s in %s cylinder container\n", powder, container);
  }

  RV = -fabs(RV);
%}

TRACE

%include "ILL/ILL_H22/ILL_H22.instr"

/* additional horizontal divergence monitor at end of guide */
/* also defines a static position to orient remaining instrument */
COMPONENT D1A_Mono_Dx = Monitor_nD(
  xwidth=0.03, yheight=0.2, restore_neutron=1,
  options="dx, all auto, per cm2, slit", restore_neutron=1)
AT (0, 0, L1) RELATIVE PREVIOUS

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

/* 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.1, NH = 1, NV = 11, RV=RV,
    mosaich = 30, mosaicv = 30, DM = DM)
  AT (0, 0, 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*A1, 0) RELATIVE Origin

COMPONENT Lmon = Monitor_nD(
    bins = 50,options="auto lambda", xwidth = 0.05, yheight = 0.05)
  AT (0, 0, 0.2) RELATIVE mono_out

COMPONENT PSDsample = Monitor_nD(
    bins = 20, options="x y", xwidth = 0.1, yheight = 0.1)
  AT (0, 0, L2-0.1) RELATIVE mono_out

/* sample position ********************************************************** */
SPLIT COMPONENT SamplePos=Arm()
AT (0, 0, L2) RELATIVE mono_out
EXTEND %{
  flag_container=flag_sample=flag_env=0;
%}

COMPONENT Environment_in=PowderN(
  radius = 0.05, yheight = 0.1, thickness=0.002,
  reflections="Al.laz", concentric=1, d_phi=RAD2DEG*atan2(0.5,L3),
  p_transmit=0.95, p_inc=0, barns=1)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  flag_env=SCATTERED;
%}

COMPONENT Container_in=PowderN(radius=0.008/2+1e-4, thickness=1e-4, yheight=0.05,
  reflections=container, concentric=1, d_phi=RAD2DEG*atan2(0.5,L3) ,
  p_transmit=0.93, p_inc=0.05)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  flag_container=SCATTERED;
%}

COMPONENT Sample=PowderN(reflections = powder,
    radius = 0.008/2, yheight = 0.03,
    d_phi=RAD2DEG*atan2(0.5,L3), p_transmit=0.08, p_inc=0.05)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  if (SCATTERED)
    flag_sample=SCATTERED;
%}

COMPONENT Container_out=COPY(Container_in)(concentric=0)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  if (SCATTERED) flag_container=1;
%}

COMPONENT Environment_out=COPY(Environment_in)(concentric=0)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  if (SCATTERED) flag_env=1;
%}

/* sample position (end) **************************************************** */

COMPONENT Collimator=Collimator_radial(xwidth=0, yheight=.25, length=.2,
    divergence=40,transmission=1, nchan=27,
    theta_min=0, theta_max=160, radius=0.25)
  AT (0, 0, 0) RELATIVE SamplePos
EXTEND %{
  if (!flag_sample && !flag_container) ABSORB;
%}

/* perfect detector: 1D(theta) */
COMPONENT BananaTheta = Monitor_nD(
    options = "banana, theta limits=[3 160], bins=380",
    xwidth = L3*2, yheight = 0.15)
  AT (0, 0, 0) RELATIVE SamplePos

/* perfect detector: 2D(theta,y) to see diffraction rings */
COMPONENT BananaPSD = Monitor_nD(
    options = "banana, theta limits=[5 160] bins=380, y bins=25",
    xwidth = L3*2*1.005, yheight = 0.5)
  AT (0, 0, 0) RELATIVE SamplePos

END
