source: sasview/test/sasrealspace/test/utest_realspace.py @ 1cdbcd8

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalcmagnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 1cdbcd8 was 1cdbcd8, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

move tests to use sasmodels rather than sas.models (tests will still fail)

  • Property mode set to 100644
File size: 12.4 KB
RevLine 
[959eb01]1"""
2    Unit tests for specific models
3    @author: Mathieu Doucet / UTK
4"""
[aaf5e49]5from __future__ import print_function
[959eb01]6
7import unittest, math, time
8
9# Disable "missing docstring" complaint
10# pylint: disable-msg=C0111
[1cdbcd8]11# Disable "too many methods" complaint
12# pylint: disable-msg=R0904
13# Disable "could be a function" complaint
[959eb01]14# pylint: disable-msg=R0201
15
[1cdbcd8]16from sasmodels.sasview_model import _make_standard_model
17EllipsoidModel = _make_standard_model('ellipsoid')
18SphereModel = _make_standard_model('sphere')
19CylinderModel = _make_standard_model('cylinder')
20CoreShellModel = _make_standard_model('core_shell_sphere')
21
22import sas.sascalc.realspace.VolumeCanvas as VolumeCanvas
23
[959eb01]24class TestRealSpaceModel(unittest.TestCase):
25    """ Unit tests for sphere model """
[1cdbcd8]26
[959eb01]27    def setUp(self):
28        self.model = VolumeCanvas.VolumeCanvas()
29        self.model.add('cylinder', 'cyl')
30        self.model.add('sphere', 'sph')
31        self.model.add('ellipsoid', 'elli')
32        self.model.add('singlehelix', 'shelix')
[1cdbcd8]33
[959eb01]34    def testAdding(self):
[1cdbcd8]35        self.assertEqual('cyl', self.model.add('cylinder', 'cyl'))
[959eb01]36
37    def testDeleting(self):
38        self.model.add('ellipsoid','elli2')
39        self.model.delete('elli2')
40        self.assert_('elli2' not in self.model.getShapeList())
41
42    def testsetParam(self):
43        self.model.setParam('q_max', 0.2)
44        self.model.setParam('shelix.radius_helix', 12)
45
46    def testgetParamList(self):
47        #print self.model.getParamList()
48        #print self.model.getParamList('shelix')
49        pass
50
51    def testPr_Iq(self):
52        self.model.getPr()
53        #print "pr is calculated", self.model.hasPr
54        result = self.model.getIq(0.1)
[1cdbcd8]55        #print "I(0.1) is calculated: ", result
[959eb01]56
57class TestSphere(unittest.TestCase):
58    """ Unit tests for sphere model """
59
60    def setUp(self):
61        self.canvas = VolumeCanvas.VolumeCanvas()
[1cdbcd8]62
63
[959eb01]64    def testSetQmax(self):
65        old_value = self.canvas.getParam('q_max')
66        new_value = old_value + 0.1
67        self.canvas.setParam('q_max', new_value)
[1cdbcd8]68        self.assertEqual(self.canvas.getParam("Q_MAx"), new_value)
69
70    def testSetDensity(self):
[959eb01]71        self.canvas.setParam('lores_density', 0.1)
72        handle = self.canvas.add('sphere')
73        self.canvas.setParam("%s.radius" % handle, 5.0)
74        vol = 4/3*math.pi*5*5*5
75        npts_1 = vol/0.1
76        value_1 = self.canvas.getIq(0.001)
[1cdbcd8]77
[959eb01]78        # Change density, the answer should be the same
79        self.canvas.setParam('lores_density', 0.2)
80        npts_2 = vol/0.2
81        value_2 = self.canvas.getIq(0.001)
[1cdbcd8]82
83        self.assert_( (value_1-value_2)/value_1 < 0.1)
84
85    def testSetDensityTiming(self):
[959eb01]86        """Testing change in computation time with density"""
87        handle = self.canvas.add('sphere')
88        self.canvas.setParam("%s.radius" % handle, 15.0)
[1cdbcd8]89
[959eb01]90        self.canvas.setParam('lores_density', 0.6)
91        t_0 = time.time()
92        self.canvas.getIq(0.001)
93        t_1 = time.time()-t_0
[1cdbcd8]94
[959eb01]95        # Change density, the answer should be the same
96        self.canvas.setParam('lores_density', 0.1)
97        t_0 = time.time()
98        self.canvas.getIq(0.001)
99        t_2 = time.time()-t_0
[1cdbcd8]100
101        self.assert_( t_2 < t_1 and (t_1-t_2)/t_2 > 2)
102
[959eb01]103    def testGetParamList(self):
104        """ Test GetParamList on empty canvas"""
105        self.assert_('lores_density' in self.canvas.getParamList())
106        handle = self.canvas.add('sphere')
[1cdbcd8]107
[959eb01]108    def testGetParamListWithShape(self):
109        """ Test GetParamList on filled canvas"""
110        self.canvas.add('sphere')
111        self.assert_('lores_density' in self.canvas.getParamList())
[1cdbcd8]112
[959eb01]113    def testAdd(self):
114        handle = "s1"
115        self.assertEqual(handle, self.canvas.add('sphere', handle))
[1cdbcd8]116
[959eb01]117        #TODO: test for current list of shape
118        self.assertEqual( [handle] , self.canvas.getShapeList())
[1cdbcd8]119
[959eb01]120    def testSetRadius(self):
121        handle = self.canvas.add('sphere')
[1cdbcd8]122        self.canvas.setParam("%s.radius" % handle, 24.0)
123        self.assertEqual(self.canvas.getParam("%s.radius" % handle), 24.0)
[959eb01]124
125    def testGetIq(self):
126        """ Test the output of I(q) to the analytical solution
127            If the normalization is wrong, we will have to fix it.
[1cdbcd8]128
[959eb01]129            getIq() should call getPr() behind the scenes so that
130            the user doesnt have to do it if he doesn't need to.
131        """
132        sphere = SphereModel()
133        sphere.setParam('scale', 1.0)
[1cdbcd8]134        sphere.setParam('background', 0.0)
135        sphere.setParam('sld', 1.0)
136        sphere.setParam('sld_solvent', 0.0)
137        sphere.setParam('radius', 10.0)
138
[959eb01]139        handle = self.canvas.add('sphere')
140        self.canvas.setParam('%s.radius' % handle, 10.0)
141        self.canvas.setParam('%s.contrast' % handle, 1.0)
[1cdbcd8]142
143
[959eb01]144        sim_1 = self.canvas.getIq(0.001)
145        ana_1 = sphere.run(0.001)
146        sim_2 = self.canvas.getIq(0.01)
147        ana_2 = sphere.run(0.01)
[1cdbcd8]148
149        # test the shape of the curve (calculate relative error
[959eb01]150        # on the output and it should be compatible with zero
151        # THIS WILL DEPEND ON THE NUMBER OF SPACE POINTS:
152        # that why we need some error analysis.
153        self.assert_( (sim_2*ana_1/sim_1 - ana_2)/ana_2 < 0.1)
[1cdbcd8]154
[959eb01]155        # test the absolute amplitude
156        self.assert_( math.fabs(sim_2-ana_2)/ana_2 < 0.1)
[1cdbcd8]157
[959eb01]158    def testGetIq2(self):
159        """ Test two different q values
160        """
161        handle = self.canvas.add('sphere')
162        self.canvas.setParam('%s.radius' % handle, 10.0)
[1cdbcd8]163
[959eb01]164        sim_1 = self.canvas.getIq(0.001)
165        sim_2 = self.canvas.getIq(0.01)
[1cdbcd8]166
[959eb01]167        self.assertNotAlmostEqual(sim_2, sim_1, 3)
[1cdbcd8]168
[959eb01]169    def testGetIq_Identical(self):
170        """ Test for identical model / no param change
171        """
172        handle = self.canvas.add('sphere')
173        self.canvas.setParam('%s.radius' % handle, 10.0)
[1cdbcd8]174
[959eb01]175        sim_1 = self.canvas.getIq(0.01)
176        sim_2 = self.canvas.getIq(0.01)
[1cdbcd8]177
[959eb01]178        self.assertEqual(sim_2, sim_1)
[1cdbcd8]179
[959eb01]180    def testGetIq_Identical2(self):
181        """ Test for identical model after a parameter change
182            Should be different only of the space points
183            are regenerated and the random seed is different
184        """
185        handle = self.canvas.add('sphere')
186        self.canvas.setParam('%s.radius' % handle, 10.0)
[1cdbcd8]187
[959eb01]188        self.canvas.setParam('lores_density', 0.1)
189        sim_1 = self.canvas.getIq(0.01)
[1cdbcd8]190
[959eb01]191        # Try to fool the code by changing to a different value
192        self.canvas.setParam('lores_density', 0.2)
193        self.canvas.getIq(0.01)
[1cdbcd8]194
[959eb01]195        self.canvas.setParam('lores_density', 0.1)
196        sim_2 = self.canvas.getIq(0.01)
[1cdbcd8]197
[959eb01]198        self.assert_((sim_2-sim_1)/sim_1<0.05)
[1cdbcd8]199
[959eb01]200    def testGetIq_time(self):
201        """ Time profile
202        """
203        handle = self.canvas.add('sphere')
204        self.canvas.setParam('%s.radius' % handle, 15.0)
[1cdbcd8]205
206
[959eb01]207        self.canvas.setParam('lores_density', 0.1)
208        t_0 = time.time()
209        sim_1 = self.canvas.getIq(0.01)
210        delta_1 = time.time()-t_0
[1cdbcd8]211
[959eb01]212        self.canvas.setParam('lores_density', 0.1)
[1cdbcd8]213
[959eb01]214        t_0 = time.time()
215        sim_2 = self.canvas.getIq(0.01)
216        delta_2 = time.time()-t_0
[1cdbcd8]217
[959eb01]218        self.assert_((delta_2-delta_1)/delta_1<0.05)
[1cdbcd8]219
220
[959eb01]221    def testGetPr(self):
222        """Compare the output of P(r) to the theoretical value"""
223        #TODO: find a way to compare you P(r) to the known
224        # analytical value.
225        pass
226
227    def testLogic1(self):
228        """ Test that the internal logic is set so that the user
229            get the right output after changing a parameter
230        """
[1cdbcd8]231
[959eb01]232        handle = self.canvas.add('sphere')
233        self.canvas.setParam('%s.radius' % handle, 10.0)
234        result_1 = self.canvas.getIq(0.1)
235        self.canvas.setParam('%s.radius' % handle, 20.0)
236        result_2 = self.canvas.getIq(0.1)
237        self.assertNotAlmostEqual(result_1, result_2, 2)
238
239class TestCanvas(unittest.TestCase):
240    """ Unit tests for all shapes in canvas model """
241
242    def setUp(self):
243        self.canvas = VolumeCanvas.VolumeCanvas()
244        self.canvas.params['lores_density'] = 0.05
245
246    def testGetIq_cylinder(self):
247        handle = self.canvas.add('cylinder','cyl')
248        self.canvas.setParam('%s.radius' % handle, 15.0)
249        self.canvas.setParam('%s.length' % handle, 50.0)
250        self.assertEqual(50,self.canvas.getParam('%s.length'%handle))
251        result_1 = self.canvas.getIq(0.1)
252        result_2 = self.canvas.getIq(0.1)
253        self.assertEqual(result_1,result_2)
254
255        self.canvas.delete(handle)
256        handle2 = self.canvas.add('cylinder','cyl2')
257        self.assertEqual(40,self.canvas.getParam('%s.length'%handle2))
258        result_3 = self.canvas.getIq(0.1)
259        self.assertNotEqual(result_1, result_3)
260
261    def testGetIq_ellipsoid(self):
262        handle = self.canvas.add('ellipsoid','elli')
263        self.canvas.setParam('%s.radius_x' % handle, 35)
264        self.canvas.setParam('%s.radius_y' % handle, 20)
265        self.canvas.setParam('%s.radius_z' % handle, 10)
266        result_1 = self.canvas.getIq(0.1)
267        result_2 = self.canvas.getIq(0.1)
268        self.assertEqual(result_1,result_2)
269
270        self.canvas.delete(handle)
271        self.assertEqual(False,self.canvas.hasPr)
272        handle2 = self.canvas.add('ellipsoid','elli2')
273        result_3 = self.canvas.getIq(0.1)
274        self.assertNotEqual(result_1, result_3)
275
276    def testGetIq_singlehelix(self):
277        handle = self.canvas.add('singlehelix','shelix')
278        self.canvas.setParam('%s.radius_helix' % handle, 11)
279        self.canvas.setParam('%s.radius_tube' % handle, 4)
280        self.canvas.setParam('%s.pitch' % handle, 30)
281        self.canvas.setParam('%s.turns' % handle, 3.2)
282        result_1 = self.canvas.getIq(0.1)
283        result_2 = self.canvas.getIq(0.1)
284        self.assertEqual(result_1,result_2)
285
286        self.canvas.delete(handle)
287        self.assertEqual(False,self.canvas.hasPr)
288        handle2 = self.canvas.add('singlehelix','shelix2')
289        result_3 = self.canvas.getIq(0.1)
290        self.assertNotEqual(result_1, result_3)
[1cdbcd8]291
[959eb01]292class TestOrdering(unittest.TestCase):
293    """ Unit tests for all shapes in canvas model """
294
295    def setUp(self):
296        radius = 15
297        thickness = 5
298        core_vol = 4.0/3.0*math.pi*radius*radius*radius
299        outer_radius = radius+thickness
300        shell_vol = 4.0/3.0*math.pi*outer_radius*outer_radius*outer_radius - core_vol
301        self.shell_sld = -1.0*core_vol/shell_vol
[1cdbcd8]302
[959eb01]303        self.canvas = VolumeCanvas.VolumeCanvas()
304        self.canvas.params['lores_density'] = 0.1
[1cdbcd8]305
[959eb01]306        # Core shell model
307        sphere = CoreShellModel()
[1cdbcd8]308        sphere.setParam('scale', 1.0)
309        sphere.setParam('background', 0.0)
310        sphere.setParam('sld_core', 1.0)
311        sphere.setParam('sld_shell', self.shell_sld)
312        sphere.setParam('sld_solvent', 0.0)
[959eb01]313        # Core radius
314        sphere.setParam('radius', radius)
315        # Shell thickness
316        sphere.setParam('thickness', thickness)
317        self.sphere = sphere
318        self.radius = radius
319        self.outer_radius = outer_radius
[1cdbcd8]320
[959eb01]321    def set_coreshell_on_canvas(self, order1=None, order2=None):
322
323        handle = self.canvas.add('sphere')
[1cdbcd8]324        self.canvas.setParam('scale' , 1.0)
325        self.canvas.setParam('background' , 0.0)
326
[959eb01]327        self.canvas.setParam('%s.radius' % handle, self.outer_radius)
328        self.canvas.setParam('%s.contrast' % handle, self.shell_sld)
[ac07a3a]329        if order1 is not None:
[959eb01]330            self.canvas.setParam('%s.order' % handle, order1)
[1cdbcd8]331
[959eb01]332        handle2 = self.canvas.add('sphere')
333        self.canvas.setParam('%s.radius' % handle2, self.radius)
334        self.canvas.setParam('%s.contrast' % handle2, 1.0)
[45dffa69]335        if order2 is not None:
[959eb01]336            self.canvas.setParam('%s.order' % handle2, order2)
[1cdbcd8]337
338
[959eb01]339    def testDefaultOrder(self):
340        self.set_coreshell_on_canvas()
[1cdbcd8]341
[959eb01]342        ana = self.sphere.run(0.05)
343        val, err = self.canvas.getIqError(0.05)
344        self.assert_(math.fabs(ana-val)<2.0*err)
[1cdbcd8]345
[959eb01]346    def testRightOrder(self):
347        self.set_coreshell_on_canvas(3.0, 6.0)
[1cdbcd8]348
[959eb01]349        ana = self.sphere.run(0.05)
350        val, err = self.canvas.getIqError(0.05)
351        #print 'right', ana, val, err
352        self.assert_(math.fabs(ana-val)/ana < 1.1)
[1cdbcd8]353
[959eb01]354    def testWrongOrder(self):
355        self.set_coreshell_on_canvas(1, 0)
[1cdbcd8]356
[959eb01]357        sphere = SphereModel()
358        sphere.setParam('scale', 1.0)
[1cdbcd8]359        sphere.setParam('background', 0.0)
360        sphere.setParam('radius', self.outer_radius)
361        sphere.setParam('sld', self.shell_sld)
362        sphere.setParam('sld_solvent', 0.0)
363
[959eb01]364        ana = sphere.run(0.05)
365        val, err = self.canvas.getIqError(0.05)
366        #print 'wrong', ana, val, err
367        self.assert_(math.fabs(ana-val)/ana < 1.1)
[1cdbcd8]368
369
[959eb01]370if __name__ == '__main__':
371    unittest.main()
Note: See TracBrowser for help on using the repository browser.