source: sasview/park_integration/ParkFitting.py @ dfd3577

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

working on park stop

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[aa36f96]1
2
3
[792db7d5]4"""
[aa36f96]5ParkFitting module contains SansParameter,Model,Data
[b2f25dc5]6FitArrange, ParkFit,Parameter classes.All listed classes work together
7to perform a simple fit with park optimizer.
[792db7d5]8"""
[89f3b66]9#import time
[dfd3577]10import numpy
[b2f25dc5]11#import park
12from park import fit
13from park import fitresult
14from park.assembly import Assembly
15from park.fitmc import FitSimplex
[dfd3577]16import park.fitmc
[b2f25dc5]17from park.fitmc import FitMC
[7d0c1a8]18
[61cb28d]19#from Loader import Load
[b2f25dc5]20from sans.fit.AbstractFitEngine import FitEngine
[d4b0687]21
[fadea71]22
[dfd3577]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   
[4c718654]71class ParkFit(FitEngine):
[7705306]72    """
[aa36f96]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   
[b2f25dc5]89    Add model with a dictionnary of FitArrangeList{} where Uid is a key
90    and model
[aa36f96]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
[792db7d5]98        the user should make sure to call set_param himself.
[aa36f96]99       
[7705306]100    """
[916a15f]101    def __init__(self):
[792db7d5]102        """
[aa36f96]103        Creates a dictionary (self.fitArrangeList={})of FitArrange elements
104        with Uid as keys
[792db7d5]105        """
[b2f25dc5]106        FitEngine.__init__(self)
107        self.fit_arrange_dict = {}
108        self.param_list = []
[37d9521]109       
[dfd3577]110    def create_assembly(self, curr_thread):
[7705306]111        """
[b2f25dc5]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
[792db7d5]116        create an assembly self.problem=  park.Assembly([(parkmodel,parkdata)])
[7705306]117        """
[89f3b66]118        mylist = []
[b2f25dc5]119        #listmodel = []
120        #i = 0
[89f3b66]121        fitproblems = []
[b2f25dc5]122        for fproblem in self.fit_arrange_dict.itervalues():
[89f3b66]123            if fproblem.get_to_fit() == 1:
[a9e04aa]124                fitproblems.append(fproblem)
[89f3b66]125        if len(fitproblems) == 0: 
[a9e04aa]126            raise RuntimeError, "No Assembly scheduled for Park fitting."
127            return
128        for item in fitproblems:
129            parkmodel = item.get_model()
[9e85792]130            for p in parkmodel.parameterset:
[fe886ee]131                ## does not allow status change for constraint parameters
[89f3b66]132                if p.status != 'computed':
[b2f25dc5]133                    if p.get_name()in item.pars:
134                        ## make parameters selected for
135                        #fit will be between boundaries
[89f3b66]136                        p.set(p.range)         
[aed7c57]137                    else:
[89f3b66]138                        p.status = 'fixed'
[b2f25dc5]139            data_list = item.get_data()
140            parkdata = data_list
[89f3b66]141            fitness = (parkmodel, parkdata)
[ca6d914]142            mylist.append(fitness)
[dfd3577]143        self.problem = MyAssembly(models=mylist, curr_thread=curr_thread)
[126a761]144       
[dfd3577]145 
146   
[89f3b66]147    def fit(self, q=None, handler=None, curr_thread=None):
[7705306]148        """
[aa36f96]149        Performs fit with park.fit module.It can  perform fit with one model
150        and a set of data, more than two fit of  one model and sets of data or
[b2f25dc5]151        fit with more than two model associated with their set of data and
152        constraints
[aa36f96]153       
[b2f25dc5]154        :param pars: Dictionary of parameter names for the model and their
155            values.
[aa36f96]156        :param qmin: The minimum value of data's range to be fit
157        :param qmax: The maximum value of data's range to be fit
158       
[b2f25dc5]159        :note: all parameter are ignored most of the time.Are just there
160            to keep ScipyFit and ParkFit interface the same.
[aa36f96]161           
162        :return: result.fitness Value of the goodness of fit metric
[b2f25dc5]163        :return: result.pvec list of parameter with the best value
164            found during fitting
[aa36f96]165        :return: result.cov Covariance matrix
166       
[7705306]167        """
[dfd3577]168        self.create_assembly(curr_thread=curr_thread)
[cf3b781]169        localfit = FitSimplex()
170        localfit.ftol = 1e-8
[681f0dc]171       
[916a15f]172        # See `park.fitresult.FitHandler` for details.
[9c648c7]173        fitter = FitMC(localfit=localfit, start_points=1)
[681f0dc]174        if handler == None:
[89f3b66]175            handler = fitresult.ConsoleUpdate(improvement_delta=0.1)
[dfd3577]176        result = fit.fit(self.problem, fitter=fitter, handler=handler)
[8296ff5]177        self.problem.all_results(result)
[89f3b66]178        if result != None:
179            if q != None:
[fd6b789]180                q.put(result)
181                return q
[48882d1]182            return result
[ee5b04c]183        else:
184            raise ValueError, "SVD did not converge"
[aa36f96]185           
Note: See TracBrowser for help on using the repository browser.