 /*******************************************************************************
*         McStas instrument definition URL=http://www.mcstas.org
*
* Instrument: SE_example
*
* %Identification
* Written by: Erik Knudsen, Peter Willendrup
* Date: June 2010
* Origin: Risoe
* %INSTRUMENT_SITE: Tests_polarization
*
* Mockup of transmission Spin-Echo, written for PNCMI 2010 school in Delft.
*
* %Description
* This instrument shows the use of essential McStas polarisation components, including Pol_mirror, Pol_Bfield and MeanPolLambda_monitor.
*
* Pol_mirror is used to polarize and analyze the incoming and scattered beams.
* Pol_Bfield is used to define guidefields and flippers.
* MeanPolLambda_montior is used to monitor beam polarisation.
*
* Example: mcrun SE_example.instr dBz=-0.0001,0.0001 -N41 -n1e5 
*
* %Parameters
* POL_ANGLE: [deg]  Reflection angle of polarizer/analyzer
* SAMPLE: [1]       Flag to include (0) or exclude incoherent scatterer
* Bguide: [T]       Field magnitude in guide fields
* dBz: [T]          Magnitude field perturbation in first guide field
* Bflip: [T]        Magnitude of flipper fields,
* Lam: [Angstrom]   Mean wavelength of neutrons emitted from source
* dLam: [Angstrom]  Wavelength spread of neutrons emitted from source
*
* %Link
* Requires mcstas 1.12b (or beta). PolLambda_monitor has been modified to work (nL->nlam)
* %End
*******************************************************************************/
DEFINE INSTRUMENT SE_example(POL_ANGLE=2, SAMPLE=0, Bguide=0.1, Bflip=3e-4, dBz=0, Lam=8, dLam=0.8)

/* The DECLARE section allows us to declare variables or  small      */
/* functions in C syntax. These may be used in the whole instrument. */
DECLARE
%{
  double pol_radius;
%}

/* The INITIALIZE section is executed when the simulation starts     */
/* (C code). You may use them as component parameter values.         */
INITIALIZE
%{
  pol_radius=0.3/(POL_ANGLE*DEG2RAD);
%}

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

COMPONENT Source = Source_simple(
        radius = .012, dist = 1, xwidth = 0.02,yheight=0.1*sin(POL_ANGLE*DEG2RAD), lambda0 = Lam,
    dlambda = dLam, flux=1e7)
AT (0, 0, 0) RELATIVE Origin

COMPONENT lam_mon = L_monitor(
  nL = 41, filename = "lam_mon", restore_neutron = 1,
  xwidth = 0.05, yheight = 0.05, Lmin = 1, Lmax = 10)
AT (0, 0, 1) RELATIVE Source

COMPONENT polariser_pt = Arm()
AT (0, 0, 1) RELATIVE Source
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT hdiv_mon = Div1D_monitor(
     ndiv = 21, filename = "hdiv_mon", restore_neutron = 1,
     xwidth = 0.05, yheight = 0.05, maxdiv = 1.0)
AT (0, 0, 0) RELATIVE polariser_pt
ROTATED (0, 0, 90) RELATIVE polariser_pt

COMPONENT polariser2 = Pol_mirror(
  rDownPar = {0.99,0.11,0.9,2,0.0185},
  rUpPar = {0.99,0.0485,0.9,1,0.0002}, zwidth = 0.1, yheight = 0.3,
  p_reflect = 0)
AT (0, 0, 0) RELATIVE polariser_pt
ROTATED (90-POL_ANGLE,90,0) RELATIVE polariser_pt
EXTEND %{
  if(!SCATTERED) ABSORB;
%}


COMPONENT psd_ap = PSD_monitor(
  filename = "psd_ap", xwidth = 0.1, yheight = 0.01,restore_neutron=1)
AT (0, 0, 0.32) RELATIVE polariser_pt
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT pl_mon0 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.01, filename = "pol_lam0",
  restore_neutron = 1, mx = 0, my = 0, mz = 1, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.32) RELATIVE polariser_pt
ROTATED (0, 0, 0) RELATIVE Source

/*beam is now polarized in the flight direction - flip it to the vertical*/

COMPONENT flipper1 = Pol_Bfield(field_type=1, 
  xwidth=0.1,yheight=0.1,
  Bx=0, By=Bflip, Bz=Bflip)
AT( 0,0,0.32) RELATIVE polariser_pt
ROTATED (0,0,0) RELATIVE Source

COMPONENT flipper1_stop=Pol_Bfield_stop()
AT(0,0,0.02) RELATIVE flipper1

COMPONENT pl_mon1 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.01, filename = "pol_lam1",
  restore_neutron = 1, mx = 0, my = 1, mz = 0, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.021) RELATIVE flipper1 
ROTATED (0, 0, 0) RELATIVE Source

/*the precession region*/

COMPONENT guide_field_1_slit=Slit(xwidth=0.1, yheight=0.1)
AT(0,0,0.0205) RELATIVE flipper1

COMPONENT guide_field_1 = Pol_Bfield(field_type=1, 
    xwidth=0.1, yheight=0.1, Bx=0, By=0, Bz=Bguide+dBz)
AT(0, 0, 0.021) RELATIVE flipper1

COMPONENT guide_field_1_stop = Pol_Bfield_stop()
AT(0,0,1) RELATIVE guide_field_1

COMPONENT guide_field_1_end=Slit(xwidth=0.1, yheight=0.01)
AT(0,0,1.001) RELATIVE guide_field_1
ROTATED (0,0,0) RELATIVE Source

