source: sasview/park_integration/ScipyFitting.py @ b2d9826

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 b2d9826 was 3ab116f, checked in by Jae Cho <jhjcho@…>, 14 years ago

raises a error when scipy get a silent error( this is a very strange behavior)

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