source: sasview/sansmodels/test/utest_dispersity.py @ 38f5b20

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 38f5b20 was 019a943, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Re #5 improving tests

  • Property mode set to 100644
File size: 20.1 KB
Line 
1"""
2    Unit tests for dispersion functionality of
3    C++ model classes
4"""
5
6#Note: The 'sans.models.DisperseModel' is for only the test. We use
7#'sans.models.dispersion_models', instead in the application.
8#The first uses width = sigma, while the second uses width = ratio (=sigma/mean)
9#for length parameters and width = sigma for angle parameters.
10#In Feb. 2011, we found and fixed the some precision problems in the C, so that
11#this test was updated too.
12
13
14import unittest, math, numpy
15
16class TestCylinder(unittest.TestCase):
17    """
18        Testing C++ Cylinder model
19    """
20    def setUp(self):
21        from sans.models.CylinderModel import CylinderModel
22        self.model= CylinderModel()
23       
24        self.model.setParam('scale', 1.0)
25        self.model.setParam('radius', 20.0)
26        self.model.setParam('length', 400.0)
27        self.model.setParam('sldCyl', 4.e-6)
28        self.model.setParam('sldSolv', 1.e-6)
29        self.model.setParam('background', 0.0)
30        self.model.setParam('cyl_theta', 0.0)
31        self.model.setParam('cyl_phi', 0.0)
32       
33    def test_simple(self):
34        self.assertAlmostEqual(self.model.run(0.001), 450.355, 3)
35        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 452.299, 3)
36       
37    def test_constant(self):
38        from sans.models.dispersion_models import DispersionModel
39        disp = DispersionModel()
40        self.model.setParam('scale', 10.0)
41        self.model.set_dispersion('radius', disp)
42        self.model.dispersion['radius']['width'] = 0.25
43        self.model.dispersion['radius']['npts'] = 100
44        self.model.dispersion['radius']['nsigmas'] = 2.5
45       
46        self.assertAlmostEqual(self.model.run(0.001), 1.021051*4527.47250339, 3)
47        self.assertAlmostEqual(self.model.runXY([0.001, 0.001]), 
48                               1.021048*4546.997777604715, 2)
49       
50    def test_gaussian(self):
51        from sans.models.dispersion_models import GaussianDispersion
52        disp = GaussianDispersion()
53        self.model.set_dispersion('radius', disp)
54        self.model.dispersion['radius']['width'] = 0.25
55        self.model.dispersion['radius']['npts'] = 100
56        self.model.dispersion['radius']['nsigmas'] = 2
57        self.model.setParam('scale', 10.0)
58       
59        self.assertAlmostEqual(self.model.run(0.001), 
60                               1.1804794*4723.32213339, 3)
61        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
62                               1.180454*4743.56, 2)
63       
64    def test_clone(self):
65        from sans.models.dispersion_models import GaussianDispersion
66        disp = GaussianDispersion()
67        self.model.set_dispersion('radius', disp)
68        self.model.dispersion['radius']['width'] = 0.25
69        self.model.dispersion['radius']['npts'] = 100
70        self.model.dispersion['radius']['nsigmas'] = 2
71        self.model.setParam('scale', 10.0)
72       
73        new_model = self.model.clone()
74        self.assertAlmostEqual(new_model.run(0.001), 
75                               1.1804794*4723.32213339, 3)
76        self.assertAlmostEqual(new_model.runXY([0.001,0.001]), 
77                               1.180454*4743.56, 2)
78       
79    def test_gaussian_zero(self):
80        from sans.models.dispersion_models import GaussianDispersion
81        disp = GaussianDispersion()
82        self.model.set_dispersion('radius', disp)
83        self.model.dispersion['radius']['width'] = 0.0
84        self.model.dispersion['radius']['npts'] = 100
85        self.model.dispersion['radius']['nsigmas'] = 2.5
86        self.model.setParam('scale', 1.0)
87       
88        self.assertAlmostEqual(self.model.run(0.001), 450.355, 3)
89        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 452.299, 3)
90       
91    def test_array(self):
92        """
93            Perform complete rotational average and
94            compare to 1D
95        """
96        from sans.models.dispersion_models import ArrayDispersion
97        disp_ph = ArrayDispersion()
98        disp_th = ArrayDispersion()
99       
100        values_ph = numpy.zeros(100)
101        values_th = numpy.zeros(100)
102        weights   = numpy.zeros(100)
103        for i in range(100):
104            values_ph[i]=(360/99.0*i)
105            values_th[i]=(180/99.0*i)
106            weights[i]=(1.0)
107       
108        disp_ph.set_weights(values_ph, weights)
109        disp_th.set_weights(values_th, weights)
110       
111        self.model.set_dispersion('cyl_theta', disp_th)
112        self.model.set_dispersion('cyl_phi', disp_ph)
113       
114        val_1d = self.model.run(math.sqrt(0.0002))
115        val_2d = self.model.runXY([0.01,0.01]) 
116       
117        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
118       
119class TestCoreShellCylinder(unittest.TestCase):
120    """
121        Testing C++ Cylinder model
122    """
123    def setUp(self):
124        from sans.models.CoreShellCylinderModel import CoreShellCylinderModel
125        self.model= CoreShellCylinderModel()
126       
127        self.model.setParam('scale', 1.0)
128        self.model.setParam('radius', 20.0)
129        self.model.setParam('thickness', 10.0)
130        self.model.setParam('length', 400.0)
131        self.model.setParam('core_sld', 1.e-6)
132        self.model.setParam('shell_sld', 4.e-6)
133        self.model.setParam('solvent_sld', 1.e-6)
134        self.model.setParam('background', 0.0)
135        self.model.setParam('axis_theta', 0.0)
136        self.model.setParam('axis_phi', 0.0)
137       
138    def test_simple(self):
139        """
140            Test simple 1D and 2D values
141            Numbers taken from model that passed validation, before
142            the update to C++ underlying class.
143        """
144        self.assertAlmostEqual(self.model.run(0.001), 353.55013216754583, 3)
145        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
146                               355.25355270620543, 3)
147       
148    def test_dispersion(self):
149        """
150            Test with dispersion
151        """
152        from sans.models.DisperseModel import DisperseModel
153        disp = DisperseModel(self.model, ['radius', 
154                                          'thickness', 
155                                          'length'], [5, 2, 50])
156        disp.setParam('n_pts', 10)
157        self.assertAlmostEqual(disp.run(0.001), 358.44062724936009, 3)
158        self.assertAlmostEqual(disp.runXY([0.001,0.001]), 360.22673635224584, 3)
159
160    def test_new_disp(self):
161        from sans.models.dispersion_models import GaussianDispersion
162        disp_rm = GaussianDispersion()
163        self.model.set_dispersion('radius', disp_rm)
164        self.model.dispersion['radius']['width'] = 0.25
165        self.model.dispersion['radius']['npts'] = 10
166        self.model.dispersion['radius']['nsigmas'] = 2
167
168        disp_rr = GaussianDispersion()
169        self.model.set_dispersion('thickness', disp_rr)
170        self.model.dispersion['thickness']['width'] = 0.2
171        self.model.dispersion['thickness']['npts'] = 10
172        self.model.dispersion['thickness']['nsigmas'] = 2
173
174        disp_len = GaussianDispersion()
175        self.model.set_dispersion('length', disp_len)
176        self.model.dispersion['length']['width'] = 1.0/8.0
177        self.model.dispersion['length']['npts'] = 10
178        self.model.dispersion['length']['nsigmas'] = 2
179
180        self.assertAlmostEqual(self.model.run(0.001), 
181                               1.07832610*358.44062724936009, 3)
182        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
183                               1.07844010*360.22673635224584, 3)
184       
185
186    def test_array(self):
187        """
188            Perform complete rotational average and
189            compare to 1D
190        """
191        from sans.models.dispersion_models import ArrayDispersion
192        disp_ph = ArrayDispersion()
193        disp_th = ArrayDispersion()
194       
195        values_ph = numpy.zeros(100)
196        values_th = numpy.zeros(100)
197        weights   = numpy.zeros(100)
198        for i in range(100):
199            values_ph[i]=(360/99.0*i)
200            values_th[i]=(180/99.0*i)
201            weights[i]=(1.0)
202       
203        disp_ph.set_weights(values_ph, weights)
204        disp_th.set_weights(values_th, weights)
205       
206        self.model.set_dispersion('axis_theta', disp_th)
207        self.model.set_dispersion('axis_phi', disp_ph)
208       
209        val_1d = self.model.run(math.sqrt(0.0002))
210        val_2d = self.model.runXY([0.01,0.01]) 
211       
212        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
213       
214       
215       
216class TestCoreShell(unittest.TestCase):
217    """
218        Testing C++ Cylinder model
219    """
220    def setUp(self):
221        from sans.models.CoreShellModel import CoreShellModel
222        self.model= CoreShellModel()
223       
224        self.model.setParam('scale', 1.0)
225        self.model.setParam('radius', 60.0)
226        self.model.setParam('thickness', 10.0)
227        self.model.setParam('core_sld', 1.e-6)
228        self.model.setParam('shell_sld', 2.e-6)
229        self.model.setParam('solvent_sld', 3.e-6)
230        self.model.setParam('background', 0.0)
231       
232    def test_simple(self):
233        """
234            Test simple 1D and 2D values
235            Numbers taken from model that passed validation, before
236            the update to C++ underlying class.
237        """
238        self.assertAlmostEqual(self.model.run(0.001), 
239                               381.27304697150055, 3)
240        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
241                               380.93779156218682, 3)
242       
243    def test_dispersion(self):
244        """
245            Test with dispersion
246        """
247        from sans.models.DisperseModel import DisperseModel
248        disp = DisperseModel(self.model, ['radius', 'thickness'], [10, 2])
249        disp.setParam('n_pts', 10)
250        self.assertAlmostEqual(disp.run(0.001), 407.344127907553, 3)
251   
252    def test_new_disp(self):
253        from sans.models.dispersion_models import GaussianDispersion
254        disp_rm = GaussianDispersion()
255        self.model.set_dispersion('radius', disp_rm)
256        self.model.dispersion['radius']['width'] = 0.1666666667
257        self.model.dispersion['radius']['npts'] = 10
258        self.model.dispersion['radius']['nsigmas'] = 2
259
260        disp_rr = GaussianDispersion()
261        self.model.set_dispersion('thickness', disp_rr)
262        self.model.dispersion['thickness']['width'] = 0.2
263        self.model.dispersion['thickness']['npts'] = 10
264        self.model.dispersion['thickness']['nsigmas'] = 2
265
266        self.assertAlmostEqual(self.model.run(0.001), 
267                               1.16747510*407.344127907553, 3)
268
269       
270class TestEllipsoid(unittest.TestCase):
271    """
272        Testing C++ Cylinder model
273    """
274    def setUp(self):
275        from sans.models.EllipsoidModel import EllipsoidModel
276        self.model= EllipsoidModel()
277       
278        self.model.setParam('scale', 1.0)
279        self.model.setParam('radius_a', 20.0)
280        self.model.setParam('radius_b', 400.0)
281        self.model.setParam('sldEll', 4.e-6)
282        self.model.setParam('sldSolv', 1.e-6)
283        self.model.setParam('background', 0.0)
284        self.model.setParam('axis_theta', 89.95445)
285        self.model.setParam('axis_phi', 0.0)
286       
287    def test_simple(self):
288        """
289            Test simple 1D and 2D values
290            Numbers taken from model that passed validation, before
291            the update to C++ underlying class.
292        """
293        self.assertAlmostEqual(self.model.run(0.001), 
294                               11808.842896863147, 3)
295        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
296                               11681.990374929677, 3)
297
298    def test_dispersion(self):
299        """
300            Test with dispersion
301        """
302        from sans.models.DisperseModel import DisperseModel
303        disp = DisperseModel(self.model, ['radius_a', 'radius_b'], [5, 50])
304        disp.setParam('n_pts', 10)
305
306        self.assertAlmostEqual(disp.run(0.001), 11948.72581312305, 3)
307        self.assertAlmostEqual(disp.runXY([0.001,0.001]), 11811.972359807551, 3)
308       
309    def test_new_disp(self):
310        from sans.models.dispersion_models import GaussianDispersion
311        disp_rm = GaussianDispersion()
312        self.model.set_dispersion('radius_a', disp_rm)
313        self.model.dispersion['radius_a']['width'] = 0.25
314        self.model.dispersion['radius_a']['npts'] = 10
315        self.model.dispersion['radius_a']['nsigmas'] = 2
316
317        disp_rr = GaussianDispersion()
318        self.model.set_dispersion('radius_b', disp_rr)
319        self.model.dispersion['radius_b']['width'] = 0.125
320        self.model.dispersion['radius_b']['npts'] = 10
321        self.model.dispersion['radius_b']['nsigmas'] = 2
322
323        self.assertAlmostEqual(self.model.run(0.001), 
324                               1.10650710*11948.72581312305, 3)
325        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
326                               1.105898*11811.972359807551, 2)
327
328    def test_array(self):
329        """
330            Perform complete rotational average and
331            compare to 1D
332        """
333        from sans.models.dispersion_models import ArrayDispersion
334        disp_ph = ArrayDispersion()
335        disp_th = ArrayDispersion()
336       
337        values_ph = numpy.zeros(100)
338        values_th = numpy.zeros(100)
339        weights   = numpy.zeros(100)
340        for i in range(100):
341            values_ph[i]=(360/99.0*i)
342            values_th[i]=(180/99.0*i)
343            weights[i]=(1.0)
344       
345        disp_ph.set_weights(values_ph, weights)
346        disp_th.set_weights(values_th, weights)
347       
348        self.model.set_dispersion('axis_theta', disp_th)
349        self.model.set_dispersion('axis_phi', disp_ph)
350       
351        val_1d = self.model.run(math.sqrt(0.0002))
352        val_2d = self.model.runXY([0.01,0.01]) 
353       
354        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
355       
356       
357       
358class TestSphere(unittest.TestCase):
359    """
360        Testing C++ Cylinder model
361    """
362    def setUp(self):
363        from sans.models.SphereModel import SphereModel
364        self.model= SphereModel()
365       
366        self.model.setParam('scale', 1.0)
367        self.model.setParam('radius', 60.0)
368        self.model.setParam('sldSph', 2.0)
369        self.model.setParam('sldSolv', 1.0)
370        self.model.setParam('background', 0.0)
371       
372    def test_simple(self):
373        """
374            Test simple 1D and 2D values
375            Numbers taken from model that passed validation, before
376            the update to C++ underlying class.
377        """
378        self.assertTrue(math.fabs(self.model.run(0.001)-90412744456148.094)<=50.0)
379        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
380                               90347660670656.391, 1)
381
382    def test_dispersion(self):
383        """
384            Test with dispersion
385        """
386        from sans.models.DisperseModel import DisperseModel
387        disp = DisperseModel(self.model, ['radius'], [10])
388        disp.setParam('n_pts', 10)
389        disp.setParam('radius.npts', 10)
390        disp.setParam('radius.nsigmas', 2.5)
391        self.assertTrue(math.fabs(disp.run(0.001)-96795008379475.219<50.0))
392       
393    def test_new_disp(self):
394        from sans.models.dispersion_models import GaussianDispersion
395        disp_rm = GaussianDispersion()
396        self.model.set_dispersion('radius', disp_rm)
397        self.model.dispersion['radius']['width'] = 0.1666666667
398        self.model.dispersion['radius']['npts'] = 10
399        self.model.dispersion['radius']['nsigmas'] = 2
400
401        #self.assertAlmostEqual(self.model.run(0.001), 96795008379475.25,3)
402       
403       
404       
405class TestEllipticalCylinder(unittest.TestCase):
406    """
407        Testing C++ Cylinder model
408    """
409    def setUp(self):
410        from sans.models.EllipticalCylinderModel import EllipticalCylinderModel
411        self.model= EllipticalCylinderModel()
412       
413        self.model.setParam('scale', 1.0)
414        self.model.setParam('r_minor', 20.0)
415        self.model.setParam('r_ratio', 1.5)
416        self.model.setParam('length', 400.0)
417        self.model.setParam('sldCyl', 4.0e-6)
418        self.model.setParam('sldSolv', 1.0e-6)
419        self.model.setParam('background', 0.0)
420        self.model.setParam('cyl_theta', 90)
421        self.model.setParam('cyl_phi', 0.0)
422        self.model.setParam('cyl_psi', 0.0)
423       
424    def test_simple(self):
425        """
426            Test simple 1D and 2D values
427            Numbers taken from model that passed validation, before
428            the update to C++ underlying class.
429        """
430        self.assertAlmostEqual(self.model.run(0.001), 
431                               675.50440232504991, 3)
432        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
433                               669.5173937622792, 0)
434       
435    def test_dispersion(self):
436        """
437            Test with dispersion
438        """
439        from sans.models.DisperseModel import DisperseModel
440        disp = DisperseModel(self.model, ['r_minor', 'r_ratio', 'length'], 
441                             [5, 0.25, 50])
442        disp.setParam('n_pts', 10)
443        self.assertAlmostEqual(disp.run(0.001), 711.18048194151925, 3)
444        self.assertAlmostEqual(disp.runXY([0.001,0.001]), 704.63525988095705, 0)
445
446    def test_new_disp(self):
447        from sans.models.dispersion_models import GaussianDispersion
448        disp_rm = GaussianDispersion()
449        self.model.set_dispersion('r_minor', disp_rm)
450        self.model.dispersion['r_minor']['width'] = 0.25
451        self.model.dispersion['r_minor']['npts'] = 10
452        self.model.dispersion['r_minor']['nsigmas'] = 2
453
454        disp_rr = GaussianDispersion()
455        self.model.set_dispersion('r_ratio', disp_rr)
456        self.model.dispersion['r_ratio']['width'] = 0.25/1.5
457        self.model.dispersion['r_ratio']['npts'] = 10
458        self.model.dispersion['r_ratio']['nsigmas'] = 2
459
460        disp_len = GaussianDispersion()
461        self.model.set_dispersion('length', disp_len)
462        self.model.dispersion['length']['width'] = 50.0/400
463        self.model.dispersion['length']['npts'] = 10
464        self.model.dispersion['length']['nsigmas'] = 2
465
466        self.assertAlmostEqual(self.model.run(0.001), 
467                               1.23925910*711.18048194151925, 3)
468        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
469                               1.238955*704.63525988095705, 0)
470       
471
472    def test_array(self):
473        """
474            Perform complete rotational average and
475            compare to 1D
476        """
477        from sans.models.dispersion_models import ArrayDispersion
478        disp_ph = ArrayDispersion()
479        disp_th = ArrayDispersion()
480        disp_ps = ArrayDispersion()
481       
482        values_ph = numpy.zeros(100)
483        values_th = numpy.zeros(100)
484        values_ps = numpy.zeros(100)
485        weights   = numpy.zeros(100)
486        for i in range(100):
487            values_ps[i]=(360/99.0*i)
488            values_ph[i]=(360/99.0*i)
489            values_th[i]=(180/99.0*i)
490            weights[i]=(1.0)
491       
492        disp_ph.set_weights(values_ph, weights)
493        disp_th.set_weights(values_th, weights)
494        disp_ps.set_weights(values_ps, weights)
495       
496        self.model.set_dispersion('cyl_theta', disp_th)
497        self.model.set_dispersion('cyl_phi', disp_ph)
498        self.model.set_dispersion('cyl_psi', disp_ps)
499       
500        val_1d = self.model.run(math.sqrt(0.0002))
501        val_2d = self.model.runXY([0.01,0.01]) 
502       
503        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
504       
505class TestDispModel(unittest.TestCase):
506    def setUp(self):
507        from sans.models.CylinderModel import CylinderModel
508        self.model = CylinderModel()
509       
510       
511    def test_disp_params(self):
512       
513        self.assertEqual(self.model.dispersion['radius']['width'], 0.0)
514        self.model.setParam('radius.width', 0.25)
515        self.assertEqual(self.model.dispersion['radius']['width'], 0.25)
516        self.assertEqual(self.model.getParam('radius.width'), 0.25)
517        self.assertEqual(self.model.dispersion['radius']['type'], 'gaussian')
518       
519 
520if __name__ == '__main__':
521    unittest.main()
522   
Note: See TracBrowser for help on using the repository browser.