Skip to content

Commit 2bc765f

Browse files
authored
Merge pull request #252 from sbillinge/doccln
Simon tweaks to DO examples
2 parents 641a107 + 6ee7a95 commit 2bc765f

File tree

2 files changed

+150
-71
lines changed

2 files changed

+150
-71
lines changed

doc/source/examples/diffraction_objects_example.rst

Lines changed: 127 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,30 @@ Diffraction Objects Example
88
This example will demonstrate how to use the functions in the ``diffpy.utils.diffraction_objects`` module
99
to 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.

news/doccln.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* Example docs for basic DiffractionObject usage
4+
5+
**Changed:**
6+
7+
* <news item>
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* <news item>
20+
21+
**Security:**
22+
23+
* <news item>

0 commit comments

Comments
 (0)