5
5
import numpy as np
6
6
7
7
from diffpy .utils .tools import get_package_info
8
+ from diffpy .utils .transforms import q_to_tth , tth_to_q
8
9
9
10
QQUANTITIES = ["q" ]
10
11
ANGLEQUANTITIES = ["angle" , "tth" , "twotheta" , "2theta" ]
17
18
"and specifying how to handle the mismatch."
18
19
)
19
20
20
- wavelength_warning_emsg = (
21
- "INFO: no wavelength has been specified. You can continue "
22
- "to use the DiffractionObject but some of its powerful features "
23
- "will not be available. To specify a wavelength, set "
24
- "diffraction_object.wavelength = [number], "
25
- "where diffraction_object is the variable name of you Diffraction Object, "
26
- "and number is the wavelength in angstroms."
27
- )
28
-
29
- length_mismatch_emsg = "Please ensure {array_name} array and intensity array are of the same length."
30
- non_numeric_value_emsg = "Invalid value found in {array_name} array. Please ensure all values are numeric."
31
- invalid_tth_emsg = "Two theta exceeds 180 degrees. Please check the input values for errors."
32
- invalid_q_or_wavelength_emsg = (
33
- "The supplied q-array and wavelength will result in an impossible two-theta. "
34
- "Please check these values and re-instantiate the DiffractionObject with correct values."
35
- )
36
-
37
21
38
22
class Diffraction_object :
39
23
"""A class to represent and manipulate data associated with diffraction experiments.
@@ -54,9 +38,9 @@ def __init__(self, name="", wavelength=None):
54
38
self .name = name
55
39
self .wavelength = wavelength
56
40
self .scat_quantity = ""
57
- self .on_q = [np .empty (0 ), np .empty (0 )]
58
- self .on_tth = [np .empty (0 ), np .empty (0 )]
59
- self .on_d = [np .empty (0 ), np .empty (0 )]
41
+ self .on_q = np . array ( [np .empty (0 ), np .empty (0 )])
42
+ self .on_tth = np . array ( [np .empty (0 ), np .empty (0 )])
43
+ self .on_d = np . array ( [np .empty (0 ), np .empty (0 )])
60
44
self ._all_arrays = [self .on_q , self .on_tth ]
61
45
self .metadata = {}
62
46
@@ -311,97 +295,19 @@ def insert_scattering_quantity(
311
295
if wavelength is not None :
312
296
self .wavelength = wavelength
313
297
if xtype .lower () in QQUANTITIES :
314
- self .on_q = [ np .array (xarray ), np . array ( yarray )]
298
+ self .on_q = np .array ([ xarray , yarray ])
315
299
elif xtype .lower () in ANGLEQUANTITIES :
316
- self .on_tth = [ np .array (xarray ), np . array ( yarray )]
300
+ self .on_tth = np .array ([ xarray , yarray ])
317
301
elif xtype .lower () in DQUANTITIES :
318
- self .on_tth = [ np .array (xarray ), np . array ( yarray )]
302
+ self .on_tth = np .array ([ xarray , yarray ])
319
303
self .set_all_arrays ()
320
304
321
- def q_to_tth (self ):
322
- r"""
323
- Helper function to convert q to two-theta.
324
-
325
- By definition the relationship is:
326
-
327
- .. math::
328
-
329
- \sin\left(\frac{2\theta}{2}\right) = \frac{\lambda q}{4 \pi}
330
-
331
- thus
332
-
333
- .. math::
334
-
335
- 2\theta_n = 2 \arcsin\left(\frac{\lambda q}{4 \pi}\right)
336
-
337
- Parameters
338
- ----------
339
- q : array
340
- An array of :math:`q` values
341
-
342
- wavelength : float
343
- Wavelength of the incoming x-rays
344
-
345
- Function adapted from scikit-beam. Thanks to those developers
346
-
347
- Returns
348
- -------
349
- two_theta : array
350
- An array of :math:`2\theta` values in radians
351
- """
352
- q = self .on_q [0 ]
353
- q = np .asarray (q )
354
- wavelength = float (self .wavelength )
355
- pre_factor = wavelength / (4 * np .pi )
356
- return np .rad2deg (2.0 * np .arcsin (q * pre_factor ))
357
-
358
- def tth_to_q (self ):
359
- r"""
360
- Helper function to convert two-theta to q
361
-
362
- By definition the relationship is
363
-
364
- .. math::
365
-
366
- \sin\left(\frac{2\theta}{2}\right) = \frac{\lambda q}{4 \pi}
367
-
368
- thus
369
-
370
- .. math::
371
-
372
- q = \frac{4 \pi \sin\left(\frac{2\theta}{2}\right)}{\lambda}
373
-
374
-
375
-
376
- Parameters
377
- ----------
378
- two_theta : array
379
- An array of :math:`2\theta` values in units of degrees
380
-
381
- wavelength : float
382
- Wavelength of the incoming x-rays
383
-
384
- Function adapted from scikit-beam. Thanks to those developers.
385
-
386
- Returns
387
- -------
388
- q : array
389
- An array of :math:`q` values in the inverse of the units
390
- of ``wavelength``
391
- """
392
- two_theta = np .asarray (np .deg2rad (self .on_tth [0 ]))
393
- wavelength = float (self .wavelength )
394
- pre_factor = (4 * np .pi ) / wavelength
395
- return pre_factor * np .sin (two_theta / 2 )
396
-
397
305
def set_all_arrays (self ):
398
306
master_array , xtype = self ._get_original_array ()
399
307
if xtype == "q" :
400
- self .on_tth [0 ] = self .q_to_tth ()
401
- self .on_tth [1 ] = master_array [1 ]
402
- if xtype == "tth" :
403
- self .on_q [0 ] = self .tth_to_q ()
404
- self .on_q [1 ] = master_array [1 ]
308
+ self .on_tth = q_to_tth (self .on_q , self .wavelength )
309
+ elif xtype == "tth" :
310
+ self .on_q = tth_to_q (self .on_tth , self .wavelength )
405
311
self .tthmin = self .on_tth [0 ][0 ]
406
312
self .tthmax = self .on_tth [0 ][- 1 ]
407
313
self .qmin = self .on_q [0 ][0 ]
@@ -500,9 +406,9 @@ def __init__(self, name="", wavelength=None):
500
406
self .name = name
501
407
self .wavelength = wavelength
502
408
self .scat_quantity = ""
503
- self .on_q = [ np .empty (0 ), np .empty ( 0 )]
504
- self .on_tth = [ np .empty (0 ), np .empty ( 0 )]
505
- self .on_d = [ np .empty (0 ), np .empty ( 0 )]
409
+ self .on_q = np .empty (( 2 , 0 ), dtype = np .float64 )
410
+ self .on_tth = np .empty (( 2 , 0 ), dtype = np .float64 )
411
+ self .on_d = np .empty (( 2 , 0 ), dtype = np .float64 )
506
412
self ._all_arrays = [self .on_q , self .on_tth ]
507
413
self .metadata = {}
508
414
@@ -757,115 +663,19 @@ def insert_scattering_quantity(
757
663
if wavelength is not None :
758
664
self .wavelength = wavelength
759
665
if xtype .lower () in QQUANTITIES :
760
- self .on_q = [ np .array (xarray ), np . array ( yarray )]
666
+ self .on_q = np .array ([ xarray , yarray ])
761
667
elif xtype .lower () in ANGLEQUANTITIES :
762
- self .on_tth = [ np .array (xarray ), np . array ( yarray )]
763
- elif xtype .lower () in DQUANTITIES :
764
- self .on_tth = [ np .array (xarray ), np . array ( yarray )]
668
+ self .on_tth = np .array ([ xarray , yarray ])
669
+ elif xtype .lower () in DQUANTITIES : # Fixme when d is implemented. This here as a placeholder
670
+ self .on_tth = np .array ([ xarray , yarray ])
765
671
self .set_all_arrays ()
766
672
767
- def q_to_tth (self ):
768
- r"""
769
- Helper function to convert q to two-theta.
770
-
771
- By definition the relationship is:
772
-
773
- .. math::
774
-
775
- \sin\left(\frac{2\theta}{2}\right) = \frac{\lambda q}{4 \pi}
776
-
777
- thus
778
-
779
- .. math::
780
-
781
- 2\theta_n = 2 \arcsin\left(\frac{\lambda q}{4 \pi}\right)
782
-
783
- Function adapted from scikit-beam. Thanks to those developers
784
-
785
- Parameters
786
- ----------
787
- q : array
788
- The array of :math:`q` values
789
-
790
- wavelength : float
791
- Wavelength of the incoming x-rays
792
-
793
- Returns
794
- -------
795
- two_theta : array
796
- The array of :math:`2\theta` values in radians
797
- """
798
- for i , value in enumerate (self .on_q [0 ]):
799
- if not isinstance (value , (int , float )):
800
- raise TypeError (non_numeric_value_emsg .format (array_name = "q" ))
801
- if len (self .on_q [0 ]) != len (self .on_q [1 ]):
802
- raise RuntimeError (length_mismatch_emsg .format (array_name = "q" ))
803
- if self .wavelength is None :
804
- warnings .warn (wavelength_warning_emsg , UserWarning )
805
- return np .empty (0 )
806
- q = self .on_q [0 ]
807
- q = np .asarray (q )
808
- wavelength = float (self .wavelength )
809
- pre_factor = wavelength / (4 * np .pi )
810
- if np .any (np .abs (q * pre_factor ) > 1 ):
811
- raise ValueError (invalid_q_or_wavelength_emsg )
812
- return np .rad2deg (2.0 * np .arcsin (q * pre_factor ))
813
-
814
- def tth_to_q (self ):
815
- r"""
816
- Helper function to convert two-theta to q
817
-
818
- By definition the relationship is
819
-
820
- .. math::
821
-
822
- \sin\left(\frac{2\theta}{2}\right) = \frac{\lambda q}{4 \pi}
823
-
824
- thus
825
-
826
- .. math::
827
-
828
- q = \frac{4 \pi \sin\left(\frac{2\theta}{2}\right)}{\lambda}
829
-
830
- Function adapted from scikit-beam. Thanks to those developers.
831
-
832
- Parameters
833
- ----------
834
- two_theta : array
835
- The array of :math:`2\theta` values in units of degrees
836
-
837
- wavelength : float
838
- Wavelength of the incoming x-rays
839
-
840
- Returns
841
- -------
842
- q : array
843
- The array of :math:`q` values in the inverse of the units
844
- of ``wavelength``
845
- """
846
- for i , value in enumerate (self .on_tth [0 ]):
847
- if not isinstance (value , (int , float )):
848
- raise TypeError (non_numeric_value_emsg .format (array_name = "two theta" ))
849
- if len (self .on_tth [0 ]) != len (self .on_tth [1 ]):
850
- raise RuntimeError (length_mismatch_emsg .format (array_name = "two theta" ))
851
- two_theta = np .asarray (np .deg2rad (self .on_tth [0 ]))
852
- if np .any (two_theta > np .pi ):
853
- raise ValueError (invalid_tth_emsg )
854
- if self .wavelength is None :
855
- warnings .warn (wavelength_warning_emsg , UserWarning )
856
- return np .empty (0 )
857
- wavelength = float (self .wavelength )
858
- pre_factor = (4 * np .pi ) / wavelength
859
- return pre_factor * np .sin (two_theta / 2 )
860
-
861
673
def set_all_arrays (self ):
862
674
master_array , xtype = self ._get_original_array ()
863
675
if xtype == "q" :
864
- self .on_tth [0 ] = self .q_to_tth ()
865
- self .on_tth [1 ] = master_array [1 ]
866
- if xtype == "tth" :
867
- self .on_q [0 ] = self .tth_to_q ()
868
- self .on_q [1 ] = master_array [1 ]
676
+ self .on_tth = q_to_tth (self .on_q , self .wavelength )
677
+ elif xtype == "tth" :
678
+ self .on_q = tth_to_q (self .on_tth , self .wavelength )
869
679
self .tthmin = self .on_tth [0 ][0 ]
870
680
self .tthmax = self .on_tth [0 ][- 1 ]
871
681
self .qmin = self .on_q [0 ][0 ]
0 commit comments