@@ -8,27 +8,30 @@ Diffraction Objects Example
88This example will demonstrate how to use the functions in the ``diffpy.utils.diffraction_objects `` module
99to create a ``DiffractionObject `` instance and analyze your diffraction data using relevant functions.
1010
11- 1) To create a ``DiffractionObject ``, you need to specify the type of the independent variable
12- (referred to as ``xtype ``, one of ``q ``, ``tth ``, or ``d ``),
13- an ``xarray `` of the corresponding values, and a ``yarray `` of the intensity values.
14- It is strongly encouraged to specify the ``wavelength `` in order to access
15- most of the other functionalities in the class.
16- Additionally, you can specify the type of your scattering experiment using the ``scat_quantity `` parameter,
17- the name of your diffraction object using the ``name `` parameter,
18- and a ``metadata `` dictionary containing relevant information about the data. Here's an example:
11+ To create a ``DiffractionObject ``, you need to specify the type of the independent variable
12+ (referred to as ``xtype ``, e.g. , one of ``q ``, ``tth ``, or ``d ``),
13+ the ``xarray `` of the `` x `` values, and a ``yarray `` of the corresponding intensity values.
14+ It is strongly encouraged to specify the ``wavelength `` in order to access
15+ most of the other functionalities in the class.
16+ Additionally, you can specify the type of your scattering experiment using the ``scat_quantity `` parameter,
17+ the name of your diffraction object using the ``name `` parameter,
18+ and a ``metadata `` dictionary containing relevant information about the data. Here's an example:
1919
2020.. code-block :: python
21+
2122 import numpy as np
2223 from diffpy.utils.diffraction_objects import DiffractionObject
24+
2325 x = np.array([0.12 , 0.24 , 0.31 , 0.4 ]) # independent variable (e.g., q)
2426 y = np.array([10 , 20 , 40 , 60 ]) # intensity values
2527 metadata = {
2628 " sample" : " rock salt from the beach" ,
2729 " composition" : " NaCl" ,
2830 " temperature" : " 300 K," ,
29- " experimenters" : " Phill, Sally"
31+ " experimenters" : [ " Phil " , " Sally" ]
3032 }
31- do = DiffractionObject(
33+
34+ my_do = DiffractionObject(
3235 xarray = x,
3336 yarray = y,
3437 xtype = " q" ,
@@ -37,90 +40,143 @@ to create a ``DiffractionObject`` instance and analyze your diffraction data usi
3740 name = " beach_rock_salt_1" ,
3841 metadata = metadata
3942 )
40- print (do.metadata)
4143
42- By creating a `` DiffractionObject`` instance, you store not only the diffraction data
43- but also all the associated information for analysis.
44+ By creating a ``DiffractionObject `` instance, you store not only the diffraction data
45+ but also all the associated information for analysis.
4446
45- 2 ) `` DiffractionObject`` automatically populates the `` xarray`` onto `` q`` , `` tth`` , and `` d`` - spacing.
46- If you want to access your diffraction data in a specific spacing, you can do this:
47+ ``DiffractionObject `` automatically populates the ``xarray `` onto each of ``q ``, ``tth ``, and ``d ``-spacing.
48+ Let's say you want to plot your data vs. Q. To do this you would type
4749
4850.. code-block :: python
49- q = do.on_xtype(" q" )
50- tth = do.on_xtype(" tth" )
51- d = do.on_xtype(" d" )
5251
53- This will return the `` xarray `` and `` yarray `` as a list of two 1D arrays, based on the specified `` xtype `` .
52+ import matplotlib.pyplot as plt
5453
55- 3) Once the ``DiffractionObject `` is created, you can use ``get_array_index `` to get the index of the closest value
56- in the ``xarray `` to a specified value.
57- This is useful for alignment or comparison tasks.
58- For example, assume you have created a ``DiffractionObject `` called ``do ``,
59- and you want to find the closest index of ``tth=80 ``, you can type the following: ::
54+ plt.plot(my_do.on_q()[0 ], my_do.on_q()[1 ])
6055
61- index = do.get_array_index(80, xtype="tth")
56+ and to plot the same data vs. two-theta type
57+
58+ .. code-block :: python
6259
63- If you do not specify an ``xtype ``, it will default to the ``xtype `` used when creating the ``DiffractionObject ``.
64- For example, if you have created a ``DiffractionObject `` called ``do `` with ``xtype="q" ``,
65- you can find its closest index for ``q=0.25 `` by typing either of the following: ::
60+ plt.plot(my_do.on_tth()[0 ], my_do.on_tth()[1 ])
6661
67- index = do.get_array_index(0.25) # no input xtype, defaults to q
68- index = do.get_array_index(0.25, xtype="q")
62+ These ` on_q() `, ` on_tth() `, etc., methods return a list with the x-array as the first element
63+ and the intensity array as the second element.
6964
70- 4) You can compare diffraction objects too.
71- For example, you can use the ``scale_to `` function to rescale one diffraction object to align its intensity values
72- with a second diffraction object at a (closest) specified value on a specified ``xarray ``.
73- This makes it easier for visualizing and comparing two intensity curves on the same plot.
74- For example, to scale ``do1 `` to match ``do2 `` at ``tth=60 ``:
65+ We can also accomplish the same thing by passing the xtype as a string to the ``on_xtype() `` method,
66+ i.e.,
67+
68+ .. code-block :: python
69+
70+ data_on_q = my_do.on_xtype(" q" )
71+ data_on_tth = my_do.on_xtype(" tth" )
72+ data_on_d = my_do.on_xtype(" d" )
73+ plt.plot(data_on_d[0 ], data_on_d[1 ])
74+
75+ This makes it very easy to compare a diffractioh pattern that was measured or calculated
76+ on one ``xtype `` with one that was measured or calculated on another. E.g., suppose that you
77+ have a calculated powder pattern from a CIF file that was calculated on a d-spacing grid using
78+ some software package, and
79+ you want to know if a diffraction pattern you have measured on a Q-grid is the same material.
80+ You could simply load them both as diffraction objects and plot them together on the same grid.
81+
82+ .. code-block :: python
83+
84+ calculated = DiffractionObject(xcalc, ycalc, " d" )
85+ measured = DiffractionObject(xmeas, ymeas, " tth" , wavelength = 0.717 )
86+ plt.plot(calculated.on_q()[0 ], calculated.on_q()[1 ])
87+ plt.plot(measured.on_q()[0 ], measured.on_q()[1 ])
88+ plt.show
89+
90+ Now, let's say that these two diffraction patterns were on very different scales. The measured one
91+ has a peak intensity of 10,000, but the calculated one only goes to 1.
92+ With diffraction objects this is easy to handle. We choose a point on the x-axis where
93+ we want to scale the two together and we use the ``scale_to() `` method,
94+
95+ Continuing the example above, if we wanted to scale the two patterns together at a position
96+ Q=5.5 inverse angstroms, where for the sake of argument we assume the
97+ calculated curve has a strong peak,
98+ we would replace the code above with
99+
100+ .. code-block :: python
101+
102+ plt.plot(calculated.on_q()[0 ], calculated.on_q()[1 ])
103+ plt.plot(measured.on_q().scale_to(calculated, q = 5.5 )[0 ], measured.on_q().scale_to(calculated, q = 5.5 )[1 ])
104+ plt.show
105+
106+ The ``scale_to() `` method returns a new ``DiffractionObject `` which we can assign to a new
107+ variable and make use of,
75108
76109.. code-block :: python
77- # Create Diffraction Objects do1 and do2
78- do1 = DiffractionObject(
79- xarray = np.array([10 , 15 , 25 , 30 , 60 , 140 ]),
80- yarray = np.array([10 , 20 , 25 , 30 , 60 , 100 ]),
81- xtype = " tth" ,
82- wavelength = 2 * np.pi
83- )
84- do2 = DiffractionObject(
85- xarray = np.array([10 , 20 , 25 , 30 , 60 , 140 ]),
86- yarray = np.array([2 , 3 , 4 , 5 , 6 , 7 ]),
87- xtype = " tth" ,
88- wavelength = 2 * np.pi
89- )
90- do1_scaled = do1.scale_to(do2, tth = 60 )
91110
92- Here, the scaling factor is computed at `` tth= 60 `` , aligning the intensity values.
93- `` do1_scaled`` will have the intensity array `` np.array([1 , 2 , 2.5 , 3 , 6 , 10 ])`` .
94- You can also scale based on other axes (e.g., `` q = 0.2 `` ): ::
111+ scaled_measured = measured.scale_to(calculated, q = 5.5 )
95112
96- do1_scaled = do1.scale_to(do2, q = 0.2 )
113+ For convenience, you can also apply an offset to the scaled new diffraction object with the optional
114+ ``offset `` argument, for example,
97115
98- The function finds the closest indices for `` q=0.2 `` and scales the `` yarray`` accordingly.
116+ .. code-block :: python
117+
118+ scaled_and_offset_measured = measured.scale_to(calculated, q = 5.5 , offset = 0.5 )
119+
120+ DiffractionObject convenience functions
121+ ---------------------------------------
122+
123+ 1) create a copy of a diffraction object using the ``copy `` method
124+ when you want to preserve the original data while working with a modified version.
125+
126+ .. code-block :: python
127+
128+ copy_of_calculated = calculated.copy()
129+
130+ 2) test the equality of two diffraction objects. For example,
131+
132+ .. code-block :: python
99133
100- Additionally, you can apply an `` offset`` to the scaled `` yarray`` . For example: ::
134+ diff_object2 = diff_object1.copy()
135+ diff_object2 == diff_object1
101136
102- do1_scaled = do1.scale_to(do2, tth = 60 , offset = 2 ) # add 2 to the scaled yarray
103- do1_scaled = do1.scale_to(do2, tth = 60 , offset = - 2 ) # subtract 2 from the scaled yarray
137+ will return `` True ``
104138
105- This allows you to shift the scaled data for easier comparison.
139+ 3) make arithmetic operations on the intensities of diffraction objects. e.g.,
140+
141+ .. code-block :: python
142+
143+ doubled_object = 2 * diff_object1 # Double the intensities
144+ sum_object = diff_object1 + diff_object2 # Sum the intensities
145+ subtract_scaled = diff_object1 - 5 * diff_object2 # subtract 5 * obj2 from obj 1
146+
147+ 4) get the value of the DiffractionObject at a given point in one of the xarrays
148+
149+ .. code-block :: python
150+
151+ tth_ninety_index = diff_object1.get_array_index(90 , xtype = " tth" )
152+ intensity_at_ninety = diff_object1.on_tth()[tth_ninety_index]
153+
154+ If you do not specify an ``xtype ``, it will default to the ``xtype `` used when creating the ``DiffractionObject ``.
155+ For example, if you have created a ``DiffractionObject `` called ``do `` with ``xtype="q" ``,
156+ you can find its closest index for ``q=0.25 `` by typing either of the following:
157+
158+ .. code-block :: python
106159
107- 5 ) You can create a copy of a diffraction object using the `` copy`` function,
108- when you want to preserve the original data while working with a modified version. ::
160+ print (do._input_xtype) # remind ourselves which array was input. prints "q" in this case.
161+ index = do.get_array_index(0.25 ) # no xtype passed, defaults to do._input_xtype, or in this example, q
162+ index = do.get_array_index(0.25 , xtype = " q" ) # explicitly choose an xtype to specify a value
109163
110- # Create a copy of Diffraction Object do
111- do_copy = do.copy()
164+ 5) The ``dump `` function saves the diffraction data and relevant information to an xy format file with headers
165+ (widely used chi format used, for example, by Fit2D and diffpy. These files can be read by ``LoadData() ``
166+ in ``diffpy.utils.parsers ``).
112167
113- 6 ) The `` dump`` function saves the diffraction data and relevant information to a specified file .
114- You can choose one of the data axis (`` q`` , `` tth`` , or `` d`` ) to export, with `` q`` as the default.
168+ You can choose which of the data axes (``q ``, ``tth ``, or ``d ``) to export, with ``q `` as the default.
115169
116170.. code-block :: python
117171 # Assume you have created a Diffraction Object do
118- file = " diffraction_data.xy "
172+ file = " diffraction_data.chi "
119173 do.dump(file , xtype = " q" )
120174
121- In the saved file " diffraction_data.xy" ,
122- the relevant information (name, scattering quantity, metadata, etc.) is included in the header.
123- Your analysis time and software version are automatically recorded as well.
124- The diffraction data is saved as two columns: the `` q`` values and corresponding intensity values.
125- This ensures your diffraction data, along with all other information,
126- is properly documented and saved for future reference.
175+ In the saved file ``diffraction_data.chi ``,
176+ relevant metadata are also written in the header (``username ``, ``name ``, ``scattering quantity ``, ``metadata ``, etc.).
177+ The datetime when the DiffractionObject was created and the version of the
178+ software (see the Section on ``get_package_info() `` for more information)
179+ is automatically recorded as well.
180+ The diffraction data is saved as two columns: the ``q `` values and corresponding intensity values.
181+ This ensures your diffraction data, along with all other information,
182+ is properly documented and saved for future reference.
0 commit comments