1
2
3 """Unit tests for particle shape envelope factors.
4 """
5
6
7 import unittest
8 import numpy
9
10 from diffpy.pdffit2 import PdfFit
11 from diffpy.pdffit2 import pdffit2
12 from pdffit2testutils import datafile
13
14
16 """Calculate spherical envelope correction
17
18 r -- PDF radius
19 d -- diameter of spherical particle
20
21 Return numpy array of shape correction envelope.
22 """
23 r1 = numpy.array(r)
24 fsph = 1.0 - 1.5*r1/d + 0.5*(r1/d)**3
25 fsph[r1 > d] = 0.0
26 return fsph
27
28
29
31
32 places = 6
33
35 self.P = PdfFit()
36 return
37
39 self.P = None
40 return
41
42
44 """check calculation of sphere envelope factor
45 """
46 self.P.read_struct(datafile('Ni.stru'))
47 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
48 self.P.calc()
49 d = 8.0
50 r = numpy.array(self.P.getR())
51 G0 = numpy.array(self.P.getpdf_fit())
52 self.P.setvar('spdiameter', d)
53 self.P.calc()
54 G1 = numpy.array(self.P.getpdf_fit())
55 dG = (G0*spherefactor(r, d) - G1)
56 msd = numpy.dot(dG, dG)/len(r)
57 self.assertAlmostEqual(0.0, numpy.sqrt(msd), self.places)
58 return
59
60
62 """check refinement of sphere envelope factor
63 """
64 dcheck = 8.0
65 dstart = 12.0
66 self.P.read_struct(datafile('Ni.stru'))
67 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
68 self.P.setvar('spdiameter', dcheck)
69 self.P.calc()
70 r = numpy.array(self.P.getR())
71 Gd8 = numpy.array(self.P.getpdf_fit())
72 Gd8noise = Gd8
73 Gd8noise[::2] += 0.01
74 Gd8noise[1::2] -= 0.01
75 self.P.reset()
76 self.P.read_struct(datafile('Ni.stru'))
77 self.P.read_data_lists('X', 0.0, 0.05, list(r), list(Gd8noise))
78 self.P.constrain('spdiameter', '@8')
79 self.P.setpar(8, dstart)
80 self.P.refine()
81 dfinal = self.P.getvar('spdiameter')
82 self.assertAlmostEqual(dcheck, dfinal, 3)
83 return
84
85
87 """check PDF calculation for 2 phases with different spdiameters
88 """
89 d1 = 6
90 d2 = 9
91 self.P.read_struct(datafile('Ni.stru'))
92 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
93 self.P.setvar('spdiameter', d1)
94 self.P.calc()
95 G1 = numpy.array(self.P.getpdf_fit())
96 self.P.reset()
97 self.P.read_struct(datafile('PbScW25TiO3.stru'))
98 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
99 self.P.setvar('spdiameter', d2)
100 self.P.calc()
101 G2 = numpy.array(self.P.getpdf_fit())
102 self.P.reset()
103 self.P.read_struct(datafile('Ni.stru'))
104 self.P.read_struct(datafile('PbScW25TiO3.stru'))
105 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
106 self.P.setphase(1)
107 self.P.setvar('spdiameter', d1)
108 self.P.setphase(2)
109 self.P.setvar('spdiameter', d2)
110 self.P.calc()
111 Gtot = numpy.array(self.P.getpdf_fit())
112 dG = (G1 + G2 - Gtot)
113 r = numpy.array(self.P.getR())
114 msd = numpy.dot(dG, dG)/len(r)
115 self.assertAlmostEqual(0.0, numpy.sqrt(msd), self.places)
116 return
117
118
120 """check PDF refinement of 2 phases that have different spdiameter.
121 """
122 dcheck1 = 8.0
123 dstart1 = 8.2
124 dcheck2 = 6.0
125 dstart2 = 5.5
126 self.P.read_struct(datafile('Ni.stru'))
127 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
128 self.P.setvar('spdiameter', dcheck1)
129 self.P.calc()
130 G1 = numpy.array(self.P.getpdf_fit())
131 self.P.reset()
132 self.P.read_struct(datafile('PbScW25TiO3.stru'))
133 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
134 self.P.setvar('spdiameter', dcheck2)
135 self.P.calc()
136 G2 = numpy.array(self.P.getpdf_fit())
137 r = numpy.array(self.P.getR())
138 Gnoise = G1 + G2
139 Gnoise[::2] += 0.01
140 Gnoise[1::2] -= 0.01
141 self.P.reset()
142 self.P.read_struct(datafile('Ni.stru'))
143 self.P.read_struct(datafile('PbScW25TiO3.stru'))
144 self.P.read_data_lists('X', 0.0, 0.05, list(r), list(Gnoise))
145 self.P.setphase(1)
146 self.P.constrain('spdiameter', '@11')
147 self.P.setphase(2)
148 self.P.constrain('spdiameter', '@12')
149 self.P.setpar(11, dstart1)
150 self.P.setpar(12, dstart2)
151 self.P.refine()
152 dfinal2 = self.P.getvar('spdiameter')
153 self.P.setphase(1)
154 dfinal1 = self.P.getvar('spdiameter')
155 self.assertAlmostEqual(dcheck1, dfinal1, 3)
156 self.assertAlmostEqual(dcheck2, dfinal2, 3)
157 return
158
159
161 """Check reading and writing of spdiameter from structure file.
162 """
163 import re
164 self.P.read_struct(datafile('Ni.stru'))
165 self.assertEqual(0.0, self.P.getvar('spdiameter'))
166
167 spdnone = self.P.save_struct_string(1)
168 self.failUnless(not re.search('(?m)^shape +sphere,', spdnone))
169 self.P.setvar('spdiameter', 7)
170 spd7 = self.P.save_struct_string(1)
171
172 self.failUnless(re.search('(?m)^shape +sphere,', spd7))
173 self.P.reset()
174 self.P.read_struct_string(spd7)
175 self.assertEqual(7.0, self.P.getvar('spdiameter'))
176
177 spd14 = re.sub('(?m)^shape +sphere.*$', 'shape sphere 14.00', spd7)
178 self.P.read_struct_string(spd14)
179 self.assertEqual(14.0, self.P.getvar('spdiameter'))
180
181 sinvalid = re.sub('(?m)^shape .*', 'shape invalid, 1', spd7)
182 self.assertRaises(pdffit2.structureError,
183 self.P.read_struct_string, sinvalid)
184 return
185
186
187
188
189
190
192
193 places = 6
194
196 self.P = PdfFit()
197 return
198
200 self.P = None
201 return
202
203
205 """check calculation of sphere envelope factor
206 """
207 self.P.read_struct(datafile('Ni.stru'))
208 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
209 self.P.calc()
210 stepcut = 8.0
211 r = numpy.array(self.P.getR())
212 G0 = numpy.array(self.P.getpdf_fit())
213 G0[r > stepcut] = 0.0
214 self.P.setvar('stepcut', stepcut)
215 self.P.calc()
216 G1 = numpy.array(self.P.getpdf_fit())
217 dG = (G0 - G1)
218 msd = numpy.dot(dG, dG)/len(r)
219 self.assertAlmostEqual(0.0, numpy.sqrt(msd), self.places)
220 return
221
222
224 """check PDF calculation for 2 phases with different spdiameters
225 """
226 d1 = 6
227 d2 = 9
228 self.P.read_struct(datafile('Ni.stru'))
229 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
230 self.P.setvar('stepcut', d1)
231 self.P.calc()
232 G1 = numpy.array(self.P.getpdf_fit())
233 self.P.reset()
234 self.P.read_struct(datafile('PbScW25TiO3.stru'))
235 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
236 self.P.setvar('stepcut', d2)
237 self.P.calc()
238 G2 = numpy.array(self.P.getpdf_fit())
239 self.P.reset()
240 self.P.read_struct(datafile('Ni.stru'))
241 self.P.read_struct(datafile('PbScW25TiO3.stru'))
242 self.P.alloc('X', 0.0, 0.05, 0.1, 10, 200)
243 self.P.setphase(1)
244 self.P.setvar('stepcut', d1)
245 self.P.setphase(2)
246 self.P.setvar('stepcut', d2)
247 self.P.calc()
248 Gtot = numpy.array(self.P.getpdf_fit())
249 dG = (G1 + G2 - Gtot)
250 r = numpy.array(self.P.getR())
251 msd = numpy.dot(dG, dG)/len(r)
252 self.assertAlmostEqual(0.0, numpy.sqrt(msd), self.places)
253
254 self.failUnless(numpy.all(0 == Gtot[r > max(d1, d2)]))
255 return
256
257
259 """Check reading and writing of stepcut from structure file.
260 """
261 import re
262 self.P.read_struct(datafile('Ni.stru'))
263 self.assertEqual(0.0, self.P.getvar('stepcut'))
264
265 sscnone = self.P.save_struct_string(1)
266 self.failUnless(not re.search('(?m)^shape +stepcut,', sscnone))
267 self.P.setvar('stepcut', 7)
268 ssc7 = self.P.save_struct_string(1)
269
270 self.failUnless(re.search('(?m)^shape +stepcut,', ssc7))
271 self.P.reset()
272 self.P.read_struct_string(ssc7)
273 self.assertEqual(7.0, self.P.getvar('stepcut'))
274
275 ssc14 = re.sub('(?m)^shape +stepcut.*$', 'shape stepcut 14.00', ssc7)
276 self.P.read_struct_string(ssc14)
277 self.assertEqual(14.0, self.P.getvar('stepcut'))
278
279 sinvalid = re.sub('(?m)^shape .*', 'shape invalid, 1', ssc7)
280 self.assertRaises(pdffit2.structureError,
281 self.P.read_struct_string, sinvalid)
282 return
283
284
285
286
287 if __name__ == '__main__':
288 unittest.main()
289
290
291