Skip to content

Commit 70e8403

Browse files
committed
update parser testing
1 parent b742d4d commit 70e8403

5 files changed

Lines changed: 394 additions & 193 deletions

File tree

src/diffpy/cmipdf/basepdfgenerator.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class BasePDFGenerator(ProfileGenerator):
7272
7373
Usable Metadata
7474
---------------
75-
scattering_type : str
75+
stype : str
7676
The scattering type "X" for x-ray, "N" for neutron (see
7777
'set_scattering_type').
7878
qmax
@@ -159,9 +159,9 @@ def _process_metadata(self):
159159
"""Process the metadata once it gets set."""
160160
ProfileGenerator._process_metadata(self)
161161

162-
scattering_type = self.meta.get("scattering_type")
163-
if scattering_type is not None:
164-
self.set_scattering_type(scattering_type)
162+
stype = self.meta.get("stype")
163+
if stype is not None:
164+
self.set_scattering_type(stype)
165165

166166
qmax = self.meta.get("qmax")
167167
if qmax is not None:
@@ -179,12 +179,12 @@ def _process_metadata(self):
179179

180180
return
181181

182-
def set_scattering_type(self, scattering_type="X"):
182+
def set_scattering_type(self, stype="X"):
183183
"""Set the scattering type.
184184
185185
Parameters
186186
----------
187-
scattering_type : str, optional
187+
stype : str, optional
188188
The scattering type. Default is `"X"`.
189189
`"X"` for x-ray, `"N"` for neutron, `"E"` for electrons,
190190
or any registered type from diffpy.srreal from
@@ -195,9 +195,9 @@ def set_scattering_type(self, scattering_type="X"):
195195
ValueError
196196
If the scattering type is unknown.
197197
"""
198-
self._calc.setScatteringFactorTableByType(scattering_type)
198+
self._calc.setScatteringFactorTableByType(stype)
199199
# update the meta dictionary only if there was no exception
200-
self.meta["scattering_type"] = self.get_scattering_type()
200+
self.meta["stype"] = self.get_scattering_type()
201201
return
202202

203203
def get_scattering_type(self):

