1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
|
/*******************************************************************************
* Instrument: ROCK beam-line at SOLEIL
*
* %Identification
* Written by: Stephane Bac, Antoine Padovani, Emmanuel Farhi
* Date: 23/02/2022
* Origin: SOLEIL
* Version: 0.3
* %INSTRUMENT_SITE: SOLEIL
*
* ROCK beam-line at SOLEIL
*
* %Description
* ROCK : Rocking Optics for Chemical Kinetics ROCK time-resolved X-ray
*
* Absorption spectroscopy (XAS) beamline Energy range 4 - 40 keV
* The ROCK beamline (ROCK being the acronym for Rocking Optics for Chemical Kinetics)
* is devoted to the study of fast kinetic processes in nanomaterials used in
* catalysis and batteries. The objective is to contribute to the development of
* more efficient catalysts and batteries which should find successful industrial
* applications in the field of energy generation and storage in compliance with
* the protection of public health and environment. The better knowledge at the
* atomic scale of nanomaterials involved in catalysis or energy storage provided
* by time-resolved XAS is recognized by the concerned communities as mandatory
* for establishing synthesis strategies leading to important breakthroughs in
* the production of energy from renewable sources and in the development of
* advanced energy storage devices.
*
* Position | Element
* ---------|--------------------------------------------------------------------
* 0 | Bending_magnet 1.72 T
* 8.5336 | Slit 1/2
* 10.15 | Toroidal mirror M1
* 11.69 | Slit 3
* 16.82 | Mirror M2a
* 18.15 | Slit 4
* 19 | Channel-cut Si monochromator at 20 (Si220), 18.92 or 19.25 m (Si111)
* 21.13 | Slit 5/6
* 22.44 | Mirror M2b
* 32.44 | Sample
*
* Examples:
* Copper scan: mxrun SOLEIL_ROCK.instr E0=8.500,9.500 scan=1 cc=2 -N100
* Manganese and chrome scan: mxrun SOLEIL_ROCK.instr E0=5.700,6.800 scan=1 sample_file=MnCr cc=2 -N100
* Pretty energy repartition monitor result: mxrun SOLEIL_ROCK.instr E0=17.000 cc=2 -n1e8
*
* %Example: E0=15.918 Detector: psd_monitor_I=6.9e+08
*
* %Parameters
* E0: [keV] Energy to hit, i.e. selected by the channel-cut monochromator
* dE: [keV] Energy spread at the source
* cc: [0-3] Channel-cut monochromator type. 0 for Si 220 with an energy range of 5.62883-46.2834 eV/4-35 deg (hit-table:11.752-34.055 ev/5.44-15.94 deg); 1 for Si 111 long 3.44694-28.3427 eV/4-35 deg (hit-table:7.196-20.854 ev/5.44-15.94 deg); 2 for Si 111 short 3.44694-18.914.3 eV/6-35 deg (hittable:5.323-18.914 ev/6-21.8 deg); 3 changes cc dynamically
* scan: [0-1] 0 no energy scan, 1 energy scan
* angle_m2a_m2b: [rad] M2A/M2B mirror's deviation angle, can vary from 0.0035 to 0.0104
* angle_m1: [rad] M1 mirror's deviation angle
* sample_file: [string] Sample chemical formulae
* reflec_material_M1: [str] Material reflectivity file name for M1 mirror, e.g. "Ir.dat"
* reflec_material_M2A_M2B: [str] Material reflectivity file name for M2A and M2B mirror. Use NULL for automatic setting.
*
* %Link
* https://www.synchrotron-soleil.fr/en/beamlines/rock
* %Link
* https://gitlab.synchrotron-soleil.fr/grades/mcxtrace-rock
* %Link
* https://github.com/antoinepado/glitch_runner_rock
*
* %End
*******************************************************************************/
DEFINE INSTRUMENT SOLEIL_ROCK (E0=15.918, dE=1,
scan=0,
angle_m2a_m2b=0.008,
angle_m1=0.0045,
string sample_file="CuMo",
string reflec_material_M1="Ir.dat",
string reflec_material_M2A_M2B="NULL",
int cc=0)
DECLARE
%{
double calculated_angle;
double Eminkev;
double Emaxkev;
double incr;
int n;
int i_h;
int i_k;
int i_l;
double length_first_crystal;
double length_second_crystal;
double center_first_crystal;
double dist_center_to_center;
double center_to_c_mono_angle;
char e_repartition_options[512];
double I_err_calc;
double absorption_coefficient;
double absorption_coefficient_error;
double number_events_after_sample;
%}
INITIALIZE
%{
i_h=1;
i_k=1;
i_l=1;
if(cc>=3){ //automatically select the right cc for the energy E0
if(E0<=15.516){
cc = 2;
}
else if (E0<=17.439){
cc = 1;
}
else if (E0<=34.055){
cc = 0;
}
}
if(cc<=0){ //cc 220
Eminkev=5.62883;
Emaxkev=46.2834;
incr=0.995/(Emaxkev-Eminkev);
n=8;
i_h=2;
i_k=2;
i_l=0;
length_first_crystal=70e-3;
length_second_crystal=70e-3;
center_first_crystal=20;
dist_center_to_center = sqrt(0.01*0.01+0.07*0.07);
/// center_to_c_mono_angle is arctan(e/(length_first_crystal/2 + length_second_crystal/2))
center_to_c_mono_angle=0.14189;
}
else if (cc<=1){ //cc long 111
Eminkev=3.44694;
Emaxkev=28.3427;
incr=0.995/(Emaxkev-Eminkev);
n=3;
length_first_crystal=70e-3;
length_second_crystal=70e-3;
center_first_crystal=18.92;
dist_center_to_center = sqrt(0.01*0.01+0.07*0.07);
center_to_c_mono_angle=0.14189;
} else if (cc<=2){ //cc short 111
Eminkev=3.44694;
Emaxkev=18.9143;
incr=0.995/(Emaxkev-Eminkev);
n=3;
length_first_crystal=50e-3;
length_second_crystal=70e-3;
center_first_crystal=19.25;
dist_center_to_center = sqrt(0.01*0.01+0.06*0.06);
center_to_c_mono_angle=0.1651;
}
calculated_angle=RAD2DEG*asin(12.39842*sqrt(n)/(2*5.4309*E0));
if (!reflec_material_M2A_M2B || !strlen(reflec_material_M2A_M2B)
|| !strcmp(reflec_material_M2A_M2B, "NULL") || !strcmp(reflec_material_M2A_M2B, "0")) {
if(E0<=7.98){
reflec_material_M2A_M2B="B4C.dat";
}
else if (E0<=16.46){
reflec_material_M2A_M2B="Pd.dat";
}
else if (E0>16.46){
reflec_material_M2A_M2B="Pt.dat";
}
}
MPI_MASTER(
fprintf(stdout,"%s: Energy=%g [keV]\n"
"\tM2 mirror=%s\n"
"\tMonochromator Si<%i %i %i> angle %g [deg], config=%i\n",
NAME_INSTRUMENT, E0, reflec_material_M2A_M2B, i_h,i_k,i_l, calculated_angle, cc);
);
sprintf(e_repartition_options,"energy limits=[%g %g], y",
E0-0.02*E0, E0+0.02*E0);
%}
TRACE
COMPONENT Origin = Progress_bar(
)
AT (0, 0, 0) ABSOLUTE
/* -------------------------------------------------- Source */
COMPONENT Source = Bending_magnet(
E0=E0, dE = dE,
Ee = 2.75, Ie = 0.5, B = 1.72, sigex=54.9e-6, sigey=20.2e-6
)
AT (0, 0, 0) RELATIVE Origin
/* -------------------------------------------------- Vertical slit 1 */
COMPONENT slit1 = Slit(
xwidth=0.021,
yheight=0.042)
AT (0, 0, 8.5336) RELATIVE PREVIOUS
/* -------------------------------------------------- Horizontal slit 2 */
COMPONENT slit2 = Slit(
xwidth=0.02,
yheight=0.01)
AT (0, 0, 8.6486-8.5336) RELATIVE PREVIOUS
/* -------------------------------------------------- Toroidal mirror M1 */
COMPONENT mirror_m1 = Mirror_toroid_pothole(
xwidth = 0.015,
zdepth = 1.1,
radius=0.0317,
radius_o=9.02e3,coating=reflec_material_M1)
AT (0, 0, 10.15-8.6486) RELATIVE PREVIOUS
ROTATED (-angle_m1*RAD2DEG/2, 0, 0) RELATIVE PREVIOUS
EXTEND
%{
if (!SCATTERED) ABSORB;
%}
COMPONENT mirror_m1_out = Arm()
AT (0,0,0) RELATIVE PREVIOUS
ROTATED (-angle_m1*RAD2DEG/2, 0, 0) RELATIVE PREVIOUS
/* -------------------------------------------------- Horizontal slit 3 */
COMPONENT slit3_xy = PSD_monitor(xwidth=0.02, yheight=0.01)
AT (0, 0, 11.6905-10.15) RELATIVE PREVIOUS
COMPONENT slit3_div = Divergence_monitor(maxdiv_h=0.05, maxdiv_v=0.05, nh=128, nv=128)
AT (0, 0, 0) RELATIVE PREVIOUS
COMPONENT slit3 = Slit(
xwidth=0.02,
yheight=0.01)
AT (0, 0, 0) RELATIVE slit3_xy
/* -------------------------------------------------- M2a mirror */
COMPONENT mirror_m2a = Mirror(
xwidth=47e-3,
zdepth=1100e-3,coating=reflec_material_M2A_M2B)
AT (0, 0, (16.82-11.6905)) RELATIVE PREVIOUS
ROTATED (-angle_m2a_m2b*RAD2DEG/2, 0, 0) RELATIVE PREVIOUS
EXTEND
%{
if (!SCATTERED) ABSORB;
%}
COMPONENT mirror_m2a_out = Arm()
AT (0, 0, 0) RELATIVE PREVIOUS
ROTATED (-angle_m2a_m2b*RAD2DEG/2, 0, 0) RELATIVE PREVIOUS
/* -------------------------------------------------- Horizontal slit 4 */
COMPONENT slit4_in = PSD_monitor(xwidth=0.5, yheight=0.5)
AT (0, 0, 18.1512-16.82) RELATIVE mirror_m2a_out
COMPONENT slit4 = Slit(
xwidth=0.02,
yheight=0.02)
AT (0, 0, 0) RELATIVE PREVIOUS
/* -------------------------------------------------- CC crystal 1 */
COMPONENT arm_crystal0 = Arm()
AT (0, 0, center_first_crystal-18.1512) RELATIVE slit4
COMPONENT bragg_crystal = Bragg_crystal(
length=length_first_crystal,
width=25e-3,
material = "Si.txt",
h = i_h,
k = i_k,
l = i_l,
crystal_type = 2
)
AT (0, 0, 0) RELATIVE arm_crystal0
ROTATED (-calculated_angle, 0, 0) RELATIVE arm_crystal0
EXTEND
%{
if (!SCATTERED) ABSORB;
%}
COMPONENT arm_crystal1 = Arm()
AT (0, 0, 0) RELATIVE PREVIOUS
ROTATED (-calculated_angle, 0, 0) RELATIVE PREVIOUS
/* -------------------------------------------------- CC crystal 2 */
// gap btw crystals is 1 cm. We shit the 2nd blade so that it is centred wrt reflection.
COMPONENT bragg_crystal_two = COPY(bragg_crystal)(
length=length_second_crystal)
AT (0, 0.01, calculated_angle ? 0.01/tan(calculated_angle*DEG2RAD) : 0) RELATIVE bragg_crystal
ROTATED (calculated_angle, 0, 0) RELATIVE arm_crystal1
EXTEND
%{
if (!SCATTERED) ABSORB;
%}
COMPONENT arm_crystal2 = Arm()
AT (0, 0, 0) RELATIVE PREVIOUS
ROTATED (calculated_angle, 0, 0) RELATIVE PREVIOUS
COMPONENT bragg_crystal_out = PSD_monitor(xwidth=0.1, yheight=0.1, nx=200, ny=200)
AT (0,0,2*length_second_crystal) RELATIVE arm_crystal2
/* -------------------------------------------------- Horizontal slit 5 */
// the beam is positioned at Y=+dy*sin(2*calculated_angle*DEG2RAD)/sin(calculated_angle*DEG2RAD)
// with dy=0.01 (CC gap) wrt the CC entry
COMPONENT slit5 = Slit(
xwidth=0.02,
yheight=0.01)
AT (0, 0, 21.135 - center_first_crystal) RELATIVE arm_crystal2
/* -------------------------------------------------- Vertical slit 6 */
COMPONENT slit6 = Slit(
xwidth=0.01,
yheight=0.02)
AT (0, 0, 21.25-21.135) RELATIVE PREVIOUS
/* -------------------------------------------------- M2b mirror */
COMPONENT mirror_m2b = Mirror_curved(
radius=5e3,
width=47e-3,
length=1100e-3,
coating=reflec_material_M2A_M2B)
AT (0, 0, 22.44-21.25) RELATIVE PREVIOUS
ROTATED (angle_m2a_m2b*RAD2DEG/2, 0, 90) RELATIVE PREVIOUS
EXTEND
%{
if (!SCATTERED) ABSORB;
%}
COMPONENT mirror_m2b_out = Arm()
AT (0, 0, 0) RELATIVE PREVIOUS
ROTATED (angle_m2a_m2b*RAD2DEG, 0, 0) RELATIVE arm_crystal2
/* -------------------------------------------------- E monitor */
COMPONENT EnergyMonitor_before_sample = Monitor_nD(
xwidth =0.1 ,
yheight =0.1 ,
min=E0-(0.005+(E0-Eminkev)*incr),
max=E0+(0.005+(E0-Eminkev)*incr),
bins=500,
options="energy",
filename="EnergyMonitor_before_sample",
restore_xray = 1
)
AT (0,0,10) RELATIVE PREVIOUS
/* -------------------------------------------------- sample */
// this is the sample stage
COMPONENT e_repartition_after_m2b = Monitor_nD(
xwidth =0.02 , yheight =0.02,
options=e_repartition_options, bins=500,
filename="e_repartition_after_m2b",
restore_xray = 1)
AT (0,0,0.5) RELATIVE PREVIOUS
COMPONENT sample_in = PSD_monitor(xwidth=0.01, yheight=0.01, nx=200, ny=200)
AT (0,0,0) RELATIVE PREVIOUS
SPLIT COMPONENT absorption_sample = Fluorescence(
material=sample_file,
xwidth = 0.05,
yheight = 0.05,
zdepth = 0.0001)
AT (0, 0, 0) RELATIVE e_repartition_after_m2b
COMPONENT fluo_monitor = Monitor_nD(
radius=0.2, options="energy", bins=1024, min=0, max=E0*1.2)
AT (0,0,0) RELATIVE PREVIOUS
/* -------------------------------------------------- E monitor */
COMPONENT EnergyMonitor_after_sample = COPY(EnergyMonitor_before_sample)(
filename = "EnergyMonitor_after_sample"
)
AT (0,0,0.5) RELATIVE PREVIOUS
COMPONENT psd_monitor = PSD_monitor(
filename="psd",
xwidth=0.004,
yheight=0.004,
nx=100,
ny=100,
restore_xray = 1
)
AT (0, 0, 0) RELATIVE PREVIOUS
FINALLY
%{
// If there is a scan, calculate the absorption coefficient.
if(scan>=1){
#ifdef USE_MPI
//MPI_MASTER is equivalent to if(mpi_node_root>=mpi_node_rank){ //statement }
//If DETECTOR_OUT_0D is inside of MPI_MASTER the program hangs forever.
//If outside it seems to work. Weird.
MPI_MASTER(
#endif
MCDETECTOR e_before_sample = COMP_GETPAR2(EnergyMonitor_before_sample,detector);
MCDETECTOR e_after_sample = COMP_GETPAR2(EnergyMonitor_after_sample,detector);
absorption_coefficient = log(e_before_sample.intensity/e_after_sample.intensity);
I_err_calc = ((e_before_sample.error/e_before_sample.intensity)+(e_after_sample.error/e_after_sample.intensity));
absorption_coefficient_error = I_err_calc;
number_events_after_sample = e_after_sample.events;
fprintf(stdout,"*** \n");
fprintf(stdout,"Before the sample: I %g I_error %g N %g \n", e_before_sample.intensity, e_before_sample.error, e_before_sample.events);
fprintf(stdout,"After the sample: I %g I_error %g N %g \n", e_after_sample.intensity, e_after_sample.error, e_after_sample.events);
fprintf(stdout,"I_err_calc: I %g \n", I_err_calc);
fprintf(stdout,"*** \n ");
#ifdef USE_MPI
);
//MPI_Barrier(MPI_COMM_WORLD);
#endif
// This set of defines is to avoid getting a '.' in the component name
#ifdef NAME_CURRENT_COMP
#undef NAME_CURRENT_COMP
#define NAME_CURRENT_COMP "absorption_coefficient"
#endif
Coords dummy;
Rotation Rot;
rot_set_rotation(Rot,0,0,0);
mcdetector_out_0D("XANES EXAFS",number_events_after_sample, absorption_coefficient, absorption_coefficient_error,instrument_name,dummy,Rot);
}
%}
END
|