@@ -35,27 +35,84 @@ def _setter_wmsg(attribute):
35
35
36
36
37
37
class DiffractionObject :
38
+ """
39
+ Initialize a DiffractionObject instance.
40
+
41
+ Parameters
42
+ ----------
43
+ xarray : array-like
44
+ The independent variable array containing "q", "tth", or "d" values.
45
+ yarray : array-like
46
+ The dependent variable array corresponding to intensity values.
47
+ xtype : str
48
+ The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}.
49
+ wavelength : float, optional
50
+ The wavelength of the incoming beam, specified in angstroms (Å). Default is none.
51
+ scat_quantity : str, optional
52
+ The type of scattering experiment (e.g., "x-ray", "neutron"). Default is an empty string "".
53
+ name : str, optional
54
+ The name or label for the scattering data. Default is an empty string "".
55
+ metadata : dict, optional
56
+ The additional metadata associated with the diffraction object. Default is {}.
57
+
58
+ Examples
59
+ --------
60
+ Create a DiffractionObject for X-ray scattering data:
61
+
62
+ >>> import numpy as np
63
+ >>> from diffpy.utils.diffraction_objects import DiffractionObject
64
+ ...
65
+ >>> x = np.array([0.12, 0.24, 0.31, 0.4]) # independent variable (e.g., q)
66
+ >>> y = np.array([10, 20, 40, 60]) # intensity values
67
+ >>> metadata = {
68
+ ... "sample": "rock salt from the beach",
69
+ ... "composition": "NaCl",
70
+ ... "temperature": "300 K,",
71
+ ... "experimenters": "Phill, Sally"
72
+ ... }
73
+ >>> do = DiffractionObject(
74
+ ... xarray=x,
75
+ ... yarray=y,
76
+ ... xtype="q",
77
+ ... wavelength=1.54,
78
+ ... scat_quantity="x-ray",
79
+ ... name="beach_rock_salt_1",
80
+ ... metadata=metadata
81
+ ... )
82
+ >>> print(do.metadata)
83
+ """
84
+
38
85
def __init__ (
39
- self , name = None , wavelength = None , scat_quantity = None , metadata = None , xarray = None , yarray = None , xtype = None
86
+ self ,
87
+ xarray ,
88
+ yarray ,
89
+ xtype ,
90
+ wavelength = None ,
91
+ scat_quantity = "" ,
92
+ name = "" ,
93
+ metadata = {},
40
94
):
41
- if name is None :
42
- name = ""
43
- self .name = name
44
- if metadata is None :
45
- metadata = {}
46
- self .metadata = metadata
47
- if xtype is None :
48
- xtype = ""
49
- self .scat_quantity = scat_quantity
50
- self .wavelength = wavelength
51
-
52
- if xarray is None :
53
- xarray = np .empty (0 )
54
- if yarray is None :
55
- yarray = np .empty (0 )
56
95
57
96
self ._id = uuid .uuid4 ()
58
- self .input_data (xarray , yarray , xtype )
97
+ self ._input_data (xarray , yarray , xtype , wavelength , scat_quantity , name , metadata )
98
+
99
+ def _input_data (self , xarray , yarray , xtype , wavelength , scat_quantity , name , metadata ):
100
+ if xtype not in XQUANTITIES :
101
+ raise ValueError (_xtype_wmsg (xtype ))
102
+ if len (xarray ) != len (yarray ):
103
+ raise ValueError (
104
+ "'xarray' and 'yarray' are different lengths. They must "
105
+ "correspond to each other and have the same length. "
106
+ "Please re-initialize 'DiffractionObject'"
107
+ "with valid 'xarray' and 'yarray's"
108
+ )
109
+ self .scat_quantity = scat_quantity
110
+ self .wavelength = wavelength
111
+ self .metadata = metadata
112
+ self .name = name
113
+ self ._input_xtype = xtype
114
+ self ._set_arrays (xarray , yarray , xtype )
115
+ self ._set_min_max_xarray ()
59
116
60
117
def __eq__ (self , other ):
61
118
if not isinstance (other , DiffractionObject ):
@@ -231,16 +288,16 @@ def get_array_index(self, value, xtype=None):
231
288
the index of the value in the array
232
289
"""
233
290
234
- if xtype is None :
235
- xtype = self ._input_xtype
291
+ xtype = self ._input_xtype
236
292
array = self .on_xtype (xtype )[0 ]
237
293
if len (array ) == 0 :
238
294
raise ValueError (f"The '{ xtype } ' array is empty. Please ensure it is initialized." )
239
295
i = (np .abs (array - value )).argmin ()
240
296
return i
241
297
242
- def _set_xarrays (self , xarray , xtype ):
298
+ def _set_arrays (self , xarray , yarray , xtype ):
243
299
self ._all_arrays = np .empty (shape = (len (xarray ), 4 ))
300
+ self ._all_arrays [:, 0 ] = yarray
244
301
if xtype .lower () in QQUANTITIES :
245
302
self ._all_arrays [:, 1 ] = xarray
246
303
self ._all_arrays [:, 2 ] = q_to_tth (xarray , self .wavelength )
@@ -253,70 +310,15 @@ def _set_xarrays(self, xarray, xtype):
253
310
self ._all_arrays [:, 3 ] = xarray
254
311
self ._all_arrays [:, 1 ] = d_to_q (xarray )
255
312
self ._all_arrays [:, 2 ] = d_to_tth (xarray , self .wavelength )
313
+
314
+ def _set_min_max_xarray (self ):
256
315
self .qmin = np .nanmin (self ._all_arrays [:, 1 ], initial = np .inf )
257
316
self .qmax = np .nanmax (self ._all_arrays [:, 1 ], initial = 0.0 )
258
317
self .tthmin = np .nanmin (self ._all_arrays [:, 2 ], initial = np .inf )
259
318
self .tthmax = np .nanmax (self ._all_arrays [:, 2 ], initial = 0.0 )
260
319
self .dmin = np .nanmin (self ._all_arrays [:, 3 ], initial = np .inf )
261
320
self .dmax = np .nanmax (self ._all_arrays [:, 3 ], initial = 0.0 )
262
321
263
- def input_data (
264
- self ,
265
- xarray ,
266
- yarray ,
267
- xtype ,
268
- metadata = {},
269
- scat_quantity = None ,
270
- name = None ,
271
- wavelength = None ,
272
- ):
273
- f"""
274
- insert a new scattering quantity into the scattering object
275
-
276
- Parameters
277
- ----------
278
- xarray array-like of floats
279
- the independent variable array
280
- yarray array-like of floats
281
- the dependent variable array
282
- xtype string
283
- the type of quantity for the independent variable from { * XQUANTITIES , }
284
- metadata, scat_quantity, name and wavelength are optional. They have the same
285
- meaning as in the constructor. Values will only be overwritten if non-empty values are passed.
286
-
287
- Returns
288
- -------
289
- Nothing. Updates the object in place.
290
-
291
- """
292
-
293
- # Check xarray and yarray have the same length
294
- if len (xarray ) != len (yarray ):
295
- raise ValueError (
296
- "'xarray' and 'yarray' must have the same length. "
297
- "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' "
298
- "with 'xarray' and 'yarray' of identical length."
299
- )
300
-
301
- self ._set_xarrays (xarray , xtype )
302
- self ._all_arrays [:, 0 ] = yarray
303
- self ._input_xtype = xtype
304
- # only update these optional values if non-empty quantities are passed to avoid overwriting
305
- # valid data inadvertently
306
- if metadata :
307
- self .metadata = metadata
308
- if scat_quantity is not None :
309
- self .scat_quantity = scat_quantity
310
- if name is not None :
311
- self .name = name
312
- if wavelength is not None :
313
- self .wavelength = wavelength
314
-
315
- # Check xtype is valid. An empty string is the default value.
316
- if xtype != "" :
317
- if xtype not in XQUANTITIES :
318
- raise ValueError (_xtype_wmsg (xtype ))
319
-
320
322
def _get_original_array (self ):
321
323
if self ._input_xtype in QQUANTITIES :
322
324
return self .on_q (), "q"
0 commit comments