@@ -175,6 +175,116 @@ def strain_tensor(x): return np.array(
175
175
nosequences ,
176
176
10 ,
177
177
msg = "Few or no rings appeared from diffraction." )
178
+
179
+ def test_polycrystal_from_odf_2phases (self ):
180
+
181
+ unit_cell = [[3.579 , 3.579 , 3.579 , 90. , 90. , 90.0 ],
182
+ [5.46745 , 5.46745 , 5.46745 , 90. , 90. , 90.0 ]]
183
+ sgname = ['F432' , 'F432' ]
184
+
185
+ def orientation_density_function (
186
+ x , q ): return 1. / (np .pi ** 2 ) # uniform ODF
187
+ number_of_crystals = 500
188
+ sample_bounding_cylinder_height = 50
189
+ sample_bounding_cylinder_radius = 25
190
+ maximum_sampling_bin_seperation = np .radians (10.0 )
191
+ # Linear strain gradient along rotation axis.
192
+ def strain_tensor (x ): return np .array (
193
+ [[0 , 0 , 0.02 * x [2 ] / sample_bounding_cylinder_height ], [0 , 0 , 0 ], [0 , 0 , 0 ]])
194
+
195
+ polycrystal = templates .polycrystal_from_odf (
196
+ orientation_density_function ,
197
+ number_of_crystals ,
198
+ sample_bounding_cylinder_height ,
199
+ sample_bounding_cylinder_radius ,
200
+ unit_cell ,
201
+ sgname ,
202
+ path_to_cif_file = None ,
203
+ maximum_sampling_bin_seperation = maximum_sampling_bin_seperation ,
204
+ strain_tensor = strain_tensor )
205
+
206
+ # Compare Euler angle distributions to scipy random uniform orientation
207
+ # sampler
208
+ euler1 = np .array ([Rotation .from_matrix (U ).as_euler (
209
+ 'xyz' , degrees = True ) for U in polycrystal .orientation_lab ])
210
+ euler2 = Rotation .random (10 * euler1 .shape [0 ]).as_euler ('xyz' )
211
+
212
+ for i in range (3 ):
213
+ hist1 , bins = np .histogram (euler1 [:, i ])
214
+ hist2 , bins = np .histogram (euler2 [:, i ])
215
+ hist2 = hist2 / 10.
216
+ # These histograms should look roughly the same
217
+ self .assertLessEqual (
218
+ np .max (
219
+ np .abs (
220
+ hist1 -
221
+ hist2 )),
222
+ number_of_crystals *
223
+ 0.05 ,
224
+ "ODF not sampled correctly." )
225
+
226
+ parameters = {
227
+ "detector_distance" : 191023.9164 ,
228
+ "detector_center_pixel_z" : 256.2345 ,
229
+ "detector_center_pixel_y" : 255.1129 ,
230
+ "pixel_side_length_z" : 181.4234 ,
231
+ "pixel_side_length_y" : 180.2343 ,
232
+ "number_of_detector_pixels_z" : 512 ,
233
+ "number_of_detector_pixels_y" : 512 ,
234
+ "wavelength" : 0.285227 ,
235
+ "beam_side_length_z" : 512 * 200. ,
236
+ "beam_side_length_y" : 512 * 200. ,
237
+ "rotation_step" : np .radians (20.0 ),
238
+ "rotation_axis" : np .array ([0. , 0. , 1.0 ])
239
+ }
240
+
241
+ beam , detector , motion = templates .s3dxrd (parameters )
242
+
243
+ number_of_crystals = 100
244
+ sample_bounding_cylinder_height = 256 * 180 / 128.
245
+ sample_bounding_cylinder_radius = 256 * 180 / 128.
246
+
247
+ polycrystal = templates .polycrystal_from_odf (
248
+ orientation_density_function ,
249
+ number_of_crystals ,
250
+ sample_bounding_cylinder_height ,
251
+ sample_bounding_cylinder_radius ,
252
+ unit_cell ,
253
+ sgname ,
254
+ path_to_cif_file = None ,
255
+ maximum_sampling_bin_seperation = maximum_sampling_bin_seperation ,
256
+ strain_tensor = strain_tensor )
257
+
258
+ polycrystal .transform (motion , time = 0.134 )
259
+ polycrystal .diffract (
260
+ beam ,
261
+ detector ,
262
+ motion ,
263
+ min_bragg_angle = 0 ,
264
+ max_bragg_angle = None ,
265
+ verbose = True )
266
+
267
+ diffraction_pattern = detector .render (
268
+ frames_to_render = 0 ,
269
+ lorentz = False ,
270
+ polarization = False ,
271
+ structure_factor = False ,
272
+ method = "centroid" ,
273
+ verbose = True )
274
+ bins , histogram = utils ._diffractogram (
275
+ diffraction_pattern , parameters ['detector_center_pixel_z' ], parameters ['detector_center_pixel_y' ])
276
+ histogram [histogram < 0.5 * np .median (histogram )] = 0
277
+ csequence , nosequences = 0 , 0
278
+ for i in range (histogram .shape [0 ]):
279
+ if histogram [i ] > 0 :
280
+ csequence += 1
281
+ elif csequence >= 1 :
282
+ nosequences += 1
283
+ csequence = 0
284
+ self .assertGreaterEqual (
285
+ nosequences ,
286
+ 10 ,
287
+ msg = "Few or no rings appeared from diffraction." )
178
288
179
289
def test_get_uniform_powder_sample (self ):
180
290
sample_bounding_radius = 256 * 180 / 128.
0 commit comments