source: sasview/sansmodels/test/utest_dispersity.py @ ebbc421

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 ebbc421 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
RevLine 
[0f5bc9f]1"""
2    Unit tests for dispersion functionality of
3    C++ model classes
4"""
5
[59b9b675]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
[0f5bc9f]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)
[18b89c4]27        self.model.setParam('sldCyl', 4.e-6)
28        self.model.setParam('sldSolv', 1.e-6)
[0f5bc9f]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)
[59b9b675]42        self.model.dispersion['radius']['width'] = 0.25
[0f5bc9f]43        self.model.dispersion['radius']['npts'] = 100
[18b89c4]44        self.model.dispersion['radius']['nsigmas'] = 2.5
[0f5bc9f]45       
[dfa8832]46        self.assertAlmostEqual(self.model.run(0.001), 1.021051*4527.47250339, 3)
[59b9b675]47        self.assertAlmostEqual(self.model.runXY([0.001, 0.001]), 
48                               1.021048*4546.997777604715, 2)
[0f5bc9f]49       
50    def test_gaussian(self):
51        from sans.models.dispersion_models import GaussianDispersion
52        disp = GaussianDispersion()
53        self.model.set_dispersion('radius', disp)
[59b9b675]54        self.model.dispersion['radius']['width'] = 0.25
[0f5bc9f]55        self.model.dispersion['radius']['npts'] = 100
[59b9b675]56        self.model.dispersion['radius']['nsigmas'] = 2
[0f5bc9f]57        self.model.setParam('scale', 10.0)
58       
[59b9b675]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)
[0f5bc9f]63       
[8809e48]64    def test_clone(self):
65        from sans.models.dispersion_models import GaussianDispersion
66        disp = GaussianDispersion()
67        self.model.set_dispersion('radius', disp)
[59b9b675]68        self.model.dispersion['radius']['width'] = 0.25
[8809e48]69        self.model.dispersion['radius']['npts'] = 100
[59b9b675]70        self.model.dispersion['radius']['nsigmas'] = 2
[8809e48]71        self.model.setParam('scale', 10.0)
72       
73        new_model = self.model.clone()
[59b9b675]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)
[8809e48]78       
[ae60f86]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
[18b89c4]85        self.model.dispersion['radius']['nsigmas'] = 2.5
[ae60f86]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       
[0f5bc9f]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):
[18b89c4]104            values_ph[i]=(360/99.0*i)
105            values_th[i]=(180/99.0*i)
[0f5bc9f]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)
[59b9b675]145        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
146                               355.25355270620543, 3)
[0f5bc9f]147       
148    def test_dispersion(self):
149        """
150            Test with dispersion
151        """
152        from sans.models.DisperseModel import DisperseModel
[59b9b675]153        disp = DisperseModel(self.model, ['radius', 
154                                          'thickness', 
155                                          'length'], [5, 2, 50])
[0f5bc9f]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)
[59b9b675]164        self.model.dispersion['radius']['width'] = 0.25
[0f5bc9f]165        self.model.dispersion['radius']['npts'] = 10
[59b9b675]166        self.model.dispersion['radius']['nsigmas'] = 2
[0f5bc9f]167
168        disp_rr = GaussianDispersion()
169        self.model.set_dispersion('thickness', disp_rr)
[59b9b675]170        self.model.dispersion['thickness']['width'] = 0.2
[0f5bc9f]171        self.model.dispersion['thickness']['npts'] = 10
[59b9b675]172        self.model.dispersion['thickness']['nsigmas'] = 2
[0f5bc9f]173
174        disp_len = GaussianDispersion()
175        self.model.set_dispersion('length', disp_len)
[59b9b675]176        self.model.dispersion['length']['width'] = 1.0/8.0
[0f5bc9f]177        self.model.dispersion['length']['npts'] = 10
[59b9b675]178        self.model.dispersion['length']['nsigmas'] = 2
[0f5bc9f]179
[59b9b675]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)
[0f5bc9f]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):
[18b89c4]199            values_ph[i]=(360/99.0*i)
200            values_th[i]=(180/99.0*i)
[0f5bc9f]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        """
[59b9b675]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)
[0f5bc9f]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)
[59b9b675]256        self.model.dispersion['radius']['width'] = 0.1666666667
[0f5bc9f]257        self.model.dispersion['radius']['npts'] = 10
[59b9b675]258        self.model.dispersion['radius']['nsigmas'] = 2
[0f5bc9f]259
260        disp_rr = GaussianDispersion()
261        self.model.set_dispersion('thickness', disp_rr)
[59b9b675]262        self.model.dispersion['thickness']['width'] = 0.2
[0f5bc9f]263        self.model.dispersion['thickness']['npts'] = 10
[59b9b675]264        self.model.dispersion['thickness']['nsigmas'] = 2
[0f5bc9f]265
[59b9b675]266        self.assertAlmostEqual(self.model.run(0.001), 
267                               1.16747510*407.344127907553, 3)
[0f5bc9f]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)
[18b89c4]281        self.model.setParam('sldEll', 4.e-6)
282        self.model.setParam('sldSolv', 1.e-6)
[0f5bc9f]283        self.model.setParam('background', 0.0)
[18b89c4]284        self.model.setParam('axis_theta', 89.95445)
[0f5bc9f]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        """
[59b9b675]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)
[0f5bc9f]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)
[18b89c4]305
[0f5bc9f]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)
[59b9b675]313        self.model.dispersion['radius_a']['width'] = 0.25
[0f5bc9f]314        self.model.dispersion['radius_a']['npts'] = 10
[59b9b675]315        self.model.dispersion['radius_a']['nsigmas'] = 2
[0f5bc9f]316
317        disp_rr = GaussianDispersion()
318        self.model.set_dispersion('radius_b', disp_rr)
[59b9b675]319        self.model.dispersion['radius_b']['width'] = 0.125
[0f5bc9f]320        self.model.dispersion['radius_b']['npts'] = 10
[59b9b675]321        self.model.dispersion['radius_b']['nsigmas'] = 2
[0f5bc9f]322
[59b9b675]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)
[0f5bc9f]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):
[18b89c4]341            values_ph[i]=(360/99.0*i)
342            values_th[i]=(180/99.0*i)
[0f5bc9f]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)
[59b9b675]368        self.model.setParam('sldSph', 2.0)
369        self.model.setParam('sldSolv', 1.0)
[0f5bc9f]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        """
[019a943]378        self.assertTrue(math.fabs(self.model.run(0.001)-90412744456148.094)<=50.0)
[59b9b675]379        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
380                               90347660670656.391, 1)
[0f5bc9f]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)
[59b9b675]389        disp.setParam('radius.npts', 10)
390        disp.setParam('radius.nsigmas', 2.5)
[019a943]391        self.assertTrue(math.fabs(disp.run(0.001)-96795008379475.219<50.0))
[0f5bc9f]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)
[59b9b675]397        self.model.dispersion['radius']['width'] = 0.1666666667
[0f5bc9f]398        self.model.dispersion['radius']['npts'] = 10
[59b9b675]399        self.model.dispersion['radius']['nsigmas'] = 2
[0f5bc9f]400
[59b9b675]401        #self.assertAlmostEqual(self.model.run(0.001), 96795008379475.25,3)
[0f5bc9f]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)
[18b89c4]417        self.model.setParam('sldCyl', 4.0e-6)
418        self.model.setParam('sldSolv', 1.0e-6)
[0f5bc9f]419        self.model.setParam('background', 0.0)
[18b89c4]420        self.model.setParam('cyl_theta', 90)
[0f5bc9f]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        """
[59b9b675]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)
[0f5bc9f]434       
435    def test_dispersion(self):
436        """
437            Test with dispersion
438        """
439        from sans.models.DisperseModel import DisperseModel
[59b9b675]440        disp = DisperseModel(self.model, ['r_minor', 'r_ratio', 'length'], 
441                             [5, 0.25, 50])
[0f5bc9f]442        disp.setParam('n_pts', 10)
443        self.assertAlmostEqual(disp.run(0.001), 711.18048194151925, 3)
[18b89c4]444        self.assertAlmostEqual(disp.runXY([0.001,0.001]), 704.63525988095705, 0)
[0f5bc9f]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)
[59b9b675]450        self.model.dispersion['r_minor']['width'] = 0.25
[0f5bc9f]451        self.model.dispersion['r_minor']['npts'] = 10
[59b9b675]452        self.model.dispersion['r_minor']['nsigmas'] = 2
[0f5bc9f]453
454        disp_rr = GaussianDispersion()
455        self.model.set_dispersion('r_ratio', disp_rr)
[59b9b675]456        self.model.dispersion['r_ratio']['width'] = 0.25/1.5
[0f5bc9f]457        self.model.dispersion['r_ratio']['npts'] = 10
[59b9b675]458        self.model.dispersion['r_ratio']['nsigmas'] = 2
[0f5bc9f]459
460        disp_len = GaussianDispersion()
461        self.model.set_dispersion('length', disp_len)
[59b9b675]462        self.model.dispersion['length']['width'] = 50.0/400
[0f5bc9f]463        self.model.dispersion['length']['npts'] = 10
[59b9b675]464        self.model.dispersion['length']['nsigmas'] = 2
[0f5bc9f]465
[59b9b675]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)
[0f5bc9f]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):
[18b89c4]487            values_ps[i]=(360/99.0*i)
488            values_ph[i]=(360/99.0*i)
489            values_th[i]=(180/99.0*i)
[0f5bc9f]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       
[ae60f86]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)
[59b9b675]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)
[ae60f86]517        self.assertEqual(self.model.dispersion['radius']['type'], 'gaussian')
[0f5bc9f]518       
519 
520if __name__ == '__main__':
521    unittest.main()
522   
Note: See TracBrowser for help on using the repository browser.