source: sasview/sansmodels/src/sans/models/test/utest_nonshape.py @ 3de85b8

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 3de85b8 was 6b8399b, checked in by Mathieu Doucet <doucetm@…>, 17 years ago

update unit tests

  • Property mode set to 100644
File size: 16.7 KB
Line 
1"""
2    Unit tests for non shape based model (Task 8.2.1)
3    These tests are part of the requirements
4"""
5
6import unittest, time, math
7from scipy.special import erf,gammaln
8
9# Disable "missing docstring" complaint
10# pylint: disable-msg=C0111
11# Disable "too many methods" complaint
12# pylint: disable-msg=R0904
13# Disable "could be a function" complaint
14# pylint: disable-msg=R0201
15
16import scipy 
17class TestGuinier(unittest.TestCase):
18    """
19        Unit tests for Guinier function
20       
21        F(x) = exp[ [A] + [B]*Q**2 ]
22       
23        The model has two parameters: A and B
24    """
25    def _func(self, a, b, x):
26        return a*math.exp(-(b*x)**2/3.0)
27   
28    def setUp(self):
29        from sans.models.GuinierModel import GuinierModel
30        self.model= GuinierModel()
31       
32    def test1D(self):
33        self.model.setParam('scale', 2.0)
34        self.model.setParam('rg', 1.0)
35       
36        self.assertEqual(self.model.run(0.0), 2.0)
37        self.assertEqual(self.model.run(2.0), 2.0*math.exp(-(1.0*2.0)**2/3.0))
38        self.assertEqual(self.model.runXY(2.0), 2.0*math.exp(-(1.0*2.0)**2/3.0))
39       
40    def test2D(self):
41        self.model.setParam('scale', 2.0)
42        self.model.setParam('rg', 1.0)
43       
44        value = self._func(2.0, 1.0, 1.0)*self._func(2.0, 1.0, 2.0)
45        self.assertEqual(self.model.runXY([0.0,0.0]), 2.0*2.0)
46        self.assertEqual(self.model.runXY([1.0,2.0]), value)
47       
48    def test2Dphi(self):
49        self.model.setParam('scale', 2.0)
50        self.model.setParam('rg', 1.0)
51       
52        x = 1.0
53        y = 2.0
54        r = math.sqrt(x**2 + y**2)
55        phi = math.atan2(y, x)
56       
57        value = self._func(2.0, 1.0, x)*self._func(2.0, 1.0, y)
58       
59        #self.assertEqual(self.model.run([r, phi]), value)
60        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
61       
62       
63class TestPorod(unittest.TestCase):
64    """
65        Unit tests for Porod function
66       
67        F(x) = C/Q**4
68       
69        The model has one parameter: C
70    """
71    def _func(self, c, x):
72        return c/(x**4)
73   
74    def setUp(self):
75        from sans.models.PorodModel import PorodModel
76        self.model= PorodModel()
77        self.model.setParam('scale', 2.0)       
78       
79    def test1D(self):
80        value = self._func(2.0, 3.0)
81        self.assertEqual(self.model.run(3.0), value)
82        self.assertEqual(self.model.runXY(3.0), value)
83       
84    def test2D(self):
85        value = self._func(2.0, 1.0)*self._func(2.0, 2.0)
86        self.assertEqual(self.model.runXY([1.0,2.0]), value)
87       
88    def test2Dphi(self):
89        x = 1.0
90        y = 2.0
91        r = math.sqrt(x**2 + y**2)
92        phi = math.atan2(y, x)
93       
94        value = self._func(2.0, 1.0)*self._func(2.0, 2.0)
95        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
96       
97class TestDebye(unittest.TestCase):
98    """
99        Unit tests for Debye function
100       
101        F(x) = 2( exp(-x)+x -1 )/x**2
102       
103        The model has three parameters:
104            Rg     =  radius of gyration
105            scale  =  scale factor
106            bkd    =  Constant background
107    """
108    def _func(self, Rg, scale, bkg, x):
109        y = (Rg * x)**2
110        return scale * (2*(math.exp(-y) + y -1)/y**2) + bkg
111   
112    def setUp(self):
113        from sans.models.DebyeModel import DebyeModel
114        self.model= DebyeModel()
115        self.model.setParam('Rg', 50.0)   
116        self.model.setParam('scale',1.0) 
117        self.model.setParam('background',0.001)   
118       
119    def test1D(self):
120        value = self._func(50.0, 1.0, 0.001, 2.0)
121        self.assertEqual(self.model.run(2.0), value)
122        self.assertEqual(self.model.runXY(2.0), value)
123       
124        # User enter zero as a value of x
125        # An exceptio is raised
126        self.assertRaises(ZeroDivisionError, self.model.run, 0.0)
127       
128    def test2D(self):
129        value = self._func(50.0, 1.0, 0.001, 1.0)*self._func(50.0, 1.0, 0.001, 2.0)
130        self.assertEqual(self.model.runXY([1.0,2.0]), value)
131       
132    def test2Dphi(self):
133        x = 1.0
134        y = 2.0
135        r = math.sqrt(x**2 + y**2)
136        phi = math.atan2(y, x)
137       
138        value = self._func(50.0, 1.0, 0.001, 1.0)*self._func(50.0, 1.0, 0.001, 2.0)
139        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
140       
141       
142class TestLorentz(unittest.TestCase):
143    """
144        Unit tests for Lorentz function
145       
146         F(x) = scale/( 1 + (x*L)^2 ) + bkd
147       
148        The model has three parameters:
149            L     =  screen Length
150            scale  =  scale factor
151            bkd    =  incoherent background
152    """
153    def _func(self, I0 , L, bgd, qval):
154        return I0/(1.0 + (qval*L)*(qval*L)) + bgd
155   
156    def setUp(self):
157        from sans.models.LorentzModel import LorentzModel
158        self.model= LorentzModel()
159       
160    def test1D(self):
161        self.model.setParam('scale', 100.0)
162        self.model.setParam('Length', 50.0)
163        self.model.setParam('background', 1.0)
164       
165        self.assertEqual(self.model.run(0.0), 101.0)
166        self.assertEqual(self.model.run(2.0), self._func(100.0, 50.0, 1.0, 2.0))
167        self.assertEqual(self.model.runXY(2.0), self._func(100.0, 50.0, 1.0, 2.0))
168       
169    def test2D(self):
170        self.model.setParam('scale', 100.0)
171        self.model.setParam('Length', 50.0)
172        self.model.setParam('background', 1.0)
173       
174        value = self._func(100.0, 50.0, 1.0, 1.0)*self._func(100.0, 50.0, 1.0, 2.0)   
175        self.assertEqual(self.model.runXY([1.0,2.0]), value)
176       
177    def test2Dphi(self):
178        self.model.setParam('scale', 100.0)
179        self.model.setParam('Length', 50.0)
180        self.model.setParam('background', 1.0)
181       
182        x = 1.0
183        y = 2.0
184        r = math.sqrt(x**2 + y**2)
185        phi = math.atan2(y, x)
186       
187        value = self._func(100.0, 50.0, 1.0, x)*self._func(100.0, 50.0, 1.0, y)
188        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
189       
190class TestDAB(unittest.TestCase):
191    """
192        Unit tests for DAB function
193       
194         F(x) = scale/( 1 + (x*L)^2 )^(2) + bkd
195       
196        The model has three parameters:
197            L      =  Correlation Length
198            scale  =  scale factor
199            bkd    =  incoherent background
200    """
201    def _func(self, Izero, range, incoh, qval):
202        return Izero/pow((1.0 + (qval*range)*(qval*range)),2) + incoh
203   
204    def setUp(self):
205        from sans.models.DABModel import DABModel
206        self.model= DABModel()
207        self.scale = 10.0
208        self.length = 40.0
209        self.back = 1.0
210       
211        self.model.setParam('scale', self.scale)
212        self.model.setParam('Length', self.length)
213        self.model.setParam('background', self.back)
214       
215    def test1D(self):
216       
217        self.assertEqual(self.model.run(0.0), self.scale+self.back)
218        self.assertEqual(self.model.run(2.0), self._func(self.scale, self.length, self.back, 2.0))
219        self.assertEqual(self.model.runXY(2.0), self._func(self.scale, self.length, self.back, 2.0))
220       
221    def test2D(self):
222        value = self._func(self.scale, self.length, self.back, 1.0)*self._func(self.scale, self.length, self.back, 2.0)   
223        self.assertEqual(self.model.runXY([1.0,2.0]), value)
224       
225    def test2Dphi(self):
226        x = 1.0
227        y = 2.0
228        r = math.sqrt(x**2 + y**2)
229        phi = math.atan2(y, x)
230       
231        value = self._func(self.scale, self.length, self.back, x)*self._func(self.scale, self.length, self.back, y)
232        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
233       
234class TestPowerLaw(unittest.TestCase):
235    """
236        Unit tests for PowerLaw function
237
238        F(x) = scale* (x)^(m) + bkd
239       
240        The model has three parameters:
241            m     =  power
242            scale  =  scale factor
243            bkd    =  incoherent background
244    """
245    def _func(self, a, m, bgd, qval):
246        return a*math.pow(qval,-m) + bgd
247   
248   
249    def setUp(self):
250        from sans.models.PowerLawModel import PowerLawModel
251        self.model= PowerLawModel()
252       
253    def test1D(self):
254        self.model.setParam('scale', math.exp(-6))
255        self.model.setParam('m', 4.0)
256        self.model.setParam('background', 1.0)
257       
258        #self.assertEqual(self.model.run(0.0), 1.0)
259        self.assertEqual(self.model.run(2.0), self._func(math.exp(-6), 4.0, 1.0, 2.0))
260        self.assertEqual(self.model.runXY(2.0), self._func(math.exp(-6), 4.0, 1.0, 2.0))
261   
262    def testlimit(self):
263        self.model.setParam('scale', math.exp(-6))
264        self.model.setParam('m', -4.0)
265        self.model.setParam('background', 1.0)
266       
267        self.assertEqual(self.model.run(0.0), 1.0)
268       
269    def test2D(self):
270        self.model.setParam('scale', math.exp(-6))
271        self.model.setParam('m', 4.0)
272        self.model.setParam('background', 1.0)
273       
274        value = self._func(math.exp(-6), 4.0, 1.0, 1.0)\
275        *self._func(math.exp(-6), 4.0, 1.0, 2.0)   
276       
277        self.assertEqual(self.model.runXY([1.0,2.0]), value)
278       
279    def test2Dphi(self):
280        self.model.setParam('scale', math.exp(-6))
281        self.model.setParam('m', 4.0)
282        self.model.setParam('background', 1.0)
283       
284        x = 1.0
285        y = 2.0
286        r = math.sqrt(x**2 + y**2)
287        phi = math.atan2(y, x)
288       
289        value = self._func(math.exp(-6), 4.0, 1.0, x)\
290        *self._func(math.exp(-6), 4.0, 1.0, y)
291        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
292               
293class TestTeubnerStrey(unittest.TestCase):
294    """
295        Unit tests for PowerLaw function
296
297        F(x) = 1/( scale + c1*(x)^(2)+  c2*(x)^(4)) + bkd
298       
299        The model has Four parameters:
300            scale  =  scale factor
301            c1     =  constant
302            c2     =  constant
303            bkd    =  incoherent background
304    """
305    def _func(self, scale, c1, c2, bck, q):
306       
307        q2 = q*q;
308        q4 = q2*q2;
309   
310        return 1.0/(scale + c1*q2+c2*q4) + bck
311   
312    def setUp(self):
313        from sans.models.TeubnerStreyModel import TeubnerStreyModel
314        self.model= TeubnerStreyModel()
315       
316    def test1D(self):
317       
318        self.model.setParam('c1', -30.0) 
319        self.model.setParam('c2', 5000.0) 
320        self.model.setParam('scale', 0.1)
321        self.model.setParam('background', 0.1)
322        #self.assertEqual(1/(math.sqrt(4)), math.pow(4,-1/2))
323        #self.assertEqual(self.model.TeubnerStreyLengths(),False )
324       
325        self.assertEqual(self.model.run(0.0), 10.1)
326        self.assertEqual(self.model.run(2.0), self._func(0.1,-30.0,5000.0,0.1,2.0))
327        self.assertEqual(self.model.runXY(2.0), self._func(0.1,-30.0,5000.0,0.1,2.0))
328       
329    def test2D(self):
330        self.model.setParam('c1', -30.0) 
331        self.model.setParam('c2', 5000.0) 
332        self.model.setParam('scale', 0.1)
333        self.model.setParam('background', 0.1)
334        value = self._func(0.1,-30.0,5000.0,0.1, 1.0)\
335        *self._func(0.1,-30.0,5000.0,0.1, 2.0)   
336       
337        self.assertEqual(self.model.runXY([1.0,2.0]), value)
338       
339    def test2Dphi(self):
340        self.model.setParam('c1', -30.0) 
341        self.model.setParam('c2', 5000.0) 
342        self.model.setParam('scale', 0.1)
343        self.model.setParam('background', 0.1)
344       
345        x = 1.0
346        y = 2.0
347        r = math.sqrt(x**2 + y**2)
348        phi = math.atan2(y, x)
349       
350        value = self._func(0.1,-30.0,5000.0,0.1, x)\
351        *self._func(0.1,-30.0,5000.0,0.1, y)
352        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
353       
354class TestBEPolyelectrolyte(unittest.TestCase):
355    """
356        Unit tests for  BEPolyelectrolyte function
357       
358        F(x) = K*1/(4*pi()*Lb*(alpha)^(2)*(q^(2)+k2)/(1+(r02)^(2))*(q^(2)+k2)\
359                       *(q^(2)-(12*h*C/b^(2)))
360       
361        The model has Eight parameters:
362            K        =  Constrast factor of the polymer
363            Lb       =  Bjerrum length
364            H        =  virial parameter
365            B        =  monomer length
366            Cs       =  Concentration of monovalent salt
367            alpha    =  ionazation degree
368            C        = polymer molar concentration
369            bkd      = background
370    """
371    def _func(self, K, Lb, H, B, Cs, alpha, C, bkd, r02, k2,  x):
372        return (K /( (4*math.pi *Lb*(alpha**2)*(x**2 +k2)) *( (1 +(r02**2))  \
373                    *((x**2) + k2)*((x**2) -(12 * H * C/(B**2))) )))+ bkd
374   
375    def setUp(self):
376        from sans.models.BEPolyelectrolyte import BEPolyelectrolyte
377        self.model= BEPolyelectrolyte()
378       
379        self.K = 10.0
380        self.Lb = 6.5
381        self.h = 11
382        self.b = 13
383        self.Cs = 0.1
384        self.alpha = 0.05
385        self.= .7
386        self.Bkd =0.01
387       
388        self.model.setParam('K', self.K) 
389        self.model.setParam('Lb', self.Lb) 
390        self.model.setParam('H', self.h)
391        self.model.setParam('B', self.b)
392        self.model.setParam('Cs',self.Cs) 
393        self.model.setParam('alpha', self.alpha) 
394        self.model.setParam('C', self.C)
395        self.model.setParam('background', self.Bkd)
396       
397    def _func(self, q):
398       
399        Ca = self.C *6.022136e-4         
400        Csa = self.Cs * 6.022136e-4       
401        k2= 4*math.pi*self.Lb*(2*self.Cs+self.alpha*Ca)   
402
403        r02 = 1./self.alpha / Ca**0.5*( self.b / (48*math.pi*self.Lb)**0.5 )
404        q2 = q**2   
405        Sq = self.K*1./(4*math.pi*self.Lb*self.alpha**2) * (q2 + k2)  /  (1+(r02**2) * (q2+k2) * (q2- (12*self.h*Ca/self.b**2)) ) + self.Bkd
406        return Sq
407       
408    def test1D(self):
409       
410       
411        q = 0.001
412   
413        self.assertEqual(self.model.run(q), self._func(q))
414        self.assertEqual(self.model.runXY(q), self._func(q))
415         
416    def test2D(self):
417        self.assertAlmostEquals(self.model.runXY([1.0,2.0]), self._func(1.0)*self._func(2.0), 8)
418       
419    def test2Dphi(self):
420
421        x = 1.0
422        y = 2.0
423        r = math.sqrt(x**2 + y**2)
424        phi = math.atan2(y, x)
425       
426        self.assertAlmostEquals(self.model.run([r, phi]), self._func(x)*self._func(y), 8)
427       
428class TestFractalModel(unittest.TestCase):
429    """
430        Unit tests for  Number Density Fractal function   
431        F(x)= P(x)*S(x) + bkd
432        The model has Seven parameters:
433            scale   =  Volume fraction
434            Radius  =  Block radius
435            Fdim    =  Fractal dimension
436            L       =  correlation Length
437            SDLB    =  SDL block
438            SDLS    =  SDL solvent
439            bkd     =  background
440    """
441    def setUp(self):
442        from sans.models.FractalModel import FractalModel
443        self.model= FractalModel()
444        self.r0 = 5.0
445        self.sldp = 2.0e-6
446        self.sldm = 6.35e-6
447        self.phi = 0.05
448        self.Df = 2
449        self.corr = 100.0
450        self.bck = 1.0
451       
452        self.model.setParam('scale', self.phi) 
453        self.model.setParam('Radius', self.r0) 
454        self.model.setParam('fractal_dim',self.Df)
455        self.model.setParam('corr_length', self.corr)
456        self.model.setParam('block_sld', self.sldp) 
457        self.model.setParam('solvent_sld', self.sldm) 
458        self.model.setParam('background', self.bck)
459       
460    def _func(self, x):
461        r0 = self.r0
462        sldp = self.sldp
463        sldm = self.sldm
464        phi = self.phi
465        Df = self.Df
466        corr = self.corr
467        bck = self.bck
468       
469        pq = 1.0e8*phi*4.0/3.0*math.pi*r0*r0*r0*(sldp-sldm)*(sldp-sldm)*math.pow((3*(math.sin(x*r0) - x*r0*math.cos(x*r0))/math.pow((x*r0),3)),2);
470       
471        sq = Df*math.exp(gammaln(Df-1.0))*math.sin((Df-1.0)*math.atan(x*corr));
472        sq /= math.pow((x*r0),Df) * math.pow((1.0 + 1.0/(x*corr)/(x*corr)),((Df-1.0)/2.0));
473        sq += 1.0;
474       
475        self.assertAlmostEqual(self.model._scatterRanDom(x), pq, 8 )
476        self.assertEqual(self.model._Block(x),sq )
477       
478        return sq*pq+bck
479   
480    def test1D(self):       
481        x = 0.001
482       
483        iq = self._func(x)
484        self.assertEqual(self.model.run(x), iq)
485        self.assertEqual(self.model.runXY(x), iq)
486   
487    def test2D(self):
488        x = 1.0
489        y = 2.0
490        r = math.sqrt(x**2 + y**2)
491        phi = math.atan2(y, x)
492        iq_x = self._func(x)
493        iq_y = self._func(y)
494       
495        self.assertEqual(self.model.run([r, phi]), iq_x*iq_y)
496        self.assertEqual(self.model.runXY([x,y]), iq_x*iq_y)
497       
498if __name__ == '__main__':
499    unittest.main()
Note: See TracBrowser for help on using the repository browser.