tests/new_test_pdf.py

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
#!/usr/bin/env python
2+
##############################################################################
3+
#
4+
# diffpy.srfit by DANSE Diffraction group
5+
# Simon J. L. Billinge
6+
# (c) 2010 The Trustees of Columbia University
7+
# in the City of New York. All rights reserved.
8+
#
9+
# File coded by: Pavol Juhas
10+
#
11+
# See AUTHORS.txt for a list of people who contributed.
12+
# See LICENSE_DANSE.txt for license information.
13+
#
14+
##############################################################################
15+
"""Tests for pdf package."""
16+
17+
import io
18+
import pickle
19+
import unittest
20+
from itertools import chain
21+
22+
import numpy
23+
import pytest
24+
25+
from diffpy.srfit.exceptions import SrFitError
26+
from diffpy.srfit.fitbase import ProfileParser
27+
from diffpy.srfit.pdf import PDFContribution, PDFGenerator, PDFParser
28+
29+
# ----------------------------------------------------------------------------
30+
31+
32+
def testParser1(datafile):
33+
data = datafile("ni-q27r100-neutron.gr")
34+
parser = PDFParser()
35+
parser.parseFile(data)
36+
37+
meta = parser._meta
38+
39+
assert data == meta["filename"]
40+
assert 1 == meta["nbanks"]
41+
assert "N" == meta["stype"]
42+
assert 27 == meta["qmax"]
43+
assert 300 == meta.get("temperature")
44+
assert meta.get("qdamp") is None
45+
assert meta.get("qbroad") is None
46+
assert meta.get("spdiameter") is None
47+
assert meta.get("scale") is None
48+
assert meta.get("doping") is None
49+
50+
x, y, dx, dy = parser.get_data()
51+
assert dx is None
52+
assert dy is None
53+
54+
testx = numpy.linspace(0.01, 100, 10000)
55+
diff = testx - x
56+
res = numpy.dot(diff, diff)
57+
assert 0 == pytest.approx(res)
58+
59+
testy = numpy.array(
60+
[
61+
1.144,
62+
2.258,
63+
3.312,
64+
4.279,
65+
5.135,
66+
5.862,
67+
6.445,
68+
6.875,
69+
7.150,
70+
7.272,
71+
]
72+
)
73+
diff = testy - y[:10]
74+
res = numpy.dot(diff, diff)
75+
assert 0 == pytest.approx(res)
76+
77+
return
78+
79+
80+
def testParser2(datafile):
81+
data = datafile("si-q27r60-xray.gr")
82+
parser = ProfileParser()
83+
parser.parse_file(data)
84+
85+
meta = parser._meta
86+
87+
assert str(data) == meta["filename"]
88+
assert 1 == meta["nbanks"]
89+
assert "X" == meta["stype"]
90+
assert 27 == meta["qmax"]
91+
assert 300 == meta.get("temperature")
92+
assert meta.get("qdamp") is None
93+
assert meta.get("qbroad") is None
94+
assert meta.get("spdiameter") is None
95+
assert meta.get("scale") is None
96+
assert meta.get("doping") is None
97+
98+
x, y, dx, dy = parser.get_data()
99+
testx = numpy.linspace(0.01, 60, 5999, endpoint=False)
100+
diff = testx - x
101+
res = numpy.dot(diff, diff)
102+
assert 0 == pytest.approx(res)
103+
104+
testy = numpy.array(
105+
[
106+
0.1105784,
107+
0.2199684,
108+
0.3270088,
109+
0.4305913,
110+
0.5296853,
111+
0.6233606,
112+
0.7108060,
113+
0.7913456,
114+
0.8644501,
115+
0.9297440,
116+
]
117+
)
118+
diff = testy - y[:10]
119+
res = numpy.dot(diff, diff)
120+
assert 0 == pytest.approx(res)
121+
122+
testdy = numpy.array(
123+
[
124+
0.001802192,
125+
0.003521449,
126+
0.005079115,
127+
0.006404892,
128+
0.007440527,
129+
0.008142955,
130+
0.008486813,
131+
0.008466340,
132+
0.008096858,
133+
0.007416456,
134+
]
135+
)
136+
diff = testdy - dy[:10]
137+
res = numpy.dot(diff, diff)
138+
assert 0 == pytest.approx(res)
139+
140+
assert dx.tolist() == [0] * len(dx)
141+
return
142+
143+
144+
def testGenerator(
145+
diffpy_srreal_available, diffpy_structure_available, datafile
146+
):
147+
if not diffpy_structure_available:
148+
pytest.skip("diffpy.structure package not available")
149+
if not diffpy_srreal_available:
150+
pytest.skip("diffpy.srreal package not available")
151+
152+
from diffpy.srreal.pdfcalculator import PDFCalculator
153+
from diffpy.structure import PDFFitStructure
154+
155+
qmax = 27.0
156+
gen = PDFGenerator()
157+
gen.setScatteringType("N")
158+
assert "N" == gen.getScatteringType()
159+
gen.setQmax(qmax)
160+
assert qmax == pytest.approx(gen.getQmax())
161+
162+
stru = PDFFitStructure()
163+
ciffile = datafile("ni.cif")
164+
cif_path = str(ciffile)
165+
stru.read(cif_path)
166+
for i in range(4):
167+
stru[i].Bisoequiv = 1
168+
gen.setStructure(stru)
169+
170+
calc = gen._calc
171+
# Test parameters
172+
for par in gen.iterPars(recurse=False):
173+
pname = par.name
174+
defval = calc._getDoubleAttr(pname)
175+
assert defval == par.getValue()
176+
# Test setting values
177+
par.set_value(1.0)
178+
assert 1.0 == par.getValue()
179+
par.set_value(defval)
180+
assert defval == par.getValue()
181+
182+
r = numpy.arange(0, 10, 0.1)
183+
y = gen(r)
184+
185+
# Now create a reference PDF. Since the calculator is testing its
186+
# output, we just have to make sure we can calculate from the
187+
# PDFGenerator interface.
188+
189+
calc = PDFCalculator()
190+
calc.rstep = r[1] - r[0]
191+
calc.rmin = r[0]
192+
calc.rmax = r[-1] + 0.5 * calc.rstep
193+
calc.qmax = qmax
194+
calc.setScatteringFactorTableByType("N")
195+
calc.eval(stru)
196+
yref = calc.pdf
197+
198+
diff = y - yref
199+
res = numpy.dot(diff, diff)
200+
assert 0 == pytest.approx(res)
201+
return
202+
203+
204+
def test_setQmin(diffpy_structure_available, diffpy_srreal_available):
205+
"""Verify qmin is propagated to the calculator object."""
206+
if not diffpy_srreal_available:
207+
pytest.skip("diffpy.srreal package not available")
208+
209+
gen = PDFGenerator()
210+
assert 0 == gen.getQmin()
211+
assert 0 == gen._calc.qmin
212+
gen.setQmin(0.93)
213+
assert 0.93 == gen.getQmin()
214+
assert 0.93 == gen._calc.qmin
215+
return
216+
217+
218+
def test_setQmax(diffpy_structure_available, diffpy_srreal_available):
219+
"""Check PDFContribution.setQmax()"""
220+
if not diffpy_structure_available:
221+
pytest.skip("diffpy.structure package not available")
222+
from diffpy.structure import Structure
223+
224+
if not diffpy_srreal_available:
225+
pytest.skip("diffpy.srreal package not available")
226+
227+
pc = PDFContribution("pdf")
228+
pc.setQmax(21)
229+
pc.addStructure("empty", Structure())
230+
assert 21 == pc.empty.getQmax()
231+
pc.setQmax(22)
232+
assert 22 == pc.getQmax()
233+
assert 22 == pc.empty.getQmax()
234+
return
235+
236+
237+
def test_getQmax(diffpy_structure_available, diffpy_srreal_available):
238+
"""Check PDFContribution.getQmax()"""
239+
if not diffpy_structure_available:
240+
pytest.skip("diffpy.structure package not available")
241+
from diffpy.structure import Structure
242+
243+
if not diffpy_srreal_available:
244+
pytest.skip("diffpy.srreal package not available")
245+
246+
# cover all code branches in PDFContribution._get_meta_value
247+
# (1) contribution metadata
248+
pc1 = PDFContribution("pdf")
249+
assert pc1.getQmax() is None
250+
pc1.setQmax(17)
251+
assert 17 == pc1.getQmax()
252+
# (2) contribution metadata
253+
pc2 = PDFContribution("pdf")
254+
pc2.addStructure("empty", Structure())
255+
pc2.empty.setQmax(18)
256+
assert 18 == pc2.getQmax()
257+
# (3) profile metadata
258+
pc3 = PDFContribution("pdf")
259+
pc3.profile.meta["qmax"] = 19
260+
assert 19 == pc3.getQmax()
261+
return
262+
263+
264+
def test_savetxt(
265+
diffpy_structure_available, diffpy_srreal_available, datafile
266+
):
267+
"check PDFContribution.savetxt()"
268+
if not diffpy_structure_available:
269+
pytest.skip("diffpy.structure package not available")
270+
from diffpy.structure import Structure
271+
272+
if not diffpy_srreal_available:
273+
pytest.skip("diffpy.srreal package not available")
274+
275+
pc = PDFContribution("pdf")
276+
pc.loadData(datafile("si-q27r60-xray.gr"))
277+
pc.setCalculationRange(0, 10)
278+
pc.addStructure("empty", Structure())
279+
fp = io.BytesIO()
280+
with pytest.raises(SrFitError):
281+
pc.savetxt(fp)
282+
pc.evaluate()
283+
pc.savetxt(fp)
284+
txt = fp.getvalue().decode()
285+
nlines = len(txt.strip().split("\n"))
286+
assert 1001 == nlines
287+
return
288+
289+
290+
def test_pickling(
291+
diffpy_structure_available, diffpy_srreal_available, datafile
292+
):
293+
"validate PDFContribution.residual() after pickling."
294+
if not diffpy_structure_available:
295+
pytest.skip("diffpy.structure package not available")
296+
from diffpy.structure import loadStructure
297+
298+
if not diffpy_srreal_available:
299+
pytest.skip("diffpy.srreal package not available")
300+
301+
pc = PDFContribution("pdf")
302+
pc.loadData(datafile("ni-q27r100-neutron.gr"))
303+
ciffile = datafile("ni.cif")
304+
cif_path = str(ciffile)
305+
ni = loadStructure(cif_path)
306+
ni.Uisoequiv = 0.003
307+
pc.addStructure("ni", ni)
308+
pc.setCalculationRange(0, 10)
309+
pc2 = pickle.loads(pickle.dumps(pc))
310+
res0 = pc.residual()
311+
assert numpy.array_equal(res0, pc2.residual())
312+
for p in chain(
313+
pc.iterate_over_parameters("Uiso"), pc2.iterate_over_parameters("Uiso")
314+
):
315+
p.value = 0.004
316+
res1 = pc.residual()
317+
assert not numpy.allclose(res0, res1)
318+
assert numpy.array_equal(res1, pc2.residual())
319+
return
320+
321+
322+
if __name__ == "__main__":
323+
unittest.main()

0 commit comments

Comments
 (0)