/*******************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright (C) 1997-2008, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Instrument: LLB_6T2
*
* %Identification
* Written by: <a href="mailto:xavier.fabreges@cea.fr">Xavier Fabrèges</a>
* Date: November 5th 2015.
* Origin: <a href="http://www-llb.cea.fr">LLB (France)</a>
* %INSTRUMENT_SITE: LLB
*
* The 6T2 thermal single crystal diffractometer at the LLB.
*
* %Description
* 6T2 is a high flux thermal single crystal diffractometer dedicated to the study of
* complex magnetic structures in condensed matter. Two monochromators are available.
* It works at 0.9 and 2.4AA without polarization and at 1.4AA with incident polarization
* (optional FeCo supermirror) and polarization analysis (P//z).
*
* Monochromators:
* PG       002 DM=3.355 AA (Highly Oriented Pyrolythic Graphite)
* Cu       220 DM=1.278 AA
*
* %Parameters
* lambda: [Angs]  wavelength
* phi: [Deg]      sample rotation along the vertical axis
* gamma: [Deg]    in plane detector position
* nu: [Deg]       out of plane detector position
* monok: [1]      monochromator to use (0: PG, 1: Cu, 5: test mode)
* samp_f: [str]   LAU file describing sample
*
* Example of a C60 200 rocking curve scan:
*    mcrun LLB_6T2.instr --mpi=NUM_CORES -N31 lambda=2.4 phi=8.37,11.37 gamma=19.74 nu=0 monok=0 samp_f="C60.lau" -n 1e8 -d C60_200
*
* %End
*******************************************************************************/
DEFINE INSTRUMENT LLB_6T2(lambda=1.0, phi=0, gamma=0, nu=0, monok=0, string samp_f="C60.lau")

DECLARE
%{
    double f_dist;
    double s_w, s_h, b_in_r, b_out_r, c_w, c_h;
    double b2mon, mon2col, col2samp;
    double b_length, c_length;
    double monoc_ang, monoc_d;
    double l_test;
    double dlambda0;
    double sT1, sT2, sT3, sI1, sI2, sI3;
    double coll_det;
%}

INITIALIZE
%{
	/****************************************************************
	*
	*  SET Source parameters (thermal moderator)
	*
	****************************************************************/
    sT1=313.;	sI1=8.05e12;
    sT2=60.; 	sI2=0.*0.55*0.697674e+13;
    sT3=20. ; 	sI3=0.*0.15*0.697674e+13;
    s_w=0.1;
    s_h=0.15;

    /****************************************************************
	*
	*  SET Distances and dimensions
	*
	****************************************************************/
    // Thermal moderator surface to barillet
    f_dist = 2.91;

    // Barillet in full opening configuration
    b_length = 0.695;
	b_in_r   = 0.10/2.0;
	b_out_r  = 0.12/2.0;

    // Barillet to Monochromator
    b2mon    = 0.75;

    // Monochromator to preliminary collimation
    mon2col = 0.80;

    // Preliminary collimation parameters
    c_length = 0.30;
    c_w      = 0.02;
    c_h      = 0.05;

    // Preliminary collimation to sample position
    col2samp = 1.2;

    /****************************************************************
	*
	*  SET Monochromators parameters
	*
	****************************************************************/
    // Cu Monochromator
    if(monok==1){
    	monoc_d=1.278;
    	monoc_ang=asin(lambda/(2.*monoc_d))*180./PI;
    	dlambda0=lambda/5.;
	}
    // Test mode for debugging purpose
    else if(monok==5){
    	monoc_d=1e4;
    	monoc_ang=20.;
    	lambda=10;
    	dlambda0=lambda;
    }
    // PG Monochromator
    else{
    	monoc_d=3.355;
    	monoc_ang=asin(lambda/(2*monoc_d))*180./PI;
    	dlambda0=lambda/5.;
    }


    /****************************************************************
	*
	*  DISPLAY Errors
	*
	****************************************************************/
    fprintf(stderr,"Monoc_ang=%3.2f\n",monoc_ang);
    if((lambda>=2*monoc_d) || (lambda<0)) exit(printf("Lambda (%g [AA]) out of range (0 -> 6.7 [AA]).\n", lambda));

    // Motors boundaries check
    if((nu>26) || (nu<-5)) exit(printf("nu (%g [Deg]) out of range (-5 -> 26 deg.).\n", nu));
    if((gamma>140) || (gamma<-28)) exit(printf("gamma (%g [Deg]) out of range (-28 -> 140 deg.).\n", gamma));

    /****************************************************************
	*
	*  SET Misceanellous parameters
	*
	****************************************************************/
    // radius of single counter collimator
    coll_det=0.01;
%}

TRACE

COMPONENT Progress = Progress_bar(
    percent = 5)
  AT (0, 0, 0) RELATIVE ABSOLUTE

/****************************************************************
*
*  COMPONENT Source
*
****************************************************************/
// Maxwellian approximation of Orphée thermal moderator
// Harmonic are filtered by PG and Er filters
COMPONENT source = Source_gen(
    yheight=s_h, xwidth=s_w,
    dist=f_dist, focus_xw=b_in_r*2.0, focus_yh = b_in_r*2.0,
    lambda0=lambda, dlambda=dlambda0,
    T1=sT1,I1=sI1,T2=sT2,I2=sI2,T3=sT3,I3=sI3)
AT (0, 0, 0) RELATIVE ABSOLUTE

