source: sasview/park_integration/ParkFitting.py @ 9855699

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 9855699 was 9855699, checked in by Gervaise Alina <gervyh@…>, 16 years ago

modified parkfitting ,added print statement

  • Property mode set to 100644
File size: 7.3 KB
Line 
1"""
2    @organization: ParkFitting module contains SansParameter,Model,Data
3    FitArrange, ParkFit,Parameter classes.All listed classes work together to perform a
4    simple fit with park optimizer.
5"""
6import time
7import numpy
8
9import park
10from park import fit,fitresult
11from park import assembly
12from park.fitmc import FitSimplex, FitMC
13
14from sans.guitools.plottables import Data1D
15from Loader import Load
16from AbstractFitEngine import FitEngine, Parameter, FitArrange
17class SansParameter(park.Parameter):
18    """
19        SANS model parameters for use in the PARK fitting service.
20        The parameter attribute value is redirected to the underlying
21        parameter value in the SANS model.
22    """
23    def __init__(self, name, model):
24         self._model, self._name = model,name
25         self.set(model.getParam(name))
26         
27    def _getvalue(self): return self._model.getParam(self.name)
28   
29    def _setvalue(self,value): 
30        self._model.setParam(self.name, value)
31       
32    value = property(_getvalue,_setvalue)
33   
34    def _getrange(self):
35        lo,hi = self._model.details[self.name][1:]
36        if lo is None: lo = -numpy.inf
37        if hi is None: hi = numpy.inf
38        return lo,hi
39   
40    def _setrange(self,r):
41        self._model.details[self.name][1:] = r
42    range = property(_getrange,_setrange)
43
44
45class Model(object):
46    """
47        PARK wrapper for SANS models.
48    """
49    def __init__(self, sans_model):
50        self.model = sans_model
51        sansp = sans_model.getParamList()
52       
53        parkp = [SansParameter(p,sans_model) for p in sansp]
54        self.parameterset = park.ParameterSet(sans_model.name,pars=parkp)
55       
56    def eval(self,x):
57        print "eval",self.parameterset[0].value
58        return self.model.run(x)
59   
60class Data(object):
61    """ Wrapper class  for SANS data """
62    def __init__(self,x=None,y=None,dy=None,dx=None,sans_data=None):
63        if not sans_data==None:
64            self.x= sans_data.x
65            self.y= sans_data.y
66            self.dx= sans_data.dx
67            self.dy= sans_data.dy
68        else:
69            if x!=None and y!=None and dy!=None:
70                self.x=x
71                self.y=y
72                self.dx=dx
73                self.dy=dy
74            else:
75                raise ValueError,\
76                "Data is missing x, y or dy, impossible to compute residuals later on"
77        self.qmin=None
78        self.qmax=None
79       
80    def setFitRange(self,mini=None,maxi=None):
81        """ to set the fit range"""
82        self.qmin=mini
83        self.qmax=maxi
84       
85    def residuals(self, fn):
86        """ @param fn: function that return model value
87            @return residuals
88        """
89        x,y,dy = [numpy.asarray(v) for v in (self.x,self.y,self.dy)]
90        if self.qmin==None and self.qmax==None: 
91            self.fx = fn(x)
92            return (y - fn(x))/dy
93       
94        else:
95            self.fx = fn(x[idx])
96            idx = x>=self.qmin & x <= self.qmax
97            return (y[idx] - fn(x[idx]))/dy[idx]
98           
99         
100    def residuals_deriv(self, model, pars=[]):
101        """
102            @return residuals derivatives .
103            @note: in this case just return empty array
104        """
105        return []
106
107           
108class ParkFit(FitEngine):
109    """
110        ParkFit performs the Fit.This class can be used as follow:
111        #Do the fit Park
112        create an engine: engine = ParkFit()
113        Use data must be of type plottable
114        Use a sans model
115       
116        Add data with a dictionnary of FitArrangeList where Uid is a key and data
117        is saved in FitArrange object.
118        engine.set_data(data,Uid)
119       
120        Set model parameter "M1"= model.name add {model.parameter.name:value}.
121        @note: Set_param() if used must always preceded set_model()
122             for the fit to be performed.
123        engine.set_param( model,"M1", {'A':2,'B':4})
124       
125        Add model with a dictionnary of FitArrangeList{} where Uid is a key and model
126        is save in FitArrange object.
127        engine.set_model(model,Uid)
128       
129        engine.fit return chisqr,[model.parameter 1,2,..],[[err1....][..err2...]]
130        chisqr1, out1, cov1=engine.fit({model.parameter.name:value},qmin,qmax)
131        @note: {model.parameter.name:value} is ignored in fit function since
132        the user should make sure to call set_param himself.
133    """
134    def __init__(self,data=[]):
135        """
136            Creates a dictionary (self.fitArrangeList={})of FitArrange elements
137            with Uid as keys
138        """
139        self.fitArrangeList={}
140       
141    def createProblem(self):
142        """
143        Extract sansmodel and sansdata from self.FitArrangelist ={Uid:FitArrange}
144        Create parkmodel and park data ,form a list couple of parkmodel and parkdata
145        create an assembly self.problem=  park.Assembly([(parkmodel,parkdata)])
146        """
147        mylist=[]
148        listmodel=[]
149       
150        for k,value in self.fitArrangeList.iteritems():
151            sansmodel=value.get_model()
152            #wrap sans model
153            parkmodel = Model(sansmodel)
154            for p in parkmodel.parameterset:
155                #self.param_list.append(p._getname())
156                if p.isfixed() and p._getname()in self.paramList:
157                    p.set([-numpy.inf,numpy.inf])
158               
159            Ldata=value.get_data()
160            x,y,dy=self._concatenateData(Ldata)
161            #wrap sansdata
162            parkdata=Data(x,y,dy,None)
163            couple=(parkmodel,parkdata)
164            mylist.append(couple)
165        print "mylist",mylist
166        self.problem =  park.Assembly(mylist)
167       
168   
169    def fit(self, qmin=None, qmax=None):
170        """
171            Performs fit with park.fit module.It can  perform fit with one model
172            and a set of data, more than two fit of  one model and sets of data or
173            fit with more than two model associated with their set of data and constraints
174           
175           
176            @param pars: Dictionary of parameter names for the model and their values.
177            @param qmin: The minimum value of data's range to be fit
178            @param qmax: The maximum value of data's range to be fit
179            @note:all parameter are ignored most of the time.Are just there to keep ScipyFit
180            and ParkFit interface the same.
181            @return result.fitness: Value of the goodness of fit metric
182            @return result.pvec: list of parameter with the best value found during fitting
183            @return result.cov: Covariance matrix
184        """
185        print "Parkfitting: fit method probably breaking just right before \
186        call fit"
187        self.createProblem()
188        pars=self.problem.fit_parameters()
189        self.problem.eval()
190        #print "M0.B",self.problem[1].parameterset['B'].value,self.problem[0].parameterset['B'].value
191
192        localfit = FitSimplex()
193        localfit.ftol = 1e-8
194        fitter = FitMC(localfit=localfit)
195       
196        result = fit.fit(self.problem,
197                         fitter=fitter,
198                         handler= fitresult.ConsoleUpdate(improvement_delta=0.1))
199        for p in result.parameters:
200            print "fit in park fitting", p.name, p.value
201        return result.fitness,result.pvec,result.cov
202   
203   
Note: See TracBrowser for help on using the repository browser.