Skip to content

Commit b0b02a8

Browse files
authored
Merge pull request #2036 from farhi/main
mcxtrace: add SWING BL at SOLEIL
2 parents 183a736 + 0b9088b commit b0b02a8

3 files changed

Lines changed: 269 additions & 3 deletions

File tree

mcxtrace-comps/contrib/SAXSQMonitor.comp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
DEFINE COMPONENT SAXSQMonitor
4242

4343

44-
SETTING PARAMETERS (string RFilename="RDetectror", string qFilename="QDetector", int NumberOfBins=100, restore_xray=0,
44+
SETTING PARAMETERS (string RFilename="RDetector", string qFilename="QDetector", int NumberOfBins=100, restore_xray=0,
4545
RadiusDetector, DistanceFromSample, LambdaMin = 1.0, Lambda0 = 0.0, qMax=0)
4646

4747

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/*******************************************************************************
2+
* Instrument: SOLEIL_SWING
3+
*
4+
* %Identification
5+
* Written by: E. Farhi, S. Bac
6+
* Date: 2025
7+
* Origin: SOLEIL
8+
* Version: 0.1
9+
* %INSTRUMENT_SITE: SOLEIL
10+
*
11+
* A simple model for the SWING beam-line at SOLEIL (small angle scattering, SAXS).
12+
*
13+
* %Description
14+
* The SWING beamline targets soft condensed matter, conformation of
15+
* macro-molecules in solution (BioSAXS) and material sciences. Our experimental
16+
* set up allows simultaneous small-angle X-ray scattering (SAXS) and wide-angle
17+
* X-ray scattering measurements (WAXS) in the 5-16 keV energy range. Anomalous
18+
* scattering experiments can also be performed. A very large variety of types of
19+
* samples can be studied, e.g., solutions, gels, amorphous solids, crystallized
20+
* solids, thanks to the diversity of the proposed sample environments.
21+
*
22+
* This model may use any PDB file as sample, or an ideal sphere colloid for testing.
23+
*
24+
* Position | Element
25+
* ---------|--------------------------------------------------------------------
26+
* 0 | U20 undulator
27+
* 11.7 | Diaphragm providing HxV=1x0.5 mm beam
28+
* 20 | Si(111) DCM, 40x40x10 mm^3 E0=5-16 keV
29+
* 22.5 | Focusing KB (HFM + VFM)
30+
* 31 | Linear H-CRL (f=81 cm): 31 m
31+
* 32 | Sample location
32+
* 32.5-39 | Detector 162.5 x 155.2 mm
33+
*
34+
* Example: E0=13 Detector: Eiger4M_I=128554
35+
*
36+
* %Parameters
37+
* E0: [keV] Nominal energy at the Wiggler.
38+
* dE: [keV] Energy half-bandwidth at the Wiggler
39+
* dcm_theta: [deg] Rotation angle of the DCM. 0=set from energy E0
40+
* mirror_grazing_angle: [deg] Tilt angle of the mirrors.
41+
* hfm_radius: [m] Horizontally focusing mirror radius.
42+
* vfm_radius: [m] Vertically focusing mirror radius.
43+
* sample: [str] Sample given as a PDB file, or NULL for a 100A dilute Sphere model.
44+
* sample_det: [m] Sample to detector distance in m.
45+
*
46+
* %Link
47+
* https://www.synchrotron-soleil.fr/en/beamlines/swing
48+
*
49+
* %End
50+
*******************************************************************************/
51+
DEFINE INSTRUMENT SOLEIL_SIXS(E0=13, dE=0.1, dcm_theta=0,
52+
hfm_radius=495, vfm_radius=859, mirror_grazing_angle=4e-3,
53+
string sample="6lyz.pdb", sample_det=2)
54+
55+
DECLARE
56+
%{
57+
double dcm_gap;
58+
double Lambda;
59+
double Ki;
60+
%}
61+
62+
USERVARS
63+
%{
64+
int flag_hfm;
65+
int flag_vfm;
66+
%}
67+
68+
INITIALIZE
69+
%{
70+
double DM= 5.4909; // Si d-spacing for the Monochromator
71+
double d = DM/sqrt(3); // <111> reflection |<111>|=3
72+
dcm_gap = 0.02; // gap between the 2 monochromator crystals
73+
74+
if (!dcm_theta && E0) {
75+
// n.lambda = 2 d sin(dcm_theta) = 2*PI/E2K / E0 with n=ORDER=1
76+
double sin_theta = 2*PI/E2K/E0 / 2 / d;
77+
if (fabs(sin_theta) < 1)
78+
dcm_theta = asin(sin_theta)*RAD2DEG;
79+
} else if (dcm_theta && !E0)
80+
E0 = 2*PI/E2K / (2*d*sin(dcm_theta*DEG2RAD));
81+
if (!dcm_theta || !E0 || dE <=0)
82+
exit(fprintf(stderr, "%s: ERROR: Monochromator can not reflect E0=%g +/- %g [keV]. Aborting.\n", NAME_INSTRUMENT, E0, dE));
83+
Ki = E0*E2K;
84+
Lambda = 2*PI/Ki;
85+
MPI_MASTER(
86+
printf("%s: E0=%g [keV] Ki=%g [1/Angs] Lambda=%g [Angs] Monochromator dcm_theta=%g [deg]\n",
87+
NAME_INSTRUMENT, E0, dcm_theta, Ki, Lambda);
88+
printf("%s: Using sample %s\n",
89+
NAME_INSTRUMENT,
90+
!strlen(sample) || !strcmp(sample,"0") || !strcmp(sample,"NULL") ? "Sphere" : sample);
91+
);
92+
if (fabs(dE/E0)>0.1) dE = 3e-2*E0;
93+
%}
94+
95+
TRACE
96+
97+
COMPONENT origin = Progress_bar()
98+
AT (0, 0, 0) RELATIVE ABSOLUTE
99+
100+
// the photon source -----------------------------------------------------------
101+
COMPONENT Source_U20 = Undulator(
102+
E0 = E0,
103+
dE = dE,
104+
Ee = 2.75,
105+
Ie = 0.5,
106+
K = 5,
107+
sigex = 388e-6,
108+
sigey = 8.1e-6,
109+
sigepx = 14.5e-6,
110+
sigepy = 4.61e-6)
111+
AT (0,0,0) RELATIVE origin
112+
113+
COMPONENT mon_src_xy = Monitor_nD(
114+
options="x y", xwidth=2e-3, yheight=2e-3, bins=128)
115+
AT (0,0,11.7) RELATIVE Source_U20
116+
117+
COMPONENT mon_src_e = Monitor_nD(options="energy", xwidth=2e-3, yheight=2e-3, bins=128,
118+
min=E0-dE*1.1, max=E0+dE*1.1)
119+
AT (0,0,0) RELATIVE PREVIOUS
120+
121+
// Diaphragm
122+
COMPONENT slit = Slit(xwidth=1e-3, yheight=0.5e-3)
123+
AT (0,0,0.1) RELATIVE PREVIOUS
124+
125+
COMPONENT slit_mon_xy = COPY(mon_src_xy)
126+
AT (0,0,0) RELATIVE PREVIOUS
127+
128+
// The double monochromator ----------------------------------------------------
129+
COMPONENT DCM_location = Arm()
130+
AT (0,0,20) RELATIVE Source_U20
131+
132+
COMPONENT dcm_xtal0 = Bragg_crystal(
133+
length=0.04, width=0.04,
134+
h=1, k=1, l=1, material="Si.txt", V=160.1826)
135+
AT(0,0,0) RELATIVE PREVIOUS
136+
ROTATED (-dcm_theta,0,0) RELATIVE PREVIOUS
137+
EXTEND %{
138+
if (!SCATTERED) ABSORB;
139+
%}
140+
141+
COMPONENT dcm0 = Arm()
142+
AT(0,0,0) RELATIVE PREVIOUS
143+
ROTATED (-dcm_theta,0,0) RELATIVE PREVIOUS
144+
145+
COMPONENT dcm_xtal1 = COPY(dcm_xtal0)
146+
AT(0,dcm_gap, dcm_theta ? dcm_gap/tan(dcm_theta*DEG2RAD) : 0) RELATIVE dcm_xtal0
147+
ROTATED (dcm_theta,0,0) RELATIVE PREVIOUS
148+
EXTEND %{
149+
if (!SCATTERED) ABSORB;
150+
%}
151+
152+
COMPONENT dcm1 = Arm()
153+
AT(0,0,0) RELATIVE PREVIOUS
154+
ROTATED (dcm_theta,0,0) RELATIVE PREVIOUS
155+
156+
COMPONENT mon_dcm_e = COPY(mon_src_e)
157+
AT (0,0,0.5) RELATIVE PREVIOUS
158+
159+
COMPONENT mon_dcm_xy = COPY(mon_src_xy)
160+
AT (0,0,0) RELATIVE PREVIOUS
161+
162+
// KB pair ---------------------------------------------------------------------
163+
// could use Mirror_elliptic
164+
// incidence angle 4 mrad
165+
166+
// KB 1st mirror (XZ plane) at 1.6m from sample
167+
// must be shifted by -2 mm on Y else beam flies underneath the mirror.
168+
COMPONENT vfm_location = COPY(mon_src_xy)
169+
AT (0,0,22.5-20.5) RELATIVE mon_dcm_xy
170+
171+
COMPONENT vfm_in_xz_plane = Arm()
172+
AT (0,0,0) RELATIVE vfm_location
173+
ROTATED(0,0,-90) RELATIVE vfm_location // YZ -> XZ
174+
175+
COMPONENT vfm = Mirror_curved(
176+
coating="Rh.txt",
177+
length=450e-3,
178+
width=0.1,
179+
radius=vfm_radius)
180+
AT (0,0,0) RELATIVE vfm_location
181+
ROTATED(0,-mirror_grazing_angle,0) RELATIVE vfm_in_xz_plane
182+
EXTEND %{
183+
flag_vfm=SCATTERED;
184+
%}
185+
186+
COMPONENT vfm_takeoff = COPY(vfm_location)
187+
AT (0,0,0) RELATIVE vfm_in_xz_plane
188+
ROTATED (-2*mirror_grazing_angle, 0, 0) RELATIVE vfm_location
189+
190+
// KB 2nd mirror (YZ) at 1m from sample, shift height=4.8 mm
191+
COMPONENT hfm_location = COPY(vfm_location)
192+
AT (0,0,34.5-33.9) RELATIVE vfm_takeoff
193+
194+
// 859 m tangential; sagital > 1 km, in YZ plane
195+
COMPONENT hfm = Mirror_curved(
196+
coating="Rh.txt",
197+
length=450e-3,
198+
width=0.1,
199+
radius=hfm_radius)
200+
AT (0,0,0) RELATIVE hfm_location
201+
ROTATED (0,-mirror_grazing_angle,0) RELATIVE hfm_location
202+
EXTEND %{
203+
flag_hfm=SCATTERED;
204+
%}
205+
206+
COMPONENT hfm_takeoff = COPY(vfm_location)
207+
AT (0,0,0) RELATIVE hfm_location
208+
ROTATED (0,-2*mirror_grazing_angle,0) RELATIVE hfm_location
209+
EXTEND %{
210+
if (!flag_hfm || !flag_vfm) ABSORB;
211+
%}
212+
213+
214+
// The sample area -------------------------------------------------------------
215+
// align surface so that the beam hits its centre (shift along Y axis)
216+
SPLIT 10 COMPONENT sample_stage = COPY(mon_src_xy)(xwidth=0.01, yheight=0.01,
217+
restore_xray=1)
218+
AT (1e-3,-1.54e-3,32-22.5) RELATIVE hfm_takeoff
219+
220+
COMPONENT sample_test = Saxs_spheres(
221+
R = 100, Phi = 0.1, Delta_rho = 1.6,
222+
yheight = 1e-3, radius = 0.25e-3, focus_xw = 1,
223+
focus_yh = 1, sphere_mtrl="Be.txt")
224+
WHEN( !strlen(sample) || !strcmp(sample,"0") || !strcmp(sample,"NULL") )
225+
AT (0,0,0) RELATIVE sample_stage
226+
EXTEND %{
227+
if (!SCATTERED) ABSORB;
228+
%}
229+
230+
COMPONENT sample = SAXSPDBFast(
231+
xwidth = 0.01,
232+
yheight = 0.01,
233+
zdepth = 0.01,
234+
SampleToDetectorDistance = sample_det,
235+
DetectorRadius = 0.16*1.41,
236+
PDBFilepath = !strlen(sample) || !strcmp(sample,"0") || !strcmp(sample,"NULL") ? "6lyz.pdb" : sample,
237+
NumberOfQBins=2000,
238+
qMax = 0.9)
239+
WHEN( strlen(sample) && strcmp(sample,"0") && strcmp(sample,"NULL") )
240+
AT (0,0,0) RELATIVE sample_stage
241+
EXTEND %{
242+
if (!SCATTERED) ABSORB;
243+
%}
244+
245+
COMPONENT sample_out = Arm()
246+
AT (0,0,0) RELATIVE sample_stage
247+
248+
COMPONENT Eiger4M = Monitor_nD(xwidth=0.5, yheight=0.5, bins=1024,
249+
options="x y")
250+
AT (0,0,sample_det) RELATIVE sample_stage
251+
252+
COMPONENT QMonitor = SAXSQMonitor(
253+
RadiusDetector = 0.22,
254+
DistanceFromSample = sample_det,
255+
LambdaMin = Lambda,
256+
Lambda0 = Lambda,
257+
NumberOfBins = 2000
258+
)
259+
AT (0,0,sample_det) RELATIVE sample_stage
260+
261+
262+
END

mcxtrace-comps/examples/Tests_samples/Template_SasView/Template_SasView.instr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
*
2323
* %Description
2424
*
25-
* Very simple test instrument for 3 examples from the suite of SasView_ components
25+
* Very simple test instrument for 3 examples from the suite of SasView_ components.
26+
* Select sample model with 'model_index':
27+
* 1= SasView_barbell
28+
* 3= SasView_bcc_paracrystal
29+
* 47= SasView_parallelepiped
2630
*
2731
* %Example: model_index=1 Ncount=1e5 par1=4 par2=1 par3=40 par4=20 par5=400 Detector: detector_I=605
2832
* %Example: model_index=3 Ncount=1e5 par1=220 par2=0.06 par3=40 par4=4 par5=1 Detector: detector_I=4.2
@@ -66,7 +70,7 @@ INITIALIZE %{
6670

6771
%}
6872

69-
TRACE
73+
TRACEmodel_index
7074

7175
COMPONENT a1 = Progress_bar()
7276
AT (0,0,0) ABSOLUTE

0 commit comments

Comments
 (0)