source: sasview/park_integration/ParkFitting.py @ d7c05a8

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 d7c05a8 was d7c05a8, checked in by Jae Cho <jhjcho@…>, 13 years ago

fit common input Ftol

  • Property mode set to 100644
File size: 6.6 KB
Line 
1
2
3
4"""
5ParkFitting module contains SansParameter,Model,Data
6FitArrange, ParkFit,Parameter classes.All listed classes work together
7to perform a simple fit with park optimizer.
8"""
9#import time
10import numpy
11#import park
12from park import fit
13from park import fitresult
14from park.assembly import Assembly
15from park.fitmc import FitSimplex
16import park.fitmc
17from park.fitmc import FitMC
18
19#from Loader import Load
20from sans.fit.AbstractFitEngine import FitEngine
21
22
23
24class MyAssembly(Assembly):
25    def __init__(self, models, curr_thread=None):
26        Assembly.__init__(self, models)
27        self.curr_thread = curr_thread
28       
29    def eval(self):
30        """
31        Recalculate the theory functions, and from them, the
32        residuals and chisq.
33
34        :note: Call this after the parameters have been updated.
35        """
36        # Handle abort from a separate thread.
37        self._cancel = False
38        if self.curr_thread != None:
39            try:
40                self.curr_thread.isquit()
41            except:
42                self._cancel = True
43
44        # Evaluate the computed parameters
45        self._fitexpression()
46
47        # Check that the resulting parameters are in a feasible region.
48        if not self.isfeasible(): return numpy.inf
49
50        resid = []
51        k = len(self._fitparameters)
52        for m in self.parts:
53            # In order to support abort, need to be able to propagate an
54            # external abort signal from self.abort() into an abort signal
55            # for the particular model.  Can't see a way to do this which
56            # doesn't involve setting a state variable.
57            self._current_model = m
58            if self._cancel: return numpy.inf
59            if m.isfitted and m.weight != 0:
60                m.residuals = m.fitness.residuals()
61                N = len(m.residuals)
62                m.degrees_of_freedom = N-k if N>k else 1
63                m.chisq = numpy.sum(m.residuals**2)
64                resid.append(m.weight*m.residuals)
65        self.residuals = numpy.hstack(resid)
66        N = len(self.residuals)
67        self.degrees_of_freedom = N-k if N>k else 1
68        self.chisq = numpy.sum(self.residuals**2)
69        return self.chisq
70   
71class ParkFit(FitEngine):
72    """
73    ParkFit performs the Fit.This class can be used as follow:
74    #Do the fit Park
75    create an engine: engine = ParkFit()
76    Use data must be of type plottable
77    Use a sans model
78   
79    Add data with a dictionnary of FitArrangeList where Uid is a key and data
80    is saved in FitArrange object.
81    engine.set_data(data,Uid)
82   
83    Set model parameter "M1"= model.name add {model.parameter.name:value}.
84   
85    :note: Set_param() if used must always preceded set_model()
86         for the fit to be performed.
87    engine.set_param( model,"M1", {'A':2,'B':4})
88   
89    Add model with a dictionnary of FitArrangeList{} where Uid is a key
90    and model
91    is save in FitArrange object.
92    engine.set_model(model,Uid)
93   
94    engine.fit return chisqr,[model.parameter 1,2,..],[[err1....][..err2...]]
95    chisqr1, out1, cov1=engine.fit({model.parameter.name:value},qmin,qmax)
96   
97    :note: {model.parameter.name:value} is ignored in fit function since
98        the user should make sure to call set_param himself.
99       
100    """
101    def __init__(self):
102        """
103        Creates a dictionary (self.fitArrangeList={})of FitArrange elements
104        with Uid as keys
105        """
106        FitEngine.__init__(self)
107        self.fit_arrange_dict = {}
108        self.param_list = []
109       
110    def create_assembly(self, curr_thread):
111        """
112        Extract sansmodel and sansdata from
113        self.FitArrangelist ={Uid:FitArrange}
114        Create parkmodel and park data ,form a list couple of parkmodel
115        and parkdata
116        create an assembly self.problem=  park.Assembly([(parkmodel,parkdata)])
117        """
118        mylist = []
119        #listmodel = []
120        #i = 0
121        fitproblems = []
122        for fproblem in self.fit_arrange_dict.itervalues():
123            if fproblem.get_to_fit() == 1:
124                fitproblems.append(fproblem)
125        if len(fitproblems) == 0: 
126            raise RuntimeError, "No Assembly scheduled for Park fitting."
127            return
128        for item in fitproblems:
129            parkmodel = item.get_model()
130            for p in parkmodel.parameterset:
131                ## does not allow status change for constraint parameters
132                if p.status != 'computed':
133                    if p.get_name()in item.pars:
134                        ## make parameters selected for
135                        #fit will be between boundaries
136                        p.set(p.range)         
137                    else:
138                        p.status = 'fixed'
139            data_list = item.get_data()
140            parkdata = data_list
141            fitness = (parkmodel, parkdata)
142            mylist.append(fitness)
143        self.problem = MyAssembly(models=mylist, curr_thread=curr_thread)
144       
145 
146    def fit(self, q=None, handler=None, curr_thread=None, ftol=None):
147        """
148        Performs fit with park.fit module.It can  perform fit with one model
149        and a set of data, more than two fit of  one model and sets of data or
150        fit with more than two model associated with their set of data and
151        constraints
152       
153        :param pars: Dictionary of parameter names for the model and their
154            values.
155        :param qmin: The minimum value of data's range to be fit
156        :param qmax: The maximum value of data's range to be fit
157       
158        :note: all parameter are ignored most of the time.Are just there
159            to keep ScipyFit and ParkFit interface the same.
160           
161        :return: result.fitness Value of the goodness of fit metric
162        :return: result.pvec list of parameter with the best value
163            found during fitting
164        :return: result.cov Covariance matrix
165       
166        """
167        self.create_assembly(curr_thread=curr_thread)
168        localfit = FitSimplex()
169        localfit.ftol = 1e-8
170       
171        # See `park.fitresult.FitHandler` for details.
172        fitter = FitMC(localfit=localfit, start_points=1)
173        if handler == None:
174            handler = fitresult.ConsoleUpdate(improvement_delta=0.1)
175        result = fit.fit(self.problem, fitter=fitter, handler=handler)
176        self.problem.all_results(result)
177        if result != None:
178            if q != None:
179                q.put(result)
180                return q
181            return result
182        else:
183            raise ValueError, "SVD did not converge"
184           
Note: See TracBrowser for help on using the repository browser.