COMPONENT pl_mon2 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.1, filename = "pol_lam2",
  restore_neutron = 1, mx = 0, my = 1, mz = 0, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.001) RELATIVE guide_field_1_end
ROTATED (0, 0, 0) RELATIVE Source

/*two flippers after one another*/
COMPONENT flipper2_1 = Pol_Bfield(field_type=1, 
  xwidth=0.1,yheight=0.1,
  Bx=0, By=Bflip, Bz=Bflip)
AT( 0,0,2e-3) RELATIVE guide_field_1_end

COMPONENT flipper2_1_stop=Pol_Bfield_stop()
AT(0,0,0.02) RELATIVE flipper2_1

COMPONENT flipper2_2 = Pol_Bfield(field_type=1, 
  xwidth=0.1,yheight=0.1,
  Bx=0, By=-Bflip, Bz=Bflip)
AT( 0,0,0.021) RELATIVE flipper2_1

COMPONENT flipper2_2_stop=Pol_Bfield_stop()
AT(0,0,0.02) RELATIVE flipper2_2

COMPONENT flipper_2_2_end=Slit(xwidth=0.1, yheight=0.01)
AT(0,0,0.0201) RELATIVE flipper2_2

/*Here is the sample position*/
COMPONENT sample_mnt= Arm()
  AT (0,0,0.02+0.021) RELATIVE flipper2_2

COMPONENT pl_mon3 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.1, filename = "pol_lam3",
  restore_neutron = 1, mx = 0, my = 1, mz = 0, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0) RELATIVE sample_mnt

COMPONENT sample0 = V_sample(
     radius=0.0099,h=0.05, focus_xw=0.1, focus_yh=0.01,target_index=4)
WHEN (SAMPLE==0) AT(0,0,0) RELATIVE sample_mnt



/*2nd precession region */

COMPONENT guide_field_2_slit=Slit(xwidth=0.1, yheight=0.1)
  AT(0,0,0.0205) RELATIVE sample_mnt

COMPONENT guide_field_2 = Pol_Bfield(field_type=1, 
    xwidth = 0.1, yheight = 0.1, Bx=0, By=0, Bz=Bguide)
AT (0, 0, 0.021) RELATIVE sample_mnt
  
COMPONENT guide_field_2_stop=Pol_Bfield_stop()
AT(0,0,1) RELATIVE guide_field_2

COMPONENT guide_field_2_end=Slit(xwidth=0.1, yheight=0.01)
AT(0,0,1.001) RELATIVE guide_field_2_stop
ROTATED (0,0,0) RELATIVE Source

/*final flipper*/
COMPONENT pl_mon40 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.1, filename = "pol_lam40",
  restore_neutron = 0, mx = 0, my = 0, mz = 1, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.001) RELATIVE guide_field_2_end
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT flipper3 = Pol_Bfield(field_type=1, 
  xwidth=0.1,yheight=0.1,
  Bx=0, By=-Bflip, Bz=Bflip)
AT( 0,0,0.001) RELATIVE guide_field_2_end 
ROTATED (0,0,0) RELATIVE Source

COMPONENT flipper3_stop=Pol_Bfield_stop()
AT(0,0,0.02) RELATIVE flipper3

COMPONENT pl_mon4 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.1, filename = "pol_lam4",
  restore_neutron = 1, mx = 0, my = 0, mz = 1, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.021) RELATIVE flipper3
ROTATED (0, 0, 0) RELATIVE Source

/*and in the end an analyzer*/

COMPONENT analyzer_arm = Arm()
AT (0, 0, 0.32+0.021) RELATIVE flipper3
ROTATED (0, 0, 0) RELATIVE flipper3

COMPONENT psd_ba = PSD_monitor(
  filename = "psd_ap", xwidth = 0.1, yheight = 0.01,restore_neutron=1)
AT (0, 0, 0) RELATIVE analyzer_arm
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT pl_mon_ba = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.01, filename = "lam_pol_ba",
  restore_neutron = 1, mx = 1, my = 0, mz = 0, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0) RELATIVE analyzer_arm
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT analyzer = Pol_mirror(
  rDownPar = {0.99,0.11,0.9,2,0.0185},
  rUpPar = {0.99,0.0485,0.9,1,0.0002}, zwidth = 0.1, yheight = 0.3,
  p_reflect = 0)
AT (0, 0, 0) RELATIVE analyzer_arm
ROTATED (90-POL_ANGLE,90,0) RELATIVE analyzer_arm
EXTEND %{
  if(!SCATTERED) ABSORB;
%}

COMPONENT detector_slit=Slit(xwidth=0.1, yheight=0.01)
AT(0,0,0.64) RELATIVE analyzer_arm
ROTATED (0,0,0) RELATIVE Source

COMPONENT pl_mon5 = MeanPolLambda_monitor(
  xwidth = 0.1, yheight = 0.1, filename = "pol_lam5",
  restore_neutron = 1, mx = 0, my = 0, mz = 1, Lmin = 1,
  Lmax = 10)
AT (0, 0, 0.641) RELATIVE analyzer_arm
ROTATED (0, 0, 0) RELATIVE Source

COMPONENT detector = PSD_monitor(
				 xwidth=0.1,yheight=0.1, filename="detector")
AT (0,0,0.642) RELATIVE analyzer_arm
ROTATED (0,0,0) RELATIVE Source


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






