source: sasview/sansmodels/src/sans/models/test/utest_dispersity.py @ 9672627

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 9672627 was 49c92de, checked in by Jae Cho <jhjcho@…>, 13 years ago

fixed error due to prec.

  • 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        """
[59b9b675]378        self.assertAlmostEqual(self.model.run(0.001), 
[49c92de]379                               90412744456130.672, 3)
[59b9b675]380        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
381                               90347660670656.391, 1)
[0f5bc9f]382
383    def test_dispersion(self):
384        """
385            Test with dispersion
386        """
387        from sans.models.DisperseModel import DisperseModel
388        disp = DisperseModel(self.model, ['radius'], [10])
389        disp.setParam('n_pts', 10)
[59b9b675]390        disp.setParam('radius.npts', 10)
391        disp.setParam('radius.nsigmas', 2.5)
[49c92de]392        self.assertAlmostEqual(disp.run(0.001), 96795008379480.859, 1)
[0f5bc9f]393       
394    def test_new_disp(self):
395        from sans.models.dispersion_models import GaussianDispersion
396        disp_rm = GaussianDispersion()
397        self.model.set_dispersion('radius', disp_rm)
[59b9b675]398        self.model.dispersion['radius']['width'] = 0.1666666667
[0f5bc9f]399        self.model.dispersion['radius']['npts'] = 10
[59b9b675]400        self.model.dispersion['radius']['nsigmas'] = 2
[0f5bc9f]401
[59b9b675]402        #self.assertAlmostEqual(self.model.run(0.001), 96795008379475.25,3)
[0f5bc9f]403       
404       
405       
406class TestEllipticalCylinder(unittest.TestCase):
407    """
408        Testing C++ Cylinder model
409    """
410    def setUp(self):
411        from sans.models.EllipticalCylinderModel import EllipticalCylinderModel
412        self.model= EllipticalCylinderModel()
413       
414        self.model.setParam('scale', 1.0)
415        self.model.setParam('r_minor', 20.0)
416        self.model.setParam('r_ratio', 1.5)
417        self.model.setParam('length', 400.0)
[18b89c4]418        self.model.setParam('sldCyl', 4.0e-6)
419        self.model.setParam('sldSolv', 1.0e-6)
[0f5bc9f]420        self.model.setParam('background', 0.0)
[18b89c4]421        self.model.setParam('cyl_theta', 90)
[0f5bc9f]422        self.model.setParam('cyl_phi', 0.0)
423        self.model.setParam('cyl_psi', 0.0)
424       
425    def test_simple(self):
426        """
427            Test simple 1D and 2D values
428            Numbers taken from model that passed validation, before
429            the update to C++ underlying class.
430        """
[59b9b675]431        self.assertAlmostEqual(self.model.run(0.001), 
432                               675.50440232504991, 3)
433        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
434                               669.5173937622792, 0)
[0f5bc9f]435       
436    def test_dispersion(self):
437        """
438            Test with dispersion
439        """
440        from sans.models.DisperseModel import DisperseModel
[59b9b675]441        disp = DisperseModel(self.model, ['r_minor', 'r_ratio', 'length'], 
442                             [5, 0.25, 50])
[0f5bc9f]443        disp.setParam('n_pts', 10)
444        self.assertAlmostEqual(disp.run(0.001), 711.18048194151925, 3)
[18b89c4]445        self.assertAlmostEqual(disp.runXY([0.001,0.001]), 704.63525988095705, 0)
[0f5bc9f]446
447    def test_new_disp(self):
448        from sans.models.dispersion_models import GaussianDispersion
449        disp_rm = GaussianDispersion()
450        self.model.set_dispersion('r_minor', disp_rm)
[59b9b675]451        self.model.dispersion['r_minor']['width'] = 0.25
[0f5bc9f]452        self.model.dispersion['r_minor']['npts'] = 10
[59b9b675]453        self.model.dispersion['r_minor']['nsigmas'] = 2
[0f5bc9f]454
455        disp_rr = GaussianDispersion()
456        self.model.set_dispersion('r_ratio', disp_rr)
[59b9b675]457        self.model.dispersion['r_ratio']['width'] = 0.25/1.5
[0f5bc9f]458        self.model.dispersion['r_ratio']['npts'] = 10
[59b9b675]459        self.model.dispersion['r_ratio']['nsigmas'] = 2
[0f5bc9f]460
461        disp_len = GaussianDispersion()
462        self.model.set_dispersion('length', disp_len)
[59b9b675]463        self.model.dispersion['length']['width'] = 50.0/400
[0f5bc9f]464        self.model.dispersion['length']['npts'] = 10
[59b9b675]465        self.model.dispersion['length']['nsigmas'] = 2
[0f5bc9f]466
[59b9b675]467        self.assertAlmostEqual(self.model.run(0.001), 
468                               1.23925910*711.18048194151925, 3)
469        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 
470                               1.238955*704.63525988095705, 0)
[0f5bc9f]471       
472
473    def test_array(self):
474        """
475            Perform complete rotational average and
476            compare to 1D
477        """
478        from sans.models.dispersion_models import ArrayDispersion
479        disp_ph = ArrayDispersion()
480        disp_th = ArrayDispersion()
481        disp_ps = ArrayDispersion()
482       
483        values_ph = numpy.zeros(100)
484        values_th = numpy.zeros(100)
485        values_ps = numpy.zeros(100)
486        weights   = numpy.zeros(100)
487        for i in range(100):
[18b89c4]488            values_ps[i]=(360/99.0*i)
489            values_ph[i]=(360/99.0*i)
490            values_th[i]=(180/99.0*i)
[0f5bc9f]491            weights[i]=(1.0)
492       
493        disp_ph.set_weights(values_ph, weights)
494        disp_th.set_weights(values_th, weights)
495        disp_ps.set_weights(values_ps, weights)
496       
497        self.model.set_dispersion('cyl_theta', disp_th)
498        self.model.set_dispersion('cyl_phi', disp_ph)
499        self.model.set_dispersion('cyl_psi', disp_ps)
500       
501        val_1d = self.model.run(math.sqrt(0.0002))
502        val_2d = self.model.runXY([0.01,0.01]) 
503       
504        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
505       
[ae60f86]506class TestDispModel(unittest.TestCase):
507    def setUp(self):
508        from sans.models.CylinderModel import CylinderModel
509        self.model = CylinderModel()
510       
511       
512    def test_disp_params(self):
513       
514        self.assertEqual(self.model.dispersion['radius']['width'], 0.0)
[59b9b675]515        self.model.setParam('radius.width', 0.25)
516        self.assertEqual(self.model.dispersion['radius']['width'], 0.25)
517        self.assertEqual(self.model.getParam('radius.width'), 0.25)
[ae60f86]518        self.assertEqual(self.model.dispersion['radius']['type'], 'gaussian')
[0f5bc9f]519       
520 
521if __name__ == '__main__':
522    unittest.main()
523   
Note: See TracBrowser for help on using the repository browser.