/*******************************************************************************
*         McStas instrument definition URL=http://www.mcstas.org
*
* Instrument: RTP_SANS
*
* %Identification
* Written by: E. Farhi and Megat Harun Al-Rashid
* Date: June 2014
* Origin: ILL/RTP
* %INSTRUMENT_SITE: TRIGA
*
* The SANS instrument installed at Reactor TRIGA PUSPATI (Malaysia)
*
* %Description
* This is a 4m long SANS installed on a radial beam port 4 at the Reactor TRIGA
* PUSPATI (RTP). Te beam port 4 is a radial tube that originates from the core,
* through the graphite reflector. A thick Be filter selects the cold tail of the
* thermal spectrum, and removes higher order PG reflections.
* A PG(002) monochromator selects the 5A neutrons that are sent into a 4m - 4m
* SANS with a 60 cm PSD detector 128x128 pixels.
* The monochromator is here used in fixed double focusing geometry.
* The accessible Q range is then 0.01-0.1 Angs-1.
*
* This model contains a detailed description of the Be filter, monochromator
* and SANS set-up. The Be filter is in the monochromator block.
*
* Example: mcrun RTP_SANS.instr lambda=5
*
* %Parameters
* lambda: [Angs]        monochromator selected wavelength
* dlambda: [Angs]       monochromator wavelength spread
* DM: [Angs]            d-spacing for the monochromator reflection
* Mono_tilt: [deg]      angle tilt between the 3 monochromator layers
* mono_rotation: [deg]  additional monochromator offset rotation for e.g rocking curves
* Be_Filter_depth: [m]  Depth of Be filter
*
* %Link
* <a href="http://www.nuclearmalaysia.gov.my/Plant&Facilities/reactor.php">Nuclear Malaysia</a>
* %Link
* M. Sufi et al., J. AppL Cryst. (1997). 30, 884-888 [doi:10.1107/S0021889897001738]
*
* %End
*******************************************************************************/
DEFINE INSTRUMENT RTP_SANS(lambda=5, DM=3.355, dlambda=.2, Be_Filter_depth=.15, Mono_tilt=-1, mono_rotation=0)

/* 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,L;
%}

USERVARS
%{
  double mono_index;
%}

/* The INITIALIZE section is executed when the simulation starts     */
/* (C code). You may use them as component parameter values.         */
INITIALIZE
%{
  /* monochromator rotation angle for Bragg reflection [deg] */
  A1 = asin(lambda/2/DM)*RAD2DEG;
  /* distance used for focusing [m] */
  L  = 4;

  printf("RTP_SANS: Monochromator take-off angle=%g [deg]\n", 2*A1);
%}

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

/* The Arm() class component defines reference points and orientations  */
/* in 3D space. Every component instance must have a unique name. Here, */
/* Origin is used. This Arm() component is set to define the origin of  */
/* our global coordinate system (AT (0,0,0) ABSOLUTE). It may be used   */
/* for further RELATIVE reference, Other useful keywords are : ROTATED  */
/* EXTEND GROUP PREVIOUS. Also think about adding a neutron source !    */
/* Progress_bar is an Arm displaying simulation progress.               */
COMPONENT Origin = Progress_bar()
  AT (0,0,0) ABSOLUTE

/* the source is focused in wavelength to provide 5 Angs neutrons */
/* to study the Be filter, use white beam e.g. dlambda = 4.5      */
COMPONENT source = Source_gen(
    radius = .154/2,
    dist = 1.16+1.50, focus_xw = .082, focus_yh = .09, lambda0 = 5,
    dlambda = dlambda, I1 = 2.79e12/25, T1 = 300)
  AT (0, 0, 0) RELATIVE Origin

COMPONENT source_monitor = Monitor_nD(
  xwidth=.154, yheight=.154, options="x y")
  AT (0, 0, 0.01) RELATIVE Origin

COMPONENT CoarseCollimator1 = Guide(w1=.154, h1=.154, l=1.16125,m=0)
  AT (0, 0, 0.01) RELATIVE PREVIOUS

COMPONENT CoarseCollimator2 = Guide(w1=.11, h1=.11, l=1.5,m=0)
  AT (0, 0, 1.16125+0.003) RELATIVE PREVIOUS

/* a slit that also detects wavelength */
COMPONENT lmon = Monitor_nD(
  xwidth=.11, options="slit disk, auto wavelength", bins=50)
  AT (0, 0, 1.5+0.01) RELATIVE PREVIOUS

/* Be filter ---------------------------------------------------------------- */
COMPONENT Be_Position = Arm()
  AT (0, 0, .147+.15/2) RELATIVE PREVIOUS

COMPONENT Be_Cryostat = PowderN(
  yheight=.2, radius=.144, thickness=.002,
  reflections = "Al.lau", concentric=1, p_transmit=.95, p_inc=1e-4)
  AT (0,0,0) RELATIVE Be_Position

COMPONENT Be_Filter = PowderN(
  xwidth=.15, yheight=.15, zdepth=Be_Filter_depth, reflections="Be.laz", p_inc=1e-4)
  AT (0,0,0) RELATIVE Be_Position

