2
2
3
3
from typing import Tuple
4
4
5
- from easyCore import np
5
+ import numpy as np
6
6
from refl1d import model
7
7
from refl1d import names
8
8
9
9
from EasyReflectometry .experiment .resolution_functions import is_constant_resolution_function
10
10
11
11
from ..wrapper_base import WrapperBase
12
12
13
- PADDING_RANGE = 3.5
14
- UPSCALE_FACTOR = 21
13
+ RESOLUTION_PADDING = 3.5
14
+ OVERSAMPLING_FACTOR = 21
15
15
MAGNETISM = False
16
+ ALL_POLARIZATIONS = False
16
17
17
18
18
19
class Refl1dWrapper (WrapperBase ):
@@ -30,7 +31,7 @@ def create_layer(self, name: str):
30
31
31
32
:param name: The name of the layer
32
33
"""
33
- if MAGNETISM :
34
+ if MAGNETISM : # A test with hardcoded magnetism in all layers
34
35
magnetism = names .Magnetism (rhoM = 0.2 , thetaM = 270 )
35
36
else :
36
37
magnetism = None
@@ -47,17 +48,6 @@ def create_item(self, name: str):
47
48
)
48
49
del self .storage ['item' ][name ].stack [0 ]
49
50
50
- def update_item (self , name : str , ** kwargs ):
51
- """
52
- Update a layer.
53
-
54
- :param name: The item name
55
- """
56
- item = self .storage ['item' ][name ]
57
- for key in kwargs .keys ():
58
- ii = getattr (item , key )
59
- setattr (ii , 'value' , kwargs [key ])
60
-
61
51
def get_item_value (self , name : str , key : str ) -> float :
62
52
"""
63
53
A function to get a given item value
@@ -155,61 +145,43 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray:
155
145
:param model_name: the model name
156
146
:return: reflectivity calculated at q
157
147
"""
158
- structure = model .Stack ()
159
- # -1 to reverse the order
160
- for i in self .storage ['model' ][model_name ]['items' ][::- 1 ]:
161
- if i .repeat .value == 1 :
162
- # -1 to reverse the order
163
- for j in range (len (i .stack ))[::- 1 ]:
164
- structure |= i .stack [j ]
165
- else :
166
- stack = model .Stack ()
167
- # -1 to reverse the order
168
- for j in range (len (i .stack ))[::- 1 ]:
169
- stack |= i .stack [j ]
170
- structure |= model .Repeat (stack , repeat = i .repeat .value )
171
-
172
- argmin = np .argmin (q_array )
173
- argmax = np .argmax (q_array )
174
- dq_vector = self ._resolution_function (q_array )
148
+ sample = _build_sample (self .storage , model_name )
149
+ dq_array = self ._resolution_function (q_array )
175
150
176
151
if is_constant_resolution_function (self ._resolution_function ):
177
152
# Get percentage of Q and change from sigma to FWHM
178
- dq_vector = dq_vector * q_array / 100 / (2 * np .sqrt (2 * np .log (2 )))
179
-
180
- if MAGNETISM :
181
- xs = []
182
- for _ in range (4 ):
183
- q = names .QProbe (
184
- Q = q_array ,
185
- dQ = dq_vector ,
186
- intensity = self .storage ['model' ][model_name ]['scale' ],
187
- background = self .storage ['model' ][model_name ]['bkg' ],
188
- )
189
- q .calc_Qo = np .linspace (
190
- q_array [argmin ] - PADDING_RANGE * dq_vector [argmin ],
191
- q_array [argmax ] + PADDING_RANGE * dq_vector [argmax ],
192
- UPSCALE_FACTOR * len (q_array ),
193
- )
194
- xs .append (q )
195
- probe = names .PolarizedQProbe (xs = xs , name = 'polarized' )
196
-
197
- R = names .Experiment (probe = probe , sample = structure ).reflectivity ()[1 ]
198
- else :
199
- q = names .QProbe (
200
- Q = q_array ,
201
- dQ = dq_vector ,
202
- intensity = self .storage ['model' ][model_name ]['scale' ],
203
- background = self .storage ['model' ][model_name ]['bkg' ],
153
+ dq_array = dq_array * q_array / 100 / (2 * np .sqrt (2 * np .log (2 )))
154
+
155
+ if not MAGNETISM :
156
+ probe = _get_probe (
157
+ q_array = q_array ,
158
+ dq_array = dq_array ,
159
+ model_name = model_name ,
160
+ storage = self .storage ,
161
+ oversampling_factor = OVERSAMPLING_FACTOR ,
204
162
)
205
- q .calc_Qo = np .linspace (
206
- q_array [argmin ] - PADDING_RANGE * dq_vector [argmin ],
207
- q_array [argmax ] + PADDING_RANGE * dq_vector [argmax ],
208
- UPSCALE_FACTOR * len (q_array ),
163
+ _ , reflectivity = names .Experiment (probe = probe , sample = sample ).reflectivity ()
164
+ else :
165
+ polarized_probe = _get_polarized_probe (
166
+ q_array = q_array ,
167
+ dq_array = dq_array ,
168
+ model_name = model_name ,
169
+ storage = self .storage ,
170
+ oversampling_factor = OVERSAMPLING_FACTOR ,
171
+ all_polarizations = ALL_POLARIZATIONS ,
209
172
)
210
- R = names .Experiment (probe = q , sample = structure ).reflectivity ()[1 ]
173
+ polarized_reflectivity = names .Experiment (probe = polarized_probe , sample = sample ).reflectivity ()
174
+
175
+ if ALL_POLARIZATIONS :
176
+ raise NotImplementedError ('Polarized reflectivity not yet implemented' )
177
+ # _, reflectivity_pp = polarized_reflectivity[0]
178
+ # _, reflectivity_pm = polarized_reflectivity[1]
179
+ # _, reflectivity_mp = polarized_reflectivity[2]
180
+ # _, reflectivity_mm = polarized_reflectivity[3]
181
+ else :
182
+ _ , reflectivity = polarized_reflectivity [0 ]
211
183
212
- return R
184
+ return reflectivity
213
185
214
186
def sld_profile (self , model_name : str ) -> Tuple [np .ndarray , np .ndarray ]:
215
187
"""
@@ -218,26 +190,82 @@ def sld_profile(self, model_name: str) -> Tuple[np.ndarray, np.ndarray]:
218
190
:param model_name: the model name
219
191
:return: z and sld(z)
220
192
"""
221
- structure = model .Stack ()
222
- # -1 to reverse the order
223
- for i in self .storage ['model' ][model_name ]['items' ][::- 1 ]:
224
- if i .repeat .value == 1 :
225
- # -1 to reverse the order
226
- for j in range (len (i .stack ))[::- 1 ]:
227
- structure |= i .stack [j ]
228
- else :
229
- stack = model .Stack ()
230
- # -1 to reverse the order
231
- for j in range (len (i .stack ))[::- 1 ]:
232
- stack |= i .stack [j ]
233
- structure |= model .Repeat (stack , repeat = i .repeat .value )
234
-
235
- q = names .QProbe (
236
- np .linspace (0.001 , 0.3 , 10 ),
237
- np .linspace (0.001 , 0.3 , 10 ),
238
- intensity = self .storage ['model' ][model_name ]['scale' ],
239
- background = self .storage ['model' ][model_name ]['bkg' ],
193
+ sample = _build_sample (self .storage , model_name )
194
+ probe = _get_probe (
195
+ q_array = np .array ([1 ]), # dummy value
196
+ dq_array = np .array ([1 ]), # dummy value
197
+ model_name = model_name ,
198
+ storage = self .storage ,
240
199
)
241
- z , sld , _ = names .Experiment (probe = q , sample = structure ).smooth_profile ()
200
+ z , sld , _ = names .Experiment (probe = probe , sample = sample ).smooth_profile ()
242
201
# -1 to reverse the order
243
202
return z , sld [::- 1 ]
203
+
204
+
205
+ def _get_oversampling_q (q_array : np .ndarray , dq_array : np .ndarray , oversampling_factor : int ) -> np .ndarray :
206
+ argmin = np .argmin (q_array ) # index of the smallest q element
207
+ argmax = np .argmax (q_array ) # index of the largest q element
208
+ return np .linspace (
209
+ q_array [argmin ] - RESOLUTION_PADDING * dq_array [argmin ], # dq element at the smallest q index
210
+ q_array [argmax ] + RESOLUTION_PADDING * dq_array [argmax ], # dq element at the largest q index
211
+ oversampling_factor * len (q_array ),
212
+ )
213
+
214
+
215
+ def _get_probe (
216
+ q_array : np .ndarray ,
217
+ dq_array : np .ndarray ,
218
+ model_name : str ,
219
+ storage : dict ,
220
+ oversampling_factor : int = 1 ,
221
+ ) -> names .QProbe :
222
+ probe = names .QProbe (
223
+ Q = q_array ,
224
+ dQ = dq_array ,
225
+ intensity = storage ['model' ][model_name ]['scale' ],
226
+ background = storage ['model' ][model_name ]['bkg' ],
227
+ )
228
+ if oversampling_factor > 1 :
229
+ probe .calc_Qo = _get_oversampling_q (q_array , dq_array , oversampling_factor )
230
+ return probe
231
+
232
+
233
+ def _get_polarized_probe (
234
+ q_array : np .ndarray ,
235
+ dq_array : np .ndarray ,
236
+ model_name : str ,
237
+ storage : dict ,
238
+ oversampling_factor : int = 1 ,
239
+ all_polarizations : bool = False ,
240
+ ) -> names .QProbe :
241
+ four_probes = []
242
+ for i in range (4 ):
243
+ if i == 0 or all_polarizations :
244
+ probe = _get_probe (
245
+ q_array = q_array ,
246
+ dq_array = dq_array ,
247
+ model_name = model_name ,
248
+ storage = storage ,
249
+ oversampling_factor = oversampling_factor ,
250
+ )
251
+ else :
252
+ probe = None
253
+ four_probes .append (probe )
254
+ return names .PolarizedQProbe (xs = four_probes , name = 'polarized' )
255
+
256
+
257
+ def _build_sample (storage : dict , model_name : str ) -> model .Stack :
258
+ sample = model .Stack ()
259
+ # -1 to reverse the order
260
+ for i in storage ['model' ][model_name ]['items' ][::- 1 ]:
261
+ if i .repeat .value == 1 :
262
+ # -1 to reverse the order
263
+ for j in range (len (i .stack ))[::- 1 ]:
264
+ sample |= i .stack [j ]
265
+ else :
266
+ stack = model .Stack ()
267
+ # -1 to reverse the order
268
+ for j in range (len (i .stack ))[::- 1 ]:
269
+ stack |= i .stack [j ]
270
+ sample |= model .Repeat (stack , repeat = i .repeat .value )
271
+ return sample
0 commit comments