source: sasview/sansmodels/src/sans/models/test/utest_nonshape.py @ 20f00bed

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 20f00bed was ec658c85, checked in by Jae Cho <jhjcho@…>, 15 years ago

python files of new models and unit tests

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