source: sasview/park_integration/ScipyFitting.py @ ecc85443

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 ecc85443 was 9a608ed, checked in by Gervaise Alina <gervyh@…>, 14 years ago

update catching exception for scipyfit

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[aa36f96]1
2
[792db7d5]3"""
[aa36f96]4ScipyFitting module contains FitArrange , ScipyFit,
5Parameter classes.All listed classes work together to perform a
6simple fit with scipy optimizer.
[792db7d5]7"""
[61cb28d]8
[88b5e83]9import numpy 
[511c6810]10import sys
[7705306]11from scipy import optimize
12
[b2f25dc5]13from sans.fit.AbstractFitEngine import FitEngine
14from sans.fit.AbstractFitEngine import SansAssembly
[511c6810]15from sans.fit.AbstractFitEngine import FitAbort
16
[61cb28d]17
[e0072082]18class fitresult(object):
[48882d1]19    """
[aa36f96]20    Storing fit result
[48882d1]21    """
[c4d6900]22    def __init__(self, model=None, param_list=None):
[89f3b66]23        self.calls = None
24        self.fitness = None
25        self.chisqr = None
26        self.pvec = None
27        self.cov = None
28        self.info = None
29        self.mesg = None
30        self.success = None
31        self.stderr = None
[e0072082]32        self.parameters = None
33        self.model = model
[c4d6900]34        self.param_list = param_list
[d603001]35        self.iterations = 0
[e0072082]36     
37    def set_model(self, model):
[aa36f96]38        """
39        """
[e0072082]40        self.model = model
41       
[90c9cdf]42    def set_fitness(self, fitness):
[aa36f96]43        """
44        """
[90c9cdf]45        self.fitness = fitness
46       
[e0072082]47    def __str__(self):
[aa36f96]48        """
49        """
[b2f25dc5]50        if self.pvec == None and self.model is None and self.param_list is None:
[e0072082]51            return "No results"
52        n = len(self.model.parameterset)
[d603001]53        self.iterations += 1
[e0072082]54        result_param = zip(xrange(n), self.model.parameterset)
[d603001]55        msg = [" [Iteration #: %s] | P%-3d  %s......|.....%s" % \
56               (self.iterations, p[0], p[1], p[1].value)\
[b2f25dc5]57              for p in result_param if p[1].name in self.param_list]
[c4d6900]58        msg.append("=== goodness of fit: %s" % (str(self.fitness)))
59        return "\n".join(msg)
[48882d1]60   
[e0072082]61    def print_summary(self):
[aa36f96]62        """
63        """
[e0072082]64        print self   
[88b5e83]65
[4c718654]66class ScipyFit(FitEngine):
[7705306]67    """
[aa36f96]68    ScipyFit performs the Fit.This class can be used as follow:
69    #Do the fit SCIPY
70    create an engine: engine = ScipyFit()
71    Use data must be of type plottable
72    Use a sans model
73   
74    Add data with a dictionnary of FitArrangeDict where Uid is a key and data
75    is saved in FitArrange object.
76    engine.set_data(data,Uid)
77   
78    Set model parameter "M1"= model.name add {model.parameter.name:value}.
79   
80    :note: Set_param() if used must always preceded set_model()
81         for the fit to be performed.In case of Scipyfit set_param is called in
82         fit () automatically.
83   
84    engine.set_param( model,"M1", {'A':2,'B':4})
85   
86    Add model with a dictionnary of FitArrangeDict{} where Uid is a key and model
87    is save in FitArrange object.
88    engine.set_model(model,Uid)
89   
90    engine.fit return chisqr,[model.parameter 1,2,..],[[err1....][..err2...]]
91    chisqr1, out1, cov1=engine.fit({model.parameter.name:value},qmin,qmax)
[7705306]92    """
[792db7d5]93    def __init__(self):
94        """
[b2f25dc5]95        Creates a dictionary (self.fit_arrange_dict={})of FitArrange elements
[aa36f96]96        with Uid as keys
[792db7d5]97        """
[b2f25dc5]98        FitEngine.__init__(self)
99        self.fit_arrange_dict = {}
100        self.param_list = []
[c4d6900]101        self.curr_thread = None
[511c6810]102        self.result = None
[d9dc518]103    #def fit(self, *args, **kw):
104    #    return profile(self._fit, *args, **kw)
[393f0f3]105
[e0072082]106    def fit(self, q=None, handler=None, curr_thread=None):
[aa36f96]107        """
108        """
[89f3b66]109        fitproblem = []
[c4d6900]110        for fproblem in self.fit_arrange_dict.itervalues():
[89f3b66]111            if fproblem.get_to_fit() == 1:
[393f0f3]112                fitproblem.append(fproblem)
[89f3b66]113        if len(fitproblem) > 1 : 
[e0072082]114            msg = "Scipy can't fit more than a single fit problem at a time."
115            raise RuntimeError, msg
[a9e04aa]116            return
[89f3b66]117        elif len(fitproblem) == 0 : 
[a9e04aa]118            raise RuntimeError, "No Assembly scheduled for Scipy fitting."
119            return
120   
[89f3b66]121        listdata = []
[393f0f3]122        model = fitproblem[0].get_model()
123        listdata = fitproblem[0].get_data()
[792db7d5]124        # Concatenate dList set (contains one or more data)before fitting
[e0072082]125        data = listdata
[89f3b66]126        self.curr_thread = curr_thread
[511c6810]127        self.result = fitresult(model=model, param_list=self.param_list)
128        self.handler = handler
129        if self.handler is not None:
130            self.handler.set_result(result=self.result)
[fd6b789]131        #try:
[511c6810]132        functor = SansAssembly(self.param_list, model, data, handler=self.handler,
133                         fitresult=self.result, curr_thread= self.curr_thread)
134   
135        try:
136            out, cov_x, _, mesg, success = optimize.leastsq(functor,
[c4d6900]137                                            model.get_params(self.param_list),
[3ab116f]138                                                    ftol = 0.001,
[c4d6900]139                                                    full_output=1,
140                                                    warning=True)
[511c6810]141        except:
[9a608ed]142            if hasattr(sys, 'last_type') and sys.last_type == FitAbort:
[511c6810]143                if self.handler is not None:
144                    msg = "Fit Stop!"
145                    #self.handler.error(msg)
146                    self.result = self.handler.get_result()
147                    return self.result
148            else:
149                raise 
150       
[c4d6900]151        chisqr = functor.chisq()
[fd6b789]152        if cov_x is not None and numpy.isfinite(cov_x).all():
153            stderr = numpy.sqrt(numpy.diag(cov_x))
154        else:
[e0072082]155            stderr = None
[511c6810]156       
157        if (out is not None) and not (numpy.isnan(out).any()) \
158            and (cov_x != None):
159            self.result.fitness = chisqr
160            self.result.stderr  = stderr
161            self.result.pvec = out
162            self.result.success = success
[fd6b789]163        else: 
[511c6810]164            msg = "SVD did not converge " + str(mesg)
165            #handler.error(msg)
166        return self.result
167
168       
[e0072082]169   
[d8a2e31]170
171
[c4d6900]172#def profile(fn, *args, **kw):
173#    import cProfile, pstats, os
174#    global call_result
175#   def call():
176#        global call_result
177#        call_result = fn(*args, **kw)
178#    cProfile.runctx('call()', dict(call=call), {}, 'profile.out')
179#    stats = pstats.Stats('profile.out')
180#    stats.sort_stats('time')
181#    stats.sort_stats('calls')
182#    stats.print_stats()
183#    os.unlink('profile.out')
184#    return call_result
[9c648c7]185
[48882d1]186     
Note: See TracBrowser for help on using the repository browser.