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
RevLine 
[914caf52]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
[f629e346]7from scipy.special import erf,gammaln
[914caf52]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
[829eee9]16import scipy 
[914caf52]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):
[f629e346]26        return a*math.exp(-(b*x)**2/3.0)
[914caf52]27   
28    def setUp(self):
[f629e346]29        from sans.models.GuinierModel import GuinierModel
[914caf52]30        self.model= GuinierModel()
31       
32    def test1D(self):
[f629e346]33        self.model.setParam('scale', 2.0)
34        self.model.setParam('rg', 1.0)
[914caf52]35       
[f629e346]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))
[6b8399b]38        self.assertEqual(self.model.runXY(2.0), 2.0*math.exp(-(1.0*2.0)**2/3.0))
[914caf52]39       
40    def test2D(self):
[f629e346]41        self.model.setParam('scale', 2.0)
42        self.model.setParam('rg', 1.0)
[914caf52]43       
44        value = self._func(2.0, 1.0, 1.0)*self._func(2.0, 1.0, 2.0)
[f629e346]45        self.assertEqual(self.model.runXY([0.0,0.0]), 2.0*2.0)
[914caf52]46        self.assertEqual(self.model.runXY([1.0,2.0]), value)
47       
48    def test2Dphi(self):
[f629e346]49        self.model.setParam('scale', 2.0)
50        self.model.setParam('rg', 1.0)
[914caf52]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       
[f03b027]59        #self.assertEqual(self.model.run([r, phi]), value)
60        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
[829eee9]61       
62       
[914caf52]63class TestPorod(unittest.TestCase):
64    """
65        Unit tests for Porod function
66       
[f629e346]67        F(x) = C/Q**4
[914caf52]68       
69        The model has one parameter: C
70    """
71    def _func(self, c, x):
[f629e346]72        return c/(x**4)
[914caf52]73   
74    def setUp(self):
[f629e346]75        from sans.models.PorodModel import PorodModel
[914caf52]76        self.model= PorodModel()
[f629e346]77        self.model.setParam('scale', 2.0)       
[914caf52]78       
79    def test1D(self):
80        value = self._func(2.0, 3.0)
81        self.assertEqual(self.model.run(3.0), value)
[6b8399b]82        self.assertEqual(self.model.runXY(3.0), value)
[914caf52]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)
[829eee9]95        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
[914caf52]96       
[829eee9]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):
[f629e346]113        from sans.models.DebyeModel import DebyeModel
[829eee9]114        self.model= DebyeModel()
115        self.model.setParam('Rg', 50.0)   
116        self.model.setParam('scale',1.0) 
[f629e346]117        self.model.setParam('background',0.001)   
[829eee9]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)
[6b8399b]122        self.assertEqual(self.model.runXY(2.0), value)
[829eee9]123       
[f629e346]124        # User enter zero as a value of x
125        # An exceptio is raised
126        self.assertRaises(ZeroDivisionError, self.model.run, 0.0)
[829eee9]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    """
[f629e346]153    def _func(self, I0 , L, bgd, qval):
154        return I0/(1.0 + (qval*L)*(qval*L)) + bgd
155   
[829eee9]156    def setUp(self):
[f629e346]157        from sans.models.LorentzModel import LorentzModel
[829eee9]158        self.model= LorentzModel()
159       
160    def test1D(self):
161        self.model.setParam('scale', 100.0)
[f629e346]162        self.model.setParam('Length', 50.0)
163        self.model.setParam('background', 1.0)
[829eee9]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))
[6b8399b]167        self.assertEqual(self.model.runXY(2.0), self._func(100.0, 50.0, 1.0, 2.0))
[829eee9]168       
169    def test2D(self):
170        self.model.setParam('scale', 100.0)
[f629e346]171        self.model.setParam('Length', 50.0)
172        self.model.setParam('background', 1.0)
[829eee9]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)
[f629e346]179        self.model.setParam('Length', 50.0)
180        self.model.setParam('background', 1.0)
[829eee9]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    """
[f629e346]201    def _func(self, Izero, range, incoh, qval):
202        return Izero/pow((1.0 + (qval*range)*(qval*range)),2) + incoh
[829eee9]203   
204    def setUp(self):
[f629e346]205        from sans.models.DABModel import DABModel
[829eee9]206        self.model= DABModel()
[6b8399b]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)
[829eee9]214       
215    def test1D(self):
216       
[6b8399b]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))
[829eee9]220       
221    def test2D(self):
[6b8399b]222        value = self._func(self.scale, self.length, self.back, 1.0)*self._func(self.scale, self.length, self.back, 2.0)   
[829eee9]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       
[6b8399b]231        value = self._func(self.scale, self.length, self.back, x)*self._func(self.scale, self.length, self.back, y)
[f03b027]232        self.assertAlmostEquals(self.model.run([r, phi]), value,1)
[914caf52]233       
[829eee9]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    """
[f629e346]245    def _func(self, a, m, bgd, qval):
246        return a*math.pow(qval,-m) + bgd
247   
[829eee9]248   
249    def setUp(self):
[f629e346]250        from sans.models.PowerLawModel import PowerLawModel
[829eee9]251        self.model= PowerLawModel()
252       
253    def test1D(self):
254        self.model.setParam('scale', math.exp(-6))
255        self.model.setParam('m', 4.0)
[f629e346]256        self.model.setParam('background', 1.0)
[829eee9]257       
[f629e346]258        #self.assertEqual(self.model.run(0.0), 1.0)
[829eee9]259        self.assertEqual(self.model.run(2.0), self._func(math.exp(-6), 4.0, 1.0, 2.0))
[6b8399b]260        self.assertEqual(self.model.runXY(2.0), self._func(math.exp(-6), 4.0, 1.0, 2.0))
[f629e346]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)
[829eee9]268       
269    def test2D(self):
270        self.model.setParam('scale', math.exp(-6))
271        self.model.setParam('m', 4.0)
[f629e346]272        self.model.setParam('background', 1.0)
[829eee9]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)
[f629e346]282        self.model.setParam('background', 1.0)
[829eee9]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    """
[f629e346]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
[829eee9]311   
312    def setUp(self):
[f629e346]313        from sans.models.TeubnerStreyModel import TeubnerStreyModel
[829eee9]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)
[f629e346]321        self.model.setParam('background', 0.1)
[829eee9]322        #self.assertEqual(1/(math.sqrt(4)), math.pow(4,-1/2))
[f629e346]323        #self.assertEqual(self.model.TeubnerStreyLengths(),False )
[829eee9]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))
[6b8399b]327        self.assertEqual(self.model.runXY(2.0), self._func(0.1,-30.0,5000.0,0.1,2.0))
[829eee9]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)
[f629e346]333        self.model.setParam('background', 0.1)
[829eee9]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)
[f629e346]343        self.model.setParam('background', 0.1)
[829eee9]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):
[f629e346]376        from sans.models.BEPolyelectrolyte import BEPolyelectrolyte
[829eee9]377        self.model= BEPolyelectrolyte()
378       
[f629e346]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       
[829eee9]408    def test1D(self):
409       
[f629e346]410       
411        q = 0.001
412   
413        self.assertEqual(self.model.run(q), self._func(q))
[6b8399b]414        self.assertEqual(self.model.runXY(q), self._func(q))
[f629e346]415         
[829eee9]416    def test2D(self):
[f629e346]417        self.assertAlmostEquals(self.model.runXY([1.0,2.0]), self._func(1.0)*self._func(2.0), 8)
[829eee9]418       
419    def test2Dphi(self):
[f629e346]420
[829eee9]421        x = 1.0
422        y = 2.0
423        r = math.sqrt(x**2 + y**2)
424        phi = math.atan2(y, x)
425       
[f629e346]426        self.assertAlmostEquals(self.model.run([r, phi]), self._func(x)*self._func(y), 8)
[829eee9]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):
[f629e346]442        from sans.models.FractalModel import FractalModel
[829eee9]443        self.model= FractalModel()
[6b8399b]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
[f629e346]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;
[829eee9]474       
[6b8399b]475        self.assertAlmostEqual(self.model._scatterRanDom(x), pq, 8 )
[f629e346]476        self.assertEqual(self.model._Block(x),sq )
[829eee9]477       
[6b8399b]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)
[829eee9]497       
[914caf52]498if __name__ == '__main__':
499    unittest.main()
Note: See TracBrowser for help on using the repository browser.