/*******************************************************************************
*         McXtrace instrument definition URL=http://www.mcxtrace.org
*
* Instrument: SSRL_bl_11_2_white_src
*
* %Identification
* Written by: Stephane Bac, Antoine Padovani
* Date: Dec 5th 2022
* Origin: Synchrotron Soleil
* %INSTRUMENT_SITE: SSRL
*
* Simulating the beamline 11-2 of SSRL to reproduce their glitches database.
*
* %Description
* BL 11-2 beamline description here: https://www-ssrl.slac.stanford.edu/mes/11-2/manual.php
* https://www-ssrl.slac.stanford.edu/mes/Glitch_Curves/ , the instrument is the BL in the unfocussed and uncollimated mode
* SSRL glitch database found here: https://www-ssrl.slac.stanford.edu/smbin/dataextractnew.pl
* Documentation and results of the .instr here: https://gitlab.synchrotron-soleil.fr/grades/beamlines/-/tree/main/glitches
* A jupyter notebook will soon be available regrouping everything.
* You may scan like so for example:
*   mxrun -n 1e7 SSRL_bl_11_2_white_src.instr -N601 Etohit=6900,7500 detuning_percentage=40
*
* %Example: Etohit=6900 Detector: EnergyMonitor_first_I=1.69521e+09
*
* %Parameters
* Etohit: [eV.] Energy used to calculate the bragg angle the monochromator is put at. This is the energy we select.
* h: [1] Miller indices.
* k: [1] Miller indices.
* l: [1] Miller indices.
* fwhm: [deg.] Full width half maximum of the second crystals's rocking curve.
* detuning_percentage: [%.] Percentage of the rocking curve fwhm to detune the second crystal by.
* detuning_rockingcurve: [deg.] Degrees to detune the second crystal by. Used to find the 2nd xtal's rocking curve. Leave at 0 otherwise.
*
* %End
*******************************************************************************/

DEFINE INSTRUMENT SSRL_bl_11_2_white_src(Etohit=6900,h=2,k=2,l=0,fwhm=0.1,detuning_percentage=0,detuning_rockingcurve=0)


DECLARE
%{
    double calculated_angle;
    double n;
    double theta_detuning;    
%}

INITIALIZE
%{
    n = h*h + k*k + l*l;
    fprintf(stdout,"n %g \n", n);
    calculated_angle=RAD2DEG*asin(12398.4198*sqrt(n)/(2*5.43096*Etohit));
    fprintf(stdout,"Energy eV %g / Angle deg %g \n", Etohit, calculated_angle);
       
    //the fwhm is 0.1 degrees by default, the value for the for 6900-7500 eV range. For other ranges find it by doing a scan with the detuning_rockingcurve parameter.
    theta_detuning=(detuning_percentage/100)*fwhm;
    fprintf(stdout,"theta_detuning degrees %g \n", theta_detuning);
      
%}

TRACE

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

COMPONENT src = Wiggler(
    E0=22, 
    dE=18, 
    B=2,
    Nper=13,
    Ie=0.1,
    length=175e-3,
    Ee=2.4,
    focus_xw=2*tan(0.0015/2),
    focus_yh=2*tan(0.00015/2) 
    )
AT (0, 0, 0) RELATIVE PREVIOUS

COMPONENT slit_mono = Slit(
    xwidth=0.005,
    yheight=0.0003
    )
AT (0, 0, 17.6-0.08) RELATIVE PREVIOUS

COMPONENT mono_loc= Arm()
AT(0,0,0.08) RELATIVE PREVIOUS

COMPONENT ray_position= Arm() //ray's position, this is used to place monitors after the dcm
AT(0,0,0) RELATIVE PREVIOUS
ROTATED (0,0,0) RELATIVE PREVIOUS

/* -------------------------------------------------------------------------- Double crystal monochromator */ 
COMPONENT mono_rotation= Arm()
AT(0,0,0) RELATIVE PREVIOUS
ROTATED (-90,0,0) RELATIVE PREVIOUS

COMPONENT mono_rotation_phi_90= Arm()
AT(0,0,0) RELATIVE PREVIOUS
ROTATED (0,0,90) RELATIVE PREVIOUS

COMPONENT center_of_rotation= Arm()
AT(0,0,0.004) RELATIVE PREVIOUS //0.006 works too though
ROTATED (0,calculated_angle,0) RELATIVE PREVIOUS 

SPLIT 10 COMPONENT bragg_crystal_split = Single_crystal(reflections="Si.lau", material_datafile="Si.txt",
    xwidth=76.2e-3, yheight = 41.275e-3, zdepth=0.001, p_transmit = -1, order = 1, mosaic=1, barns =1,
    
    ax=5.43096*0.40824829,
    ay=-5.43096*0.57735027,
    az=5.43096*0.70710678,

    bx=-5.43096*0.40824829,
    by=5.43096*0.57735027,
    bz=5.43096*0.70710678,
    
    cx=5.43096*0.81649658,
    cy=5.43096*0.57735027,
    cz=5.43096*0)
AT (0.0762/2, 0, -0.006/2-(0.001/2)) RELATIVE PREVIOUS
ROTATED (0,0,0) RELATIVE PREVIOUS    
EXTEND %{
  if(!SCATTERED) ABSORB;
%}

COMPONENT mono_loc_2= Arm()
AT(-0.09525/2, 0, 0.006/2+(0.001/2)) RELATIVE center_of_rotation

//counter clock wise detuning
COMPONENT detuning_rotation = Arm()
AT(0,0, 0) RELATIVE PREVIOUS
ROTATED(0,detuning_rockingcurve+theta_detuning, 0) RELATIVE PREVIOUS //use one or the other, not both.

SPLIT 10 COMPONENT bragg_crystal_two_split = COPY(bragg_crystal_split)(
    xwidth=95.25e-3)
AT (0,0 ,0) RELATIVE PREVIOUS
ROTATED (0,0,0) RELATIVE PREVIOUS    
EXTEND %{
  if(!SCATTERED) ABSORB;
%}


/* -------------------------------------------------------------------------- Energy monitors */ 
COMPONENT EnergyMonitor_first = Monitor_nD(    
    xwidth=44e-4,
    yheight=44e-4,        
    min=4, 
    max=40, 
    bins=500,
    options="energy",
    filename="EnergyMonitor_first",
    restore_xray = 1
    ) 
AT (0, 0.006*sin(DEG2RAD*2*calculated_angle)/sin(DEG2RAD*calculated_angle), 18.6-17.6) RELATIVE ray_position    

COMPONENT EnergyMonitor_second = COPY(EnergyMonitor_first)(
    xwidth=2.8e-3,yheight=2.8e-3,filename="EnergyMonitor_second") 
AT (0,0,0) RELATIVE PREVIOUS

COMPONENT EnergyMonitor_third = COPY(EnergyMonitor_first)(
    xwidth=1e-2,yheight=1e-2,filename="EnergyMonitor_third") 
AT (0,0,10) RELATIVE PREVIOUS

COMPONENT EnergyMonitor_fourth = COPY(EnergyMonitor_first)(
    xwidth=4.3e-3,yheight=4.3e-3,filename="EnergyMonitor_fourth")  
AT (0,0,0) RELATIVE PREVIOUS

SAVE %{
%}

FINALLY
%{                                              
%}

END

