Skip to content

Commit 03eaa87

Browse files
initial commit, add docstring and tests
1 parent ed9fb03 commit 03eaa87

File tree

2 files changed

+117
-14
lines changed

2 files changed

+117
-14
lines changed

src/diffpy/utils/transforms.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"The supplied q-array and wavelength will result in an impossible two-theta. "
1717
"Please check these values and re-instantiate the DiffractionObject with correct values."
1818
)
19+
invalid_input_emsg = (
20+
"Input values have resulted in an infinite output. Please ensure there are no zeros in the input."
21+
)
1922

2023

2124
def _validate_inputs(q, wavelength):
@@ -58,7 +61,7 @@ def q_to_tth(q, wavelength):
5861
-------
5962
tth : 1D array
6063
The array of :math:`2\theta` values in degrees numpy.array([tths]).
61-
This is the correct format for loading into diffpy.utils.DiffractionOject.on_tth
64+
This is the correct format for loading into diffpy.utils.DiffractionObject.on_tth.
6265
"""
6366
_validate_inputs(q, wavelength)
6467
q.astype(float)
@@ -92,21 +95,19 @@ def tth_to_q(tth, wavelength):
9295
9396
Parameters
9497
----------
95-
tth : 2D array
96-
The array of :math:`2\theta` values and :math: 'i' intensity values, np.array([[tths], [is]]).
97-
This is the same format as, and so can accept, diffpy.utils.DiffractionOject.on_tth
98+
tth : 1D array
99+
The array of :math:`2\theta` values np.array([tths]).
98100
The units of tth are expected in degrees.
99101
100102
wavelength : float
101103
Wavelength of the incoming x-rays/neutrons/electrons
102104
103105
Returns
104106
-------
105-
on_q : 2D array
106-
The array of :math:`q` values and :math: 'i' intensity values unchanged,
107-
np.array([[qs], [is]]).
107+
q : 1D array
108+
The array of :math:`q` values np.array([qs]).
108109
The units for the q-values are the inverse of the units of the provided wavelength.
109-
This is the correct format for loading into diffpy.utils.DiffractionOject.on_q
110+
This is the correct format for loading into diffpy.utils.DiffractionObject.on_q.
110111
"""
111112
tth.astype(float)
112113
if np.any(np.deg2rad(tth) > np.pi):
@@ -121,17 +122,49 @@ def tth_to_q(tth, wavelength):
121122
return q
122123

123124

124-
def q_to_d(qarray):
125-
return 2.0 * np.pi / copy(qarray)
125+
def q_to_d(q):
126+
r"""
127+
Helper function to convert q to d on independent variable axis, using :math:`d = \frac{2 \pi}{q}`.
128+
129+
Parameters
130+
----------
131+
q : 1D array
132+
The array of :math:`q` values np.array([qs]).
133+
The units of q must be reciprocal of the units of wavelength.
134+
135+
Returns
136+
-------
137+
d : 1D array
138+
The array of :math:`d` values np.array([ds]).
139+
"""
140+
if 0 in q:
141+
raise ValueError(invalid_input_emsg)
142+
return 2.0 * np.pi / copy(q)[::-1]
126143

127144

128145
def tth_to_d(ttharray, wavelength):
129146
qarray = tth_to_q(ttharray, wavelength)
130147
return 2.0 * np.pi / copy(qarray)
131148

132149

133-
def d_to_q(darray):
134-
return 2.0 * np.pi / copy(darray)
150+
def d_to_q(d):
151+
r"""
152+
Helper function to convert q to d using :math:`d = \frac{2 \pi}{q}`.
153+
154+
Parameters
155+
----------
156+
d : 1D array
157+
The array of :math:`d` values np.array([ds]).
158+
159+
Returns
160+
-------
161+
q : 1D array
162+
The array of :math:`q` values np.array([qs]).
163+
The units of q must be reciprocal of the units of wavelength.
164+
"""
165+
if 0 in d:
166+
raise ValueError(invalid_input_emsg)
167+
return 2.0 * np.pi / copy(d)[::-1]
135168

136169

137170
def d_to_tth(darray, wavelength):

tests/test_transforms.py

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
import pytest
33

4-
from diffpy.utils.transforms import q_to_tth, tth_to_q
4+
from diffpy.utils.transforms import d_to_q, q_to_d, q_to_tth, tth_to_q
55

66
params_q_to_tth = [
77
# UC1: Empty q values, no wavelength, return empty arrays
@@ -64,7 +64,7 @@ def test_q_to_tth_bad(inputs, expected):
6464
np.array([0, 1, 2, 3, 4, 5]),
6565
),
6666
# UC3: User specified valid tth values between 0-180 degrees (with wavelength)
67-
# expected q vales are sin15, sin30, sin45, sin60, sin90
67+
# expected q values are sin15, sin30, sin45, sin60, sin90
6868
(
6969
[4 * np.pi, np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0])],
7070
np.array([0, 0.258819, 0.5, 0.707107, 0.866025, 1]),
@@ -96,3 +96,73 @@ def test_tth_to_q(inputs, expected):
9696
def test_tth_to_q_bad(inputs, expected):
9797
with pytest.raises(expected[0], match=expected[1]):
9898
tth_to_q(inputs[1], inputs[0])
99+
100+
101+
params_q_to_d = [
102+
# UC1: User specified empty q values
103+
([np.array([])], np.array([])),
104+
# UC2: User specified valid q values
105+
(
106+
[np.array([np.pi / 6, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi])],
107+
np.array([0.4, 0.5, 0.66667, 1, 2, 12]),
108+
),
109+
]
110+
111+
112+
@pytest.mark.parametrize("inputs, expected", params_q_to_d)
113+
def test_q_to_d(inputs, expected):
114+
actual = q_to_d(inputs[0])
115+
assert np.allclose(actual, expected)
116+
117+
118+
params_q_to_d_bad = [
119+
# UC1: user specified an invalid q value that results in an infinite d value
120+
(
121+
[np.array([0, 1, 2, 3, 4])],
122+
[
123+
ValueError,
124+
"Input values have resulted in an infinite output. Please ensure there are no zeros in the input.",
125+
],
126+
),
127+
]
128+
129+
130+
@pytest.mark.parametrize("inputs, expected", params_q_to_d_bad)
131+
def test_q_to_d_bad(inputs, expected):
132+
with pytest.raises(expected[0], match=expected[1]):
133+
q_to_d(inputs[0])
134+
135+
136+
params_d_to_q = [
137+
# UC1: User specified empty d values
138+
([np.array([])], np.array([])),
139+
# UC2: User specified valid d values
140+
(
141+
[np.array([np.pi / 6, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi])],
142+
np.array([0.4, 0.5, 0.66667, 1, 2, 12]),
143+
),
144+
]
145+
146+
147+
@pytest.mark.parametrize("inputs, expected", params_d_to_q)
148+
def test_d_to_q(inputs, expected):
149+
actual = d_to_q(inputs[0])
150+
assert np.allclose(actual, expected)
151+
152+
153+
params_d_to_q_bad = [
154+
# UC1: user specified an invalid d value that results in an infinite q value
155+
(
156+
[np.array([0, 1, 2, 3, 4])],
157+
[
158+
ValueError,
159+
"Input values have resulted in an infinite output. Please ensure there are no zeros in the input.",
160+
],
161+
),
162+
]
163+
164+
165+
@pytest.mark.parametrize("inputs, expected", params_d_to_q_bad)
166+
def test_d_to_q_bad(inputs, expected):
167+
with pytest.raises(expected[0], match=expected[1]):
168+
d_to_q(inputs[0])

0 commit comments

Comments
 (0)