source: sasview/test/sasfit/test/utest_fit_smeared.py @ bc873053

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 bc873053 was bc873053, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

Fix slit height resolution problem. Still issues with slit width. Refs #472

  • Property mode set to 100644
File size: 7.2 KB
Line 
1"""
2    Unit tests for fitting module
3    @author M. Doucet
4"""
5import unittest
6import math
7
8import numpy
9from sas.fit.AbstractFitEngine import Model
10from sas.fit.BumpsFitting import BumpsFit as Fit
11from sas.dataloader.loader import Loader
12from sas.models.qsmearing import smear_selection
13from sas.models.CylinderModel import CylinderModel
14from sas.models.SphereModel import SphereModel
15
16
17from bumps import fitters
18try:
19    from bumps.options import FIT_CONFIG
20    def set_fitter(alg, opts):
21        FIT_CONFIG.selected_id= alg
22        FIT_CONFIG.values[alg].update(opts, monitors=[])
23except:
24    # CRUFT: Bumps changed its handling of fit options around 0.7.5.6
25    def set_fitter(alg, opts):
26        #print "fitting",alg,opts
27        #print "options",fitters.FIT_OPTIONS[alg].__dict__
28        fitters.FIT_DEFAULT = alg
29        fitters.FIT_OPTIONS[alg].options.update(opts, monitors=[])
30
31
32class testFitModule(unittest.TestCase):
33    """ test fitting """
34   
35    def test_without_resolution(self):
36        """ Simple cylinder model fit  """
37       
38        out=Loader().load("cyl_400_20.txt")
39        # This data file has not error, add them
40        #out.dy = out.y
41       
42        fitter = Fit()
43        fitter.set_data(out,1)
44       
45        # Receives the type of model for the fitting
46        model1  = CylinderModel()
47        model1.setParam("scale", 1.0)
48        model1.setParam("radius",18)
49        model1.setParam("length", 397)
50        model1.setParam("sldCyl",3e-006 )
51        model1.setParam("sldSolv",0.0 )
52        model1.setParam("background", 0.0)
53        model = Model(model1)
54        pars1 =['length','radius','scale']
55        fitter.set_model(model,1,pars1)
56       
57        # What the hell is this line for?
58        fitter.select_problem_for_fit(id=1,value=1)
59        result1, = fitter.fit()
60        #print "result1",result1
61
62        self.assert_(result1)
63        self.assertTrue(len(result1.pvec) > 0)
64        self.assertTrue(len(result1.stderr) > 0)
65       
66        self.assertTrue( math.fabs(result1.pvec[0]-400.0)/3.0 < result1.stderr[0] )
67        self.assertTrue( math.fabs(result1.pvec[1]-20.0)/3.0  < result1.stderr[1] )
68        self.assertTrue( math.fabs(result1.pvec[2]-1)/3.0   < result1.stderr[2] )
69        self.assertTrue( result1.fitness < 1.0 )
70
71    def test_dispersion(self):
72        """
73            Cylinder fit with dispersion
74        """
75        set_fitter('lm', {})
76        self._dispersion(fitter = Fit())
77
78    def _dispersion(self, fitter):
79        # Load data
80        # This data is for a cylinder with
81        #   length=400, radius=20, radius disp=5, scale=1e-10
82        out=Loader().load("cyl_400_20_disp5r.txt")
83        out.dy = numpy.zeros(len(out.y))
84        for i in range(len(out.y)):
85            out.dy[i] = math.sqrt(out.y[i])
86       
87        # Receives the type of model for the fitting
88        model1  = CylinderModel()
89        model1.setParam("scale", 10.0)
90        model1.setParam("radius",18)
91        model1.setParam("length", 397)
92        model1.setParam("sldCyl",3e-006 )
93        model1.setParam("sldSolv",0.0 )
94        model1.setParam("background", 0.0)
95
96        # Dispersion parameters
97        model1.dispersion['radius']['width'] = 0.25
98        model1.dispersion['radius']['npts'] = 50
99
100        model = Model(model1)
101
102        pars1 =['length','radius','scale','radius.width']
103        fitter.set_data(out,1)
104        fitter.set_model(model,1,pars1)
105        fitter.select_problem_for_fit(id=1,value=1)
106        #import time; T0 = time.time()
107        result1, = fitter.fit()
108
109        self.assert_(result1)
110        self.assertTrue(len(result1.pvec)>0)
111        self.assertTrue(len(result1.stderr)>0)
112
113        #print [z for z in zip(result1.param_list,result1.pvec,result1.stderr)]
114        self.assertTrue( math.fabs(result1.pvec[0]-399.8)/3.0 < result1.stderr[0] )
115        self.assertTrue( math.fabs(result1.pvec[1]-17.5)/3.0  < result1.stderr[1] )
116        self.assertTrue( math.fabs(result1.pvec[2]-11.1)/3.0   < result1.stderr[2] )
117        self.assertTrue( math.fabs(result1.pvec[3]-0.276)/3.0   < result1.stderr[3] )
118        self.assertTrue( result1.fitness < 1.0 )
119       
120       
121class smear_testdata(unittest.TestCase):
122    """
123        Test fitting with the smearing operations
124        The output of the fits should be compated to fits
125        done with IGOR for the same models and data sets.
126    """
127    def setUp(self):
128        data = Loader().load("latex_smeared.xml")
129        self.data_res = data[0]
130        self.data_slit = data[1]
131       
132        self.sphere = SphereModel()
133        self.sphere.setParam('background', 0)
134        self.sphere.setParam('radius', 5000.0)
135        self.sphere.setParam('scale', 0.4)
136        self.sphere.setParam('sldSolv',0)
137        self.sphere.setParam('sldSph',1e-6)
138        #self.sphere.setParam('radius.npts', 30)
139        #self.sphere.setParam('radius.width',50)
140
141    def test_reso(self):
142
143        # Let the data module find out what smearing the
144        # data needs
145        smear = smear_selection(self.data_res)
146        #self.assertEqual(smear.__class__.__name__, 'QSmearer')
147        #self.assertEqual(smear.__class__.__name__, 'PySmearer')
148
149        # Fit
150        fitter = Fit()
151       
152        # Data: right now this is the only way to set the smearer object
153        # We should improve that and have a way to get access to the
154        # data for a given fit.
155        fitter.set_data(self.data_res,1)
156        fitter.fit_arrange_dict[1].data_list[0].smearer = smear
157
158        # Model: maybe there's a better way to do this.
159        # Ideally we should have to create a new model from our sas model.
160        fitter.set_model(Model(self.sphere),1, ['radius','scale', 'background'])
161       
162        # Why do we have to do this...?
163        fitter.select_problem_for_fit(id=1,value=1)
164
165        # Perform the fit (might take a while)
166        result1, = fitter.fit()
167       
168        #print "v",result1.pvec
169        #print "dv",result1.stderr
170        #print "chisq(v)",result1.fitness
171
172        self.assertTrue( math.fabs(result1.pvec[0]-5000) < 20 )
173        self.assertTrue( math.fabs(result1.pvec[1]-0.48) < 0.02 )
174        self.assertTrue( math.fabs(result1.pvec[2]-0.060)  < 0.002 )
175
176
177    def test_slit(self):
178        smear = smear_selection(self.data_slit)
179        #self.assertEqual(smear.__class__.__name__, 'SlitSmearer')
180        #self.assertEqual(smear.__class__.__name__, 'PySmearer')
181
182        fitter = Fit()
183       
184        # Data: right now this is the only way to set the smearer object
185        # We should improve that and have a way to get access to the
186        # data for a given fit.
187        fitter.set_data(self.data_slit,1)
188        fitter.fit_arrange_dict[1].data_list[0].smearer = smear
189        fitter.fit_arrange_dict[1].data_list[0].qmax = 0.003
190       
191        # Model
192        fitter.set_model(Model(self.sphere),1, ['radius','scale'])
193        fitter.select_problem_for_fit(id=1,value=1)
194       
195        result1, = fitter.fit()
196
197        #print "v",result1.pvec
198        #print "dv",result1.stderr
199        #print "chisq(v)",result1.fitness
200
201        numpy.testing.assert_allclose(result1.pvec, [2323.466,0.22137], rtol=0.001)
202
203if __name__ == '__main__':
204    unittest.main()
Note: See TracBrowser for help on using the repository browser.