COMPONENT Pos_1 = Arm(
    )
AT (0,0,f_dist) RELATIVE source
ROTATED (0,0,0) RELATIVE source

// Lambda distribution detector
COMPONENT Lambda_mon=L_monitor(
    xwidth=0.10, yheight=0.15,
    nL=101, filename="Lambda_mon.txt", Lmin=lambda-dlambda0, Lmax=lambda+dlambda0)
AT (0,0,0.005) RELATIVE source

/****************************************************************
*
*  COMPONENT Barillet
*
****************************************************************/
// Described by two circular slits
COMPONENT Bar_in=Slit(
    radius=b_in_r)
AT (0,0,f_dist) RELATIVE source

COMPONENT Bar_out=Slit(
	radius=b_out_r)
AT (0,0,b_length) RELATIVE PREVIOUS

// For comparison with gold foil activation (1.1e10 n/s/cm2 normalized @ 1.8AA)
COMPONENT activation_flux=L_monitor(
    xwidth=0.01, yheight=0.01,
    nL=401, filename="activation_flux.txt", Lmin=lambda-dlambda0, Lmax=lambda+dlambda0)
WHEN(monok==5)
AT (0,0,0.02) RELATIVE Bar_out

/****************************************************************
*
*  COMPONENT Monochromator
*
****************************************************************/
COMPONENT Pos_2 = Arm(
    )
AT (0,0,b2mon) RELATIVE Bar_out
ROTATED (0,monoc_ang,0) ABSOLUTE

COMPONENT Monoc=Monochromator_curved(
    zwidth=0.015, yheight=0.1, gap=0.0005,
    NH=7, NV=1, mosaich=25.0, mosaicv=25.0,
    reflect="HOPG.rfl", transmit="HOPG.trm",
    DM=monoc_d, RV=0, RH=0)
AT (0,0,0) RELATIVE Pos_2

COMPONENT Pos_3 = Arm(
    )
AT (0,0,0) RELATIVE PREVIOUS
ROTATED (0,2.0*monoc_ang,0) ABSOLUTE

// Divergence monitor after monochromator
COMPONENT div_ROI = Divergence_monitor(
    nh = 51, nv = 51, filename = "div_ROI.txt",
    xwidth = 0.4, yheight = 0.4,
    maxdiv_h=3, maxdiv_v=3)
AT (0, 0, 0.1) RELATIVE PREVIOUS

/****************************************************************
*
*  COMPONENT Preliminary collimation
*
****************************************************************/
COMPONENT Pos_4 = Arm(
    )
AT (0,0,mon2col) RELATIVE Pos_3

COMPONENT Collim_in=Slit(
    xwidth=c_w, yheight=c_h)
AT (0,0,0) RELATIVE PREVIOUS

COMPONENT Collim_out=Slit(
	xwidth=c_w, yheight=c_h)
AT (0,0,c_length) RELATIVE PREVIOUS

/****************************************************************
*
*  COMPONENT Sample window for background reduction
*
****************************************************************/
COMPONENT sample_collim=Slit(
	xwidth=0.02, yheight=0.02)
AT (0,0,col2samp-0.3) RELATIVE Pos_4

// Flux at sample positions
COMPONENT sample_flux=L_monitor(
    xwidth=0.01, yheight=0.01,
    nL=201, filename="sample_flux.txt", Lmin=lambda-dlambda0, Lmax=lambda+dlambda0)
AT (0, 0, col2samp-0.01) RELATIVE Pos_4

// Divergence at sample positions
COMPONENT sample_div = Divergence_monitor(
    nh = 201, nv = 201, filename = "sample_div.txt", xwidth = 0.01,
    yheight = 0.01, maxdiv_h=2, maxdiv_v=2)
AT (0, 0, 0.005) RELATIVE PREVIOUS

/****************************************************************
*
*  COMPONENT Single-crystal
*
****************************************************************/
// Single crystal at sample position
// Manually edited
SPLIT 100 COMPONENT Sample=Single_crystal(
        reflections=samp_f,
        recip_cell=0,order=1,
        xwidth=0.01, yheight=0.01, zdepth=0.01,
        // Remove/comment the following for automatic
        // configuration through LAU file
        delta_d_d=1e-6, mosaic = 15,
        ax =  0.0, ay =  0.0, az = 14.0,
        bx = 14.0, by =  0.0, bz =  0.0,
        cx =  0.0, cy = 14.0, cz =  0.0)
AT (0,0,col2samp) RELATIVE Pos_4
ROTATED (0,phi,0) RELATIVE Pos_4


/****************************************************************
*
*  COMPONENT Single counter detector
*
****************************************************************/
COMPONENT Pos_5 = Arm(
    )
AT (0,0,0) RELATIVE PREVIOUS
ROTATED (nu,gamma,0) RELATIVE Pos_4

// Scattered beam collimation to suppress sample environment
// contributions (probably useless here)
COMPONENT Coll_det1 = Slit(
	radius=coll_det)
AT (0,0,0.35) RELATIVE Pos_5

COMPONENT Coll_det2 = Slit(
	radius=coll_det)
AT (0,0,0.50) RELATIVE Pos_5

// 128x128 PSD detector with 0.2 degree resolution
COMPONENT Mon_out = PSD_monitor(
    xwidth=0.02, yheight=0.02,
    nx=11, ny=11, filename="Output.txt")
AT(0,0,0.57) RELATIVE Pos_5
ROTATED (0,0,0) RELATIVE Pos_5
END