COMPONENT Be_Cryostat_out = COPY(Be_Cryostat)(concentric=0)
  AT (0,0,0) RELATIVE Be_Position

COMPONENT lmo_afterBe = Monitor_nD(
  xwidth=.082, yheight=0.09, options="slit, auto wavelength", bins=50)
  AT (0, 0, .145+.15/2+1e-3) RELATIVE Be_Position

/* monochromator ------------------------------------------------------------ */
SPLIT COMPONENT mono_cradle = Arm()
  AT (0, 0, .145+.15/2+.176) RELATIVE Be_Position

COMPONENT mono_rotation = Arm()
  AT (0, 0, 0) RELATIVE mono_cradle
  ROTATED (0, -A1+mono_rotation, 0) RELATIVE mono_cradle
  EXTEND %{
    mono_index=0;
  %}

COMPONENT mono1 = Monochromator_curved(
    width=.11, height=.09, NH=2,NV=3,
    RV=2*L*sin(DEG2RAD*A1), RV=2*L/sin(DEG2RAD*A1),
    DM=DM, mosaich=48, mosaicv=48,
    reflect="HOPG.rfl" ,transmit="HOPG.trm")
  AT (-.01, 0, 0) RELATIVE mono_rotation
  ROTATED (0, Mono_tilt, 0) RELATIVE mono_rotation
  EXTEND %{
    if (SCATTERED) mono_index=1;
  %}

COMPONENT mono2 = COPY(mono1)
  AT (0, 0, 0) RELATIVE mono_rotation
  ROTATED (0, 0, 0) RELATIVE mono_rotation
  EXTEND %{
    if (SCATTERED) mono_index=2;
  %}

COMPONENT mono3 = COPY(mono1)
  AT (0.01, 0, 0) RELATIVE mono_rotation
  ROTATED (0, -Mono_tilt, 0) RELATIVE mono_rotation
  EXTEND %{
    if (SCATTERED) mono_index=3;
  %}

COMPONENT mono_takeoff = Arm()
  AT (0, 0, 0) RELATIVE mono_cradle
  ROTATED (0, -2*A1, 0) RELATIVE mono_cradle

COMPONENT psd_transmit = Monitor_nD(xwidth=.12, yheight=.12, options="x y", bins=50)
  AT (0, 0, 0.25) RELATIVE mono_cradle
  GROUP mono_rt

/* primary collimator (flight path) 3.8 m ----------------------------------- */
COMPONENT psd_reflect = Monitor_nD(xwidth=.12, yheight=.12, options="x y", bins=50)
  AT (0, 0, 0.574) RELATIVE mono_takeoff
  GROUP mono_rt
  EXTEND %{
    if (!mono_index) ABSORB;
  %}

COMPONENT lmon_reflect2 = Monitor_nD(
  xwidth=.05, yheight=.05,
  options="disk, auto wavelength", bins=50)
  AT (0, 0, 0.575) RELATIVE mono_takeoff

/*COMPONENT lmon_reflect = Monitor_nD(
  xwidth=.02, yheight=.02, user1=mono_index,
  options="disk slit, auto wavelength, user1 limits=[0 4]", bins=50)
  AT (0, 0, 0.575+1e-4) RELATIVE mono_takeoff*/

COMPONENT coll1=Guide(w1=.05,h1=.05,l=3.8)
  AT (0, 0, 0.575+1e-3) RELATIVE mono_takeoff

COMPONENT sample_psd = Monitor_nD(
  xwidth=.02, yheight=.02, options="disk slit, x y", bins=50)
  AT (0, 0, 0.575+3.80+1e-2) RELATIVE mono_takeoff

/* sample ------------------------------------------------------------------- */
/* from JAC 1997: flux at sample = 3900 n/s/cm2 */
SPLIT 100 COMPONENT sample = Sans_spheres(
  R = 100, Phi = 1e-3, Delta_rho = 0.6,
  sigma_abs = 0.5, xwidth=0.01, yheight=0.01, zdepth=0.005)
  AT (0, 0, .575+3.80+.10) RELATIVE mono_takeoff
EXTEND %{
 if (!SCATTERED) ABSORB;
%}

/* secondary flight path (detector tube) 4m --------------------------------- */
COMPONENT det = Monitor_nD(xwidth=.6, yheight=.6, bins=128, options="x y slit")
  AT (0, 0, 3.8) RELATIVE sample

COMPONENT PSDrad = PSD_monitor_rad(
    filename = "psd2.dat", filename_av = "psd2_av.dat", rmax = 0.45)
  AT (0, 0, 1e-2) RELATIVE det

COMPONENT det_tube = Shape(radius=1, yheight=4)
  AT (0, 0, .1+4/2) RELATIVE sample
  ROTATED (90,0,0) RELATIVE sample

COMPONENT reactor = Shape(radius=.7/2, yheight=.4)
  AT (0,0,-.35) RELATIVE Origin

/* This section is executed when the simulation ends (C code). Other    */
/* optional sections are : SAVE                                         */
FINALLY
%{
%}
/* The END token marks the instrument definition end */
END
