@@ -35,27 +35,84 @@ def _setter_wmsg(attribute):
3535
3636
3737class 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+
3885 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 = {},
4094 ):
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 )
5695
5796 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 ()
59116
60117 def __eq__ (self , other ):
61118 if not isinstance (other , DiffractionObject ):
@@ -231,16 +288,16 @@ def get_array_index(self, value, xtype=None):
231288 the index of the value in the array
232289 """
233290
234- if xtype is None :
235- xtype = self ._input_xtype
291+ xtype = self ._input_xtype
236292 array = self .on_xtype (xtype )[0 ]
237293 if len (array ) == 0 :
238294 raise ValueError (f"The '{ xtype } ' array is empty. Please ensure it is initialized." )
239295 i = (np .abs (array - value )).argmin ()
240296 return i
241297
242- def _set_xarrays (self , xarray , xtype ):
298+ def _set_arrays (self , xarray , yarray , xtype ):
243299 self ._all_arrays = np .empty (shape = (len (xarray ), 4 ))
300+ self ._all_arrays [:, 0 ] = yarray
244301 if xtype .lower () in QQUANTITIES :
245302 self ._all_arrays [:, 1 ] = xarray
246303 self ._all_arrays [:, 2 ] = q_to_tth (xarray , self .wavelength )
@@ -253,70 +310,15 @@ def _set_xarrays(self, xarray, xtype):
253310 self ._all_arrays [:, 3 ] = xarray
254311 self ._all_arrays [:, 1 ] = d_to_q (xarray )
255312 self ._all_arrays [:, 2 ] = d_to_tth (xarray , self .wavelength )
313+
314+ def _set_min_max_xarray (self ):
256315 self .qmin = np .nanmin (self ._all_arrays [:, 1 ], initial = np .inf )
257316 self .qmax = np .nanmax (self ._all_arrays [:, 1 ], initial = 0.0 )
258317 self .tthmin = np .nanmin (self ._all_arrays [:, 2 ], initial = np .inf )
259318 self .tthmax = np .nanmax (self ._all_arrays [:, 2 ], initial = 0.0 )
260319 self .dmin = np .nanmin (self ._all_arrays [:, 3 ], initial = np .inf )
261320 self .dmax = np .nanmax (self ._all_arrays [:, 3 ], initial = 0.0 )
262321
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-
320322 def _get_original_array (self ):
321323 if self ._input_xtype in QQUANTITIES :
322324 return self .on_q (), "q"
0 commit comments