Changeset 233c121 in sasview for src


Ignore:
Timestamp:
May 21, 2014 9:19:00 AM (11 years ago)
Author:
pkienzle
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
bf5e985
Parents:
85a3b46 (diff), 099c355 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

refactor OnFit? handler to allow fit to current page only

Location:
src/sans
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • src/sans/fit/BumpsFitting.py

    reff93b8 r233c121  
    169169                   for i,M in enumerate(self.fit_arrange_dict.values()) 
    170170                   if M.get_to_fit() == 1 ] 
     171        if len(models) == 0: 
     172            raise RuntimeError("Nothing to fit") 
    171173        problem = FitProblem(models) 
    172174 
     
    246248    mapper = SerialMapper  
    247249    fitdriver.mapper = mapper.start_mapper(problem, None) 
    248     import time; T0 = time.time() 
     250    #import time; T0 = time.time() 
    249251    try: 
    250252        best, fbest = fitdriver.fit() 
  • src/sans/guiframe/gui_manager.py

    r51af54b rafb5080  
    19581958                wx.PostEvent(self, StatusEvent(status="Completed Saving.")) 
    19591959            else: 
    1960                 msg = "No perspective windows are loaded. " 
    1961                 msg += "No data was saved to %s\n" % (str(path)) 
     1960                msg = "Error occurred while saving the project: " 
     1961                msg += "To save, at least one application panel " 
     1962                msg += "should have a data set " 
     1963                msg += "and model selected. " 
     1964                msg += "No project was saved to %s" % (str(path)) 
    19621965                logging.error(msg) 
    19631966                wx.PostEvent(self,StatusEvent(status=msg)) 
  • src/sans/perspectives/fitting/fitpage.py

    r4e9f227 r233c121  
    20682068        return self.tcChi.GetValue() 
    20692069         
    2070     def get_param_list(self): 
    2071         """ 
    2072         :return self.param_toFit: list containing  references to TextCtrl 
    2073             checked.Theses TextCtrl will allow reference to parameters to fit. 
    2074          
    2075         :raise: if return an empty list of parameter fit will nnote work 
    2076             properly so raise ValueError,"missing parameter to fit" 
    2077         """ 
    2078         if self.param_toFit != []: 
    2079             return self.param_toFit 
    2080         else: 
    2081             msg = "missing parameters to fit" 
    2082             wx.MessageBox(msg, 'warning') 
    2083             return False 
    2084        
    20852070    def onsetValues(self, chisqr, p_name, out, cov): 
    20862071        """ 
  • src/sans/perspectives/fitting/fitting.py

    reff93b8 r233c121  
    8686        self.elapsed = 0.022 
    8787        self.fit_panel = None 
    88         #let fit ready 
    89         self.fitproblem_count = None 
    9088        #Flag to let the plug-in know that it is running stand alone 
    9189        self.standalone = True 
     
    983981        :param uid: id related to the panel currently calling this fit function. 
    984982        """ 
    985         flag = True 
    986         ##  count the number of fitproblem schedule to fit 
    987         fitproblem_count = 0 
    988         for value in self.page_finder.values(): 
    989             if value.get_scheduled() == 1: 
    990                 fitproblem_count += 1 
     983        if uid is None: raise RuntimeError("no page to fit") # Should never happen 
     984 
    991985        # Remember the user selected fit engine before the fit.  Simultaneous 
    992986        # fitting may change the selected engine, so it needs to be restored 
    993987        # when the fit is complete. 
    994988        self._gui_engine = self._fit_engine 
    995         self.fitproblem_count = fitproblem_count 
    996         if self._fit_engine in ("park","bumps"): 
    997             engineType = "Simultaneous Fit" 
     989 
     990        sim_page_uid = getattr(self.sim_page, 'uid', None) 
     991        batch_page_uid = getattr(self.batch_page, 'uid', None) 
     992 
     993        if uid == sim_page_uid: 
     994            fit_type = 'simultaneous' 
     995        elif uid == batch_page_uid: 
     996            fit_type = 'combined_batch' 
    998997        else: 
    999             engineType = "Single Fit" 
     998            fit_type = 'single' 
     999 
     1000        # if constrained fit, don't use scipy leastsq directly 
     1001        if fit_type == 'simultaneous': 
     1002            if self._fit_engine not in ("park","bumps"): 
     1003                self._on_change_engine(engine='bumps') 
     1004 
     1005 
    10001006        fitter_list = [] 
    10011007        sim_fitter = None 
    1002         is_single_fit = True 
    1003         batch_on = False 
    1004         if self.sim_page is not None and self.sim_page.uid == uid: 
     1008        if fit_type == 'simultaneous': 
    10051009            #simulatanous fit only one engine need to be created 
    1006             ## if simultaneous fit change automatically the engine to park 
    1007             if self._fit_engine not in ("park","bumps"): 
    1008                 self._on_change_engine(engine='park') 
    10091010            sim_fitter = Fit(self._fit_engine) 
    10101011            sim_fitter.fitter_id = self.sim_page.uid 
    10111012            fitter_list.append(sim_fitter) 
    1012             is_single_fit = False 
    1013             batch_on = self.sim_page.batch_on 
    1014              
    1015         self.fitproblem_count = fitproblem_count 
    1016         if self._fit_engine in ("park","bumps"): 
    1017             engineType = "Simultaneous Fit" 
    1018         else: 
    1019             engineType = "Single Fit" 
    1020          
     1013 
    10211014        self.current_pg = None 
    10221015        list_page_id = [] 
    10231016        fit_id = 0 
    1024         batch_inputs = {} 
    1025         batch_outputs = {} 
    1026         for page_id, value in self.page_finder.iteritems(): 
     1017        for page_id, page_info in self.page_finder.iteritems(): 
    10271018            # For simulfit (uid give with None), do for-loop 
    10281019            # if uid is specified (singlefit), do it only on the page. 
    1029             if engineType == "Single Fit": 
    1030                 #combine more than 1 batch page on single mode 
    1031                 if self.batch_page is None or self.batch_page.uid != uid: 
    1032                     if page_id != uid: 
    1033                         continue 
     1020            if page_id in (sim_page_uid, batch_page_uid): continue 
     1021            if fit_type == "single" and page_id != uid: continue 
     1022 
    10341023            try: 
    1035                 if value.get_scheduled() == 1: 
    1036                     value.nbr_residuals_computed = 0 
    1037                     #Get list of parameters name to fit 
    1038                     pars = [] 
    1039                     templist = [] 
     1024                if page_info.get_scheduled() == 1: 
     1025                    page_info.nbr_residuals_computed = 0 
    10401026                    page = self.fit_panel.get_page_by_id(page_id) 
    10411027                    self.set_fit_weight(uid=page.uid, 
    10421028                                     flag=page.get_weight_flag(), 
    10431029                                     is2d=page._is_2D()) 
    1044                     templist = page.get_param_list() 
    1045                     flag = page._update_paramv_on_fit() 
    1046                     if not flag: 
     1030                    if not page.param_toFit: 
     1031                        msg = "No fitting parameters for %s"%page.window_caption 
     1032                        wx.PostEvent(page.parent.parent, 
     1033                                     StatusEvent(status=msg, info="error", 
     1034                                                 type="stop")) 
     1035                        return False 
     1036                    if not page._update_paramv_on_fit(): 
    10471037                        msg = "Fitting range or parameter values are" 
    10481038                        msg += " invalid in %s" % \ 
     
    10511041                                     StatusEvent(status=msg, info="error", 
    10521042                                     type="stop")) 
    1053                         return flag 
    1054                     for element in templist: 
    1055                         name = str(element[1]) 
    1056                         pars.append(name) 
    1057                     fitproblem_list = value.values() 
     1043                        return False 
     1044 
     1045                    pars = [str(element[1]) for element in page.param_toFit] 
     1046                    fitproblem_list = page_info.values() 
    10581047                    for fitproblem in  fitproblem_list: 
    10591048                        if sim_fitter is None: 
    10601049                            fitter = Fit(self._fit_engine) 
    10611050                            fitter.fitter_id = page_id 
    1062                             self._fit_helper(fitproblem=fitproblem, 
    1063                                              pars=pars, 
    1064                                              fitter=fitter, 
    1065                                              fit_id=fit_id, 
    1066                                              batch_inputs=batch_inputs, 
    1067                                              batch_outputs=batch_outputs) 
    10681051                            fitter_list.append(fitter) 
    10691052                        else: 
    10701053                            fitter = sim_fitter 
    1071                             self._fit_helper(fitproblem=fitproblem, 
     1054                        self._add_problem_to_fit(fitproblem=fitproblem, 
    10721055                                             pars=pars, 
    10731056                                             fitter=fitter, 
    1074                                              fit_id=fit_id, 
    1075                                              batch_inputs=batch_inputs, 
    1076                                              batch_outputs=batch_outputs) 
     1057                                             fit_id=fit_id) 
    10771058                        fit_id += 1 
    10781059                    list_page_id.append(page_id) 
    1079                     current_page_id = page_id 
    1080                     value.clear_model_param() 
     1060                    page_info.clear_model_param() 
    10811061            except KeyboardInterrupt: 
    1082                 flag = True 
    10831062                msg = "Fitting terminated" 
    10841063                wx.PostEvent(self.parent, StatusEvent(status=msg, info="info", 
    10851064                                                      type="stop")) 
    1086                 return flag 
     1065                return True 
    10871066            except: 
    1088                 flag = False 
    1089                 msg = "%s error: %s" % (engineType, sys.exc_value) 
     1067                msg = "Fitting error: %s" % str(sys.exc_value) 
    10901068                wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", 
    10911069                                                      type="stop")) 
    1092                 return flag 
     1070                return False 
    10931071        ## If a thread is already started, stop it 
    10941072        #if self.calc_fit!= None and self.calc_fit.isrunning(): 
     
    11021080                                improvement_delta=0.1) 
    11031081        self._mac_sleep(0.2) 
    1104         ## perform single fit 
    1105         try: 
    1106             page = self.fit_panel.get_page_by_id(uid) 
    1107             batch_on = page.batch_on 
    1108         except: 
    1109             try: 
    1110                 #if the id cannot be found then  we deal with a self.sim_page 
    1111                 #or a self.batch_page 
    1112                 if self.sim_page is not None and uid == self.sim_page.uid: 
    1113                     batch_on = self.sim_page.batch_on 
    1114                 if self.batch_page is not None and uid == self.batch_page.uid: 
    1115                     batch_on = self.batch_page.batch_on 
    1116             except: 
    1117                 batch_on = False 
    11181082 
    11191083        # batch fit 
    1120         if batch_on: 
     1084        batch_inputs = {} 
     1085        batch_outputs = {} 
     1086        page = self.fit_panel.get_page_by_id(uid) 
     1087        if page.batch_on: 
    11211088            calc_fit = FitThread(handler=handler, 
    11221089                                 fn=fitter_list, 
     
    11291096                                 reset_flag=self.batch_reset_flag) 
    11301097        else: 
    1131             # single fit: not batch and not simul fit 
    1132             if not is_single_fit: 
    1133                 current_page_id = self.sim_page.uid 
    11341098            ## Perform more than 1 fit at the time 
    11351099            calc_fit = FitThread(handler=handler, 
     
    11411105                                    completefn=self._fit_completed, 
    11421106                                    ftol=self.ftol) 
    1143         self.fit_thread_list[current_page_id] = calc_fit 
     1107        #self.fit_thread_list[current_page_id] = calc_fit 
     1108        self.fit_thread_list[uid] = calc_fit 
    11441109        calc_fit.queue() 
     1110        calc_fit.ready(2.5) 
    11451111        msg = "Fitting is in progress..." 
    11461112        wx.PostEvent(self.parent, StatusEvent(status=msg, type="progress")) 
    11471113         
    1148         self.ready_fit(calc_fit=calc_fit) 
    1149         return flag 
    1150      
    1151     def ready_fit(self, calc_fit): 
    1152         """ 
    1153         Ready for another fit 
    1154         """ 
    1155         if self.fitproblem_count != None and self.fitproblem_count > 1: 
    1156             calc_fit.ready(2.5) 
    1157         else: 
    1158             time.sleep(0.4) 
    1159              
     1114        return True 
     1115 
    11601116    def remove_plot(self, uid, fid=None, theory=False): 
    11611117        """ 
     
    12971253                self.page_finder[uid].schedule_tofit(value) 
    12981254                 
    1299     def _fit_helper(self, fitproblem, pars, fitter, fit_id, 
    1300                     batch_inputs, batch_outputs): 
     1255    def _add_problem_to_fit(self, fitproblem, pars, fitter, fit_id): 
    13011256        """ 
    13021257        Create and set fit engine with series of data and model 
  • src/sans/perspectives/fitting/simfitpage.py

    r4e9f227 r233c121  
    138138                self.Layout() 
    139139                break 
    140         self._onAdd_constraint(None) 
     140 
     141        ## some model or parameters can be constrained 
     142        self._show_constraint() 
     143        self.sizer3.Layout() 
     144        self.Layout() 
     145        self.Refresh() 
     146        #self._onAdd_constraint(None) 
    141147              
    142148    def onFit(self, event): 
  • src/sans/fit/AbstractFitEngine.py

    r6c00702 r8d074d9  
    33#import logging 
    44import sys 
     5import math 
    56import numpy 
    6 import math 
    7 import park 
     7 
    88from sans.dataloader.data_info import Data1D 
    99from sans.dataloader.data_info import Data2D 
    10 _SMALLVALUE = 1.0e-10     
    11      
    12 class SansParameter(park.Parameter): 
    13     """ 
    14     SANS model parameters for use in the PARK fitting service. 
    15     The parameter attribute value is redirected to the underlying 
    16     parameter value in the SANS model. 
    17     """ 
    18     def __init__(self, name, model, data): 
    19         """ 
    20             :param name: the name of the model parameter 
    21             :param model: the sans model to wrap as a park model 
    22         """ 
    23         park.Parameter.__init__(self, name) 
    24         self._model, self._name = model, name 
    25         self.data = data 
    26         self.model = model 
    27         #set the value for the parameter of the given name 
    28         self.set(model.getParam(name)) 
    29           
    30     def _getvalue(self): 
    31         """ 
    32         override the _getvalue of park parameter 
    33          
    34         :return value the parameter associates with self.name 
    35          
    36         """ 
    37         return self._model.getParam(self.name) 
    38      
    39     def _setvalue(self, value): 
    40         """ 
    41         override the _setvalue pf park parameter 
    42          
    43         :param value: the value to set on a given parameter 
    44          
    45         """ 
    46         self._model.setParam(self.name, value) 
    47          
    48     value = property(_getvalue, _setvalue) 
    49      
    50     def _getrange(self): 
    51         """ 
    52         Override _getrange of park parameter 
    53         return the range of parameter 
    54         """ 
    55         #if not  self.name in self._model.getDispParamList(): 
    56         lo, hi = self._model.details[self.name][1:3] 
    57         if lo is None: lo = -numpy.inf 
    58         if hi is None: hi = numpy.inf 
    59         if lo > hi: 
    60             raise ValueError, "wrong fit range for parameters" 
    61          
    62         return lo, hi 
    63      
    64     def get_name(self): 
    65         """ 
    66         """ 
    67         return self._getname() 
    68      
    69     def _setrange(self, r): 
    70         """ 
    71         override _setrange of park parameter 
    72          
    73         :param r: the value of the range to set 
    74          
    75         """ 
    76         self._model.details[self.name][1:3] = r 
    77     range = property(_getrange, _setrange) 
    78      
    79      
    80 class Model(park.Model): 
    81     """ 
    82     PARK wrapper for SANS models. 
     10_SMALLVALUE = 1.0e-10 
     11 
     12# Note: duplicated from park 
     13class FitHandler(object): 
     14    """ 
     15    Abstract interface for fit thread handler. 
     16 
     17    The methods in this class are called by the optimizer as the fit 
     18    progresses. 
     19 
     20    Note that it is up to the optimizer to call the fit handler correctly, 
     21    reporting all status changes and maintaining the 'done' flag. 
     22    """ 
     23    done = False 
     24    """True when the fit job is complete""" 
     25    result = None 
     26    """The current best result of the fit""" 
     27 
     28    def improvement(self): 
     29        """ 
     30        Called when a result is observed which is better than previous 
     31        results from the fit. 
     32 
     33        result is a FitResult object, with parameters, #calls and fitness. 
     34        """ 
     35    def error(self, msg): 
     36        """ 
     37        Model had an error; print traceback 
     38        """ 
     39    def progress(self, current, expected): 
     40        """ 
     41        Called each cycle of the fit, reporting the current and the 
     42        expected amount of work.   The meaning of these values is 
     43        optimizer dependent, but they can be converted into a percent 
     44        complete using (100*current)//expected. 
     45 
     46        Progress is updated each iteration of the fit, whatever that 
     47        means for the particular optimization algorithm.  It is called 
     48        after any calls to improvement for the iteration so that the 
     49        update handler can control I/O bandwidth by suppressing 
     50        intermediate improvements until the fit is complete. 
     51        """ 
     52    def finalize(self): 
     53        """ 
     54        Fit is complete; best results are reported 
     55        """ 
     56    def abort(self): 
     57        """ 
     58        Fit was aborted. 
     59        """ 
     60 
     61    # TODO: not sure how these are used, but they are needed for running the fit 
     62    def update_fit(self, last=False): pass 
     63    def set_result(self, result=None): self.result = result 
     64 
     65class Model: 
     66    """ 
     67    Fit wrapper for SANS models. 
    8368    """ 
    8469    def __init__(self, sans_model, sans_data=None, **kw): 
    8570        """ 
    8671        :param sans_model: the sans model to wrap using park interface 
    87          
    88         """ 
    89         park.Model.__init__(self, **kw) 
     72 
     73        """ 
    9074        self.model = sans_model 
    9175        self.name = sans_model.name 
    9276        self.data = sans_data 
    93         #list of parameters names 
    94         self.sansp = sans_model.getParamList() 
    95         #list of park parameter 
    96         self.parkp = [SansParameter(p, sans_model, sans_data) for p in self.sansp] 
    97         #list of parameter set 
    98         self.parameterset = park.ParameterSet(sans_model.name, pars=self.parkp) 
    99         self.pars = [] 
    100    
     77 
    10178    def get_params(self, fitparams): 
    10279        """ 
    10380        return a list of value of paramter to fit 
    104          
     81 
    10582        :param fitparams: list of paramaters name to fit 
    106          
    107         """ 
    108         list_params = [] 
    109         self.pars = [] 
    110         self.pars = fitparams 
    111         for item in fitparams: 
    112             for element in self.parkp: 
    113                 if element.name == str(item): 
    114                     list_params.append(element.value) 
    115         return list_params 
    116      
     83 
     84        """ 
     85        return [self.model.getParam(k) for k in fitparams] 
     86 
    11787    def set_params(self, paramlist, params): 
    11888        """ 
    11989        Set value for parameters to fit 
    120          
     90 
    12191        :param params: list of value for parameters to fit 
    122          
    123         """ 
    124         try: 
    125             for i in range(len(self.parkp)): 
    126                 for j in range(len(paramlist)): 
    127                     if self.parkp[i].name == paramlist[j]: 
    128                         self.parkp[i].value = params[j] 
    129                         self.model.setParam(self.parkp[i].name, params[j]) 
    130         except: 
    131             raise 
    132    
     92 
     93        """ 
     94        for k,v in zip(paramlist, params): 
     95            self.model.setParam(k,v) 
     96 
     97    def set(self, **kw): 
     98        self.set_params(*zip(*kw.items())) 
     99 
    133100    def eval(self, x): 
    134101        """ 
    135102            Override eval method of park model. 
    136          
     103 
    137104            :param x: the x value used to compute a function 
    138105        """ 
     
    141108        except: 
    142109            raise 
    143          
     110 
    144111    def eval_derivs(self, x, pars=[]): 
    145112        """ 
     
    154121        instead of calling eval. 
    155122        """ 
    156         return [] 
    157  
    158      
     123        raise NotImplementedError('no derivatives available') 
     124 
     125    def __call__(self, x): 
     126        return self.eval(x) 
     127 
    159128class FitData1D(Data1D): 
    160129    """ 
     
    185154        """ 
    186155        Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy) 
     156        self.num_points = len(x) 
    187157        self.sans_data = data 
    188158        self.smearer = smearer 
     
    251221        """ 
    252222        return self.qmin, self.qmax 
    253          
     223 
     224    def size(self): 
     225        """ 
     226        Number of measurement points in data set after masking, etc. 
     227        """ 
     228        return len(self.x) 
     229 
    254230    def residuals(self, fn): 
    255231        """ 
     
    293269    def __init__(self, sans_data2d, data=None, err_data=None): 
    294270        Data2D.__init__(self, data=data, err_data=err_data) 
    295         """ 
    296             Data can be initital with a data (sans plottable) 
    297             or with vectors. 
    298         """ 
     271        # Data can be initialized with a sans plottable or with vectors. 
    299272        self.res_err_image = [] 
     273        self.num_points = 0 # will be set by set_data 
    300274        self.idx = [] 
    301275        self.qmin = None 
     
    339313        self.idx = (self.idx) & (self.mask) 
    340314        self.idx = (self.idx) & (numpy.isfinite(self.data)) 
     315        self.num_points = numpy.sum(self.idx) 
    341316 
    342317    def set_smearer(self, smearer): 
     
    372347        """ 
    373348        return self.qmin, self.qmax 
    374       
     349 
     350    def size(self): 
     351        """ 
     352        Number of measurement points in data set after masking, etc. 
     353        """ 
     354        return numpy.sum(self.idx) 
     355 
    375356    def residuals(self, fn): 
    376357        """ 
     
    409390 
    410391 
    411 class SansAssembly: 
    412     """ 
    413     Sans Assembly class a class wrapper to be call in optimizer.leastsq method 
    414     """ 
    415     def __init__(self, paramlist, model=None, data=None, fitresult=None, 
    416                  handler=None, curr_thread=None, msg_q=None): 
    417         """ 
    418         :param Model: the model wrapper fro sans -model 
    419         :param Data: the data wrapper for sans data 
    420          
    421         """ 
    422         self.model = model 
    423         self.data = data 
    424         self.paramlist = paramlist 
    425         self.msg_q = msg_q 
    426         self.curr_thread = curr_thread 
    427         self.handler = handler 
    428         self.fitresult = fitresult 
    429         self.res = [] 
    430         self.true_res = [] 
    431         self.func_name = "Functor" 
    432         self.theory = None 
    433          
    434     def chisq(self): 
    435         """ 
    436         Calculates chi^2 
    437          
    438         :param params: list of parameter values 
    439          
    440         :return: chi^2 
    441          
    442         """ 
    443         total = 0 
    444         for item in self.true_res: 
    445             total += item * item 
    446         if len(self.true_res) == 0: 
    447             return None 
    448         return total / len(self.true_res) 
    449      
    450     def __call__(self, params): 
    451         """ 
    452             Compute residuals 
    453             :param params: value of parameters to fit 
    454         """ 
    455         #import thread 
    456         self.model.set_params(self.paramlist, params) 
    457         #print "params", params 
    458         self.true_res, theory = self.data.residuals(self.model.eval) 
    459         self.theory = copy.deepcopy(theory) 
    460         # check parameters range 
    461         if self.check_param_range(): 
    462             # if the param value is outside of the bound 
    463             # just silent return res = inf 
    464             return self.res 
    465         self.res = self.true_res 
    466          
    467         if self.fitresult is not None: 
    468             self.fitresult.set_model(model=self.model) 
    469             self.fitresult.residuals = self.true_res 
    470             self.fitresult.iterations += 1 
    471             self.fitresult.theory = theory 
    472             
    473             #fitness = self.chisq(params=params) 
    474             fitness = self.chisq() 
    475             self.fitresult.pvec = params 
    476             self.fitresult.set_fitness(fitness=fitness) 
    477             if self.msg_q is not None: 
    478                 self.msg_q.put(self.fitresult) 
    479                  
    480             if self.handler is not None: 
    481                 self.handler.set_result(result=self.fitresult) 
    482                 self.handler.update_fit() 
    483  
    484             if self.curr_thread != None: 
    485                 try: 
    486                     self.curr_thread.isquit() 
    487                 except: 
    488                     #msg = "Fitting: Terminated...       Note: Forcing to stop " 
    489                     #msg += "fitting may cause a 'Functor error message' " 
    490                     #msg += "being recorded in the log file....." 
    491                     #self.handler.stop(msg) 
    492                     raise 
    493           
    494         return self.res 
    495      
    496     def check_param_range(self): 
    497         """ 
    498         Check the lower and upper bound of the parameter value 
    499         and set res to the inf if the value is outside of the 
    500         range 
    501         :limitation: the initial values must be within range. 
    502         """ 
    503  
    504         #time.sleep(0.01) 
    505         is_outofbound = False 
    506         # loop through the fit parameters 
    507         for p in self.model.parameterset: 
    508             param_name = p.get_name() 
    509             if param_name in self.paramlist: 
    510                  
    511                 # if the range was defined, check the range 
    512                 if numpy.isfinite(p.range[0]): 
    513                     if p.value == 0: 
    514                         # This value works on Scipy 
    515                         # Do not change numbers below 
    516                         value = _SMALLVALUE 
    517                     else: 
    518                         value = p.value 
    519                     # For leastsq, it needs a bit step back from the boundary 
    520                     val = p.range[0] - value * _SMALLVALUE 
    521                     if p.value < val: 
    522                         self.res *= 1e+6 
    523                          
    524                         is_outofbound = True 
    525                         break 
    526                 if numpy.isfinite(p.range[1]): 
    527                     # This value works on Scipy 
    528                     # Do not change numbers below 
    529                     if p.value == 0: 
    530                         value = _SMALLVALUE 
    531                     else: 
    532                         value = p.value 
    533                     # For leastsq, it needs a bit step back from the boundary 
    534                     val = p.range[1] + value * _SMALLVALUE 
    535                     if p.value > val: 
    536                         self.res *= 1e+6 
    537                         is_outofbound = True 
    538                         break 
    539  
    540         return is_outofbound 
    541      
    542      
     392 
    543393class FitEngine: 
    544394    def __init__(self): 
     
    571421         
    572422        """ 
    573         if model == None: 
    574             raise ValueError, "AbstractFitEngine: Need to set model to fit" 
    575          
    576         new_model = model 
     423        if not pars: 
     424            raise ValueError("no fitting parameters") 
     425 
     426        if model is None: 
     427            raise ValueError("no model to fit") 
     428 
    577429        if not issubclass(model.__class__, Model): 
    578             new_model = Model(model, data) 
    579          
    580         if len(constraints) > 0: 
    581             for constraint in constraints: 
    582                 name, value = constraint 
    583                 try: 
    584                     new_model.parameterset[str(name)].set(str(value)) 
    585                 except: 
    586                     msg = "Fit Engine: Error occurs when setting the constraint" 
    587                     msg += " %s for parameter %s " % (value, name) 
    588                     raise ValueError, msg 
    589                  
    590         if len(pars) > 0: 
    591             temp = [] 
    592             for item in pars: 
    593                 if item in new_model.model.getParamList(): 
    594                     temp.append(item) 
    595                     self.param_list.append(item) 
    596                 else: 
    597                      
    598                     msg = "wrong parameter %s used " % str(item) 
    599                     msg += "to set model %s. Choose " % str(new_model.model.name) 
    600                     msg += "parameter name within %s" % \ 
    601                                 str(new_model.model.getParamList()) 
    602                     raise ValueError, msg 
    603                
    604             #A fitArrange is already created but contains data_list only at id 
    605             if self.fit_arrange_dict.has_key(id): 
    606                 self.fit_arrange_dict[id].set_model(new_model) 
    607                 self.fit_arrange_dict[id].pars = pars 
    608             else: 
    609             #no fitArrange object has been create with this id 
    610                 fitproblem = FitArrange() 
    611                 fitproblem.set_model(new_model) 
    612                 fitproblem.pars = pars 
    613                 self.fit_arrange_dict[id] = fitproblem 
    614                 vals = [] 
    615                 for name in pars: 
    616                     vals.append(new_model.model.getParam(name)) 
    617                 self.fit_arrange_dict[id].vals = vals 
    618         else: 
    619             raise ValueError, "park_integration:missing parameters" 
    620      
     430            model = Model(model, data) 
     431 
     432        sasmodel = model.model 
     433        available_parameters = sasmodel.getParamList() 
     434        for p in pars: 
     435            if p not in available_parameters: 
     436                raise ValueError("parameter %s not available in model %s; use one of [%s] instead" 
     437                                 %(p, sasmodel.name, ", ".join(available_parameters))) 
     438 
     439        if id not in self.fit_arrange_dict: 
     440            self.fit_arrange_dict[id] = FitArrange() 
     441 
     442        self.fit_arrange_dict[id].set_model(model) 
     443        self.fit_arrange_dict[id].pars = pars 
     444        self.fit_arrange_dict[id].vals = [sasmodel.getParam(name) for name in pars] 
     445        self.fit_arrange_dict[id].constraints = constraints 
     446 
     447        self.param_list.extend(pars) 
     448 
    621449    def set_data(self, data, id, smearer=None, qmin=None, qmax=None): 
    622450        """ 
     
    700528        self.vals = [] 
    701529        self.selected = 0 
    702          
     530 
    703531    def set_model(self, model): 
    704532        """ 
     
    752580        """ 
    753581        return self.selected 
    754      
    755      
    756 IS_MAC = True 
    757 if sys.platform.count("win32") > 0: 
    758     IS_MAC = False 
    759  
    760582 
    761583class FResult(object): 
     
    765587    def __init__(self, model=None, param_list=None, data=None): 
    766588        self.calls = None 
    767         self.pars = [] 
    768589        self.fitness = None 
    769590        self.chisqr = None 
     
    776597        self.residuals = [] 
    777598        self.index = [] 
    778         self.parameters = None 
    779         self.is_mac = IS_MAC 
    780599        self.model = model 
    781600        self.data = data 
     
    803622        if self.pvec == None and self.model is None and self.param_list is None: 
    804623            return "No results" 
    805         n = len(self.model.parameterset) 
    806          
    807         result_param = zip(xrange(n), self.model.parameterset) 
    808         msg1 = ["[Iteration #: %s ]" % self.iterations] 
    809         msg3 = ["=== goodness of fit: %s ===" % (str(self.fitness))] 
    810         if not self.is_mac: 
    811             msg2 = ["P%-3d  %s......|.....%s" % \ 
    812                 (p[0], p[1], p[1].value)\ 
    813                   for p in result_param if p[1].name in self.param_list] 
    814             msg = msg1 + msg3 + msg2 
    815         else: 
    816             msg = msg1 + msg3 
    817         msg = "\n".join(msg) 
    818         return msg 
     624 
     625        sasmodel = self.model.model 
     626        pars = enumerate(sasmodel.getParamList()) 
     627        msg1 = "[Iteration #: %s ]" % self.iterations 
     628        msg3 = "=== goodness of fit: %s ===" % (str(self.fitness)) 
     629        msg2 = ["P%-3d  %s......|.....%s" % (i, v, sasmodel.getParam(v)) 
     630                for i,v in pars if v in self.param_list] 
     631        msg = [msg1, msg3] + msg2 
     632        return "\n".join(msg) 
    819633     
    820634    def print_summary(self): 
    821635        """ 
    822636        """ 
    823         print self 
     637        print str(self) 
  • src/sans/fit/Fitting.py

    r5777106 re3efa6b3  
    88from sans.fit.ScipyFitting import ScipyFit 
    99from sans.fit.ParkFitting import ParkFit 
     10from sans.fit.BumpsFitting import BumpsFit 
    1011 
     12ENGINES={ 
     13    'scipy': ScipyFit, 
     14    'park': ParkFit, 
     15    'bumps': BumpsFit, 
     16} 
    1117 
    1218class Fit(object): 
     
    2632         
    2733    """   
    28     def __init__(self, engine='scipy'): 
     34    def __init__(self, engine='scipy', *args, **kw): 
    2935        """ 
    3036        """ 
     
    3238        self._engine = None 
    3339        self.fitter_id = None 
    34         self.set_engine(engine) 
     40        self.set_engine(engine, *args, **kw) 
    3541           
    3642    def __setattr__(self, name, value): 
     
    4955            self.__dict__[name] = value 
    5056                 
    51     def set_engine(self, word): 
     57    def set_engine(self, word, *args, **kw): 
    5258        """ 
    5359        Select the type of Fit  
     
    5965              
    6066        """ 
    61         if word == "scipy": 
    62             self._engine = ScipyFit() 
    63         elif word == "park": 
    64             self._engine = ParkFit() 
    65         else: 
    66             raise ValueError, "enter the keyword scipy or park" 
     67        try: 
     68            self._engine = ENGINES[word](*args, **kw) 
     69        except KeyError, exc: 
     70            raise KeyError("fit engine should be one of scipy, park or bumps") 
    6771 
    6872    def fit(self, msg_q=None, q=None, handler=None,  
  • src/sans/fit/Loader.py

    r5777106 r6fe5100  
    88    This class is loading values from given file or value giving by the user 
    99    """ 
    10      
    1110    def __init__(self, x=None, y=None, dx=None, dy=None): 
     11        raise NotImplementedError("a code search shows that this code is not active, and you are not seeing this message") 
    1212        # variable to store loaded values 
    1313        self.x = x 
  • src/sans/fit/ParkFitting.py

    r9d6d5ba r8d074d9  
    2424from sans.fit.AbstractFitEngine import FitEngine 
    2525from sans.fit.AbstractFitEngine import FResult 
    26    
     26 
     27class SansParameter(park.Parameter): 
     28    """ 
     29    SANS model parameters for use in the PARK fitting service. 
     30    The parameter attribute value is redirected to the underlying 
     31    parameter value in the SANS model. 
     32    """ 
     33    def __init__(self, name, model, data): 
     34        """ 
     35            :param name: the name of the model parameter 
     36            :param model: the sans model to wrap as a park model 
     37        """ 
     38        park.Parameter.__init__(self, name) 
     39        #self._model, self._name = model, name 
     40        self.data = data 
     41        self.model = model 
     42        #set the value for the parameter of the given name 
     43        self.set(model.getParam(name)) 
     44 
     45        # TODO: model is missing parameter ranges for dispersion parameters 
     46        if name not in model.details: 
     47            #print "setting details for",name 
     48            model.details[name] = ["", None, None] 
     49 
     50    def _getvalue(self): 
     51        """ 
     52        override the _getvalue of park parameter 
     53 
     54        :return value the parameter associates with self.name 
     55 
     56        """ 
     57        return self.model.getParam(self.name) 
     58 
     59    def _setvalue(self, value): 
     60        """ 
     61        override the _setvalue pf park parameter 
     62 
     63        :param value: the value to set on a given parameter 
     64 
     65        """ 
     66        self.model.setParam(self.name, value) 
     67 
     68    value = property(_getvalue, _setvalue) 
     69 
     70    def _getrange(self): 
     71        """ 
     72        Override _getrange of park parameter 
     73        return the range of parameter 
     74        """ 
     75        #if not  self.name in self._model.getDispParamList(): 
     76        lo, hi = self.model.details[self.name][1:3] 
     77        if lo is None: lo = -numpy.inf 
     78        if hi is None: hi = numpy.inf 
     79        if lo > hi: 
     80            raise ValueError, "wrong fit range for parameters" 
     81 
     82        return lo, hi 
     83 
     84    def get_name(self): 
     85        """ 
     86        """ 
     87        return self._getname() 
     88 
     89    def _setrange(self, r): 
     90        """ 
     91        override _setrange of park parameter 
     92 
     93        :param r: the value of the range to set 
     94 
     95        """ 
     96        self.model.details[self.name][1:3] = r 
     97    range = property(_getrange, _setrange) 
     98 
     99 
     100class ParkModel(park.Model): 
     101    """ 
     102    PARK wrapper for SANS models. 
     103    """ 
     104    def __init__(self, sans_model, sans_data=None, **kw): 
     105        """ 
     106        :param sans_model: the sans model to wrap using park interface 
     107 
     108        """ 
     109        park.Model.__init__(self, **kw) 
     110        self.model = sans_model 
     111        self.name = sans_model.name 
     112        self.data = sans_data 
     113        #list of parameters names 
     114        self.sansp = sans_model.getParamList() 
     115        #list of park parameter 
     116        self.parkp = [SansParameter(p, sans_model, sans_data) for p in self.sansp] 
     117        #list of parameter set 
     118        self.parameterset = park.ParameterSet(sans_model.name, pars=self.parkp) 
     119        self.pars = [] 
     120 
     121    def get_params(self, fitparams): 
     122        """ 
     123        return a list of value of paramter to fit 
     124 
     125        :param fitparams: list of paramaters name to fit 
     126 
     127        """ 
     128        list_params = [] 
     129        self.pars = fitparams 
     130        for item in fitparams: 
     131            for element in self.parkp: 
     132                if element.name == str(item): 
     133                    list_params.append(element.value) 
     134        return list_params 
     135 
     136    def set_params(self, paramlist, params): 
     137        """ 
     138        Set value for parameters to fit 
     139 
     140        :param params: list of value for parameters to fit 
     141 
     142        """ 
     143        try: 
     144            for i in range(len(self.parkp)): 
     145                for j in range(len(paramlist)): 
     146                    if self.parkp[i].name == paramlist[j]: 
     147                        self.parkp[i].value = params[j] 
     148                        self.model.setParam(self.parkp[i].name, params[j]) 
     149        except: 
     150            raise 
     151 
     152    def eval(self, x): 
     153        """ 
     154            Override eval method of park model. 
     155 
     156            :param x: the x value used to compute a function 
     157        """ 
     158        try: 
     159            return self.model.evalDistribution(x) 
     160        except: 
     161            raise 
     162 
     163    def eval_derivs(self, x, pars=[]): 
     164        """ 
     165        Evaluate the model and derivatives wrt pars at x. 
     166 
     167        pars is a list of the names of the parameters for which derivatives 
     168        are desired. 
     169 
     170        This method needs to be specialized in the model to evaluate the 
     171        model function.  Alternatively, the model can implement is own 
     172        version of residuals which calculates the residuals directly 
     173        instead of calling eval. 
     174        """ 
     175        return [] 
     176 
     177 
    27178class SansFitResult(fitresult.FitResult): 
    28179    def __init__(self, *args, **kwrds): 
     
    244395        return fitpars 
    245396     
    246     def all_results(self, result): 
     397    def extend_results_with_calculated_parameters(self, result): 
    247398        """ 
    248399        Extend result from the fit with the calculated parameters. 
     
    292443                # dividing residuals by N in order to be consistent with Scipy 
    293444                m.chisq = numpy.sum(m.residuals**2/N)  
    294                 resid.append(m.weight*m.residuals/math.sqrt(N)) 
     445                resid.append(m.weight*m.residuals) 
    295446        self.residuals = numpy.hstack(resid) 
    296447        N = len(self.residuals) 
    297448        self.degrees_of_freedom = N-k if N>k else 1 
    298449        self.chisq = numpy.sum(self.residuals**2) 
    299         return self.chisq 
     450        return self.chisq/self.degrees_of_freedom 
    300451     
    301452class ParkFit(FitEngine): 
     
    354505            if fproblem.get_to_fit() == 1: 
    355506                fitproblems.append(fproblem) 
    356         if len(fitproblems) == 0:  
     507        if len(fitproblems) == 0: 
    357508            raise RuntimeError, "No Assembly scheduled for Park fitting." 
    358             return 
    359509        for item in fitproblems: 
    360             parkmodel = item.get_model() 
     510            model = item.get_model() 
     511            parkmodel = ParkModel(model.model, model.data) 
     512            parkmodel.pars = item.pars 
    361513            if reset_flag: 
    362514                # reset the initial value; useful for batch 
     
    364516                    ind = item.pars.index(name) 
    365517                    parkmodel.model.setParam(name, item.vals[ind]) 
     518 
     519            # set the constraints into the model 
     520            for p,v in item.constraints: 
     521                parkmodel.parameterset[str(p)].set(str(v)) 
    366522             
    367523            for p in parkmodel.parameterset: 
    368524                ## does not allow status change for constraint parameters 
    369525                if p.status != 'computed': 
    370                     if p.get_name()in item.pars: 
     526                    if p.get_name() in item.pars: 
    371527                        ## make parameters selected for  
    372528                        #fit will be between boundaries 
     
    383539    def fit(self, msg_q=None,  
    384540            q=None, handler=None, curr_thread=None,  
    385                                         ftol=1.49012e-8, reset_flag=False): 
     541            ftol=1.49012e-8, reset_flag=False): 
    386542        """ 
    387543        Performs fit with park.fit module.It can  perform fit with one model 
     
    407563        localfit = SansFitSimplex() 
    408564        localfit.ftol = ftol 
    409          
     565        localfit.xtol = 1e-6 
     566 
    410567        # See `park.fitresult.FitHandler` for details. 
    411568        fitter = SansFitMC(localfit=localfit, start_points=1) 
     
    416573        try: 
    417574            result = fit.fit(self.problem, fitter=fitter, handler=handler) 
    418             self.problem.all_results(result) 
     575            self.problem.extend_results_with_calculated_parameters(result) 
    419576             
    420577        except LinAlgError: 
    421578            raise ValueError, "SVD did not converge" 
     579 
     580        if result is None: 
     581            raise RuntimeError("park did not return a fit result") 
    422582     
    423583        for m in self.problem.parts: 
     
    427587            small_result.theory = theory 
    428588            small_result.residuals = residuals 
    429             small_result.pvec = [] 
    430             small_result.cov = [] 
    431             small_result.stderr = [] 
    432             small_result.param_list = [] 
    433             small_result.residuals = m.residuals 
    434             if result is not None: 
    435                 for p in result.parameters: 
    436                     if p.data.name == small_result.data.name and \ 
    437                             p.model.name == small_result.model.name: 
    438                         small_result.index = m.data.idx 
    439                         small_result.fitness = result.fitness 
    440                         small_result.pvec.append(p.value) 
    441                         small_result.stderr.append(p.stderr) 
    442                         name_split = p.name.split('.') 
    443                         name = name_split[1].strip() 
    444                         if len(name_split) > 2: 
    445                             name += '.' + name_split[2].strip() 
    446                         small_result.param_list.append(name) 
     589            small_result.index = m.data.idx 
     590            small_result.fitness = result.fitness 
     591 
     592            # Extract the parameters that are part of this model; make sure 
     593            # they match the fitted parameters for this model, and place them 
     594            # in the same order as they occur in the model. 
     595            pars = {} 
     596            for p in result.parameters: 
     597                #if p.data.name == small_result.data.name and 
     598                if p.model.name == small_result.model.name: 
     599                    model_name, par_name = p.name.split('.', 1) 
     600                    pars[par_name] = (p.value, p.stderr) 
     601            #assert len(pars.keys()) == len(m.model.pars) 
     602            v,dv = zip(*[pars[p] for p in m.model.pars]) 
     603            small_result.pvec = v 
     604            small_result.stderr = dv 
     605            small_result.param_list = m.model.pars 
     606 
     607            # normalize chisq by degrees of freedom 
     608            dof = len(small_result.residuals)-len(small_result.pvec) 
     609            small_result.fitness = numpy.sum(residuals**2)/dof 
     610 
    447611            result_list.append(small_result)     
    448612        if q != None: 
  • src/sans/fit/ScipyFitting.py

    r5777106 r8d074d9  
    1  
    2  
    31""" 
    42ScipyFitting module contains FitArrange , ScipyFit, 
     
    64simple fit with scipy optimizer. 
    75""" 
     6import sys 
     7import copy 
    88 
    99import numpy  
    10 import sys 
    11  
    1210 
    1311from sans.fit.AbstractFitEngine import FitEngine 
    14 from sans.fit.AbstractFitEngine import SansAssembly 
    15 from sans.fit.AbstractFitEngine import FitAbort 
    16 from sans.fit.AbstractFitEngine import Model 
    17 from sans.fit.AbstractFitEngine import FResult  
     12from sans.fit.AbstractFitEngine import FResult 
     13 
     14class SansAssembly: 
     15    """ 
     16    Sans Assembly class a class wrapper to be call in optimizer.leastsq method 
     17    """ 
     18    def __init__(self, paramlist, model=None, data=None, fitresult=None, 
     19                 handler=None, curr_thread=None, msg_q=None): 
     20        """ 
     21        :param Model: the model wrapper fro sans -model 
     22        :param Data: the data wrapper for sans data 
     23 
     24        """ 
     25        self.model = model 
     26        self.data = data 
     27        self.paramlist = paramlist 
     28        self.msg_q = msg_q 
     29        self.curr_thread = curr_thread 
     30        self.handler = handler 
     31        self.fitresult = fitresult 
     32        self.res = [] 
     33        self.true_res = [] 
     34        self.func_name = "Functor" 
     35        self.theory = None 
     36 
     37    def chisq(self): 
     38        """ 
     39        Calculates chi^2 
     40 
     41        :param params: list of parameter values 
     42 
     43        :return: chi^2 
     44 
     45        """ 
     46        total = 0 
     47        for item in self.true_res: 
     48            total += item * item 
     49        if len(self.true_res) == 0: 
     50            return None 
     51        return total / (len(self.true_res) - len(self.paramlist)) 
     52 
     53    def __call__(self, params): 
     54        """ 
     55            Compute residuals 
     56            :param params: value of parameters to fit 
     57        """ 
     58        #import thread 
     59        self.model.set_params(self.paramlist, params) 
     60        #print "params", params 
     61        self.true_res, theory = self.data.residuals(self.model.eval) 
     62        self.theory = copy.deepcopy(theory) 
     63        # check parameters range 
     64        if self.check_param_range(): 
     65            # if the param value is outside of the bound 
     66            # just silent return res = inf 
     67            return self.res 
     68        self.res = self.true_res 
     69 
     70        if self.fitresult is not None: 
     71            self.fitresult.set_model(model=self.model) 
     72            self.fitresult.residuals = self.true_res 
     73            self.fitresult.iterations += 1 
     74            self.fitresult.theory = theory 
     75 
     76            #fitness = self.chisq(params=params) 
     77            fitness = self.chisq() 
     78            self.fitresult.pvec = params 
     79            self.fitresult.set_fitness(fitness=fitness) 
     80            if self.msg_q is not None: 
     81                self.msg_q.put(self.fitresult) 
     82 
     83            if self.handler is not None: 
     84                self.handler.set_result(result=self.fitresult) 
     85                self.handler.update_fit() 
     86 
     87            if self.curr_thread != None: 
     88                try: 
     89                    self.curr_thread.isquit() 
     90                except: 
     91                    #msg = "Fitting: Terminated...       Note: Forcing to stop " 
     92                    #msg += "fitting may cause a 'Functor error message' " 
     93                    #msg += "being recorded in the log file....." 
     94                    #self.handler.stop(msg) 
     95                    raise 
     96 
     97        return self.res 
     98 
     99    def check_param_range(self): 
     100        """ 
     101        Check the lower and upper bound of the parameter value 
     102        and set res to the inf if the value is outside of the 
     103        range 
     104        :limitation: the initial values must be within range. 
     105        """ 
     106 
     107        #time.sleep(0.01) 
     108        is_outofbound = False 
     109        # loop through the fit parameters 
     110        model = self.model.model 
     111        for p in self.paramlist: 
     112            value = model.getParam(p) 
     113            low,high = model.details[p][1:3] 
     114            if low is not None and numpy.isfinite(low): 
     115                if p.value == 0: 
     116                    # This value works on Scipy 
     117                    # Do not change numbers below 
     118                    value = _SMALLVALUE 
     119                # For leastsq, it needs a bit step back from the boundary 
     120                val = low - value * _SMALLVALUE 
     121                if value < val: 
     122                    self.res *= 1e+6 
     123                    is_outofbound = True 
     124                    break 
     125            if high is not None and numpy.isfinite(high): 
     126                # This value works on Scipy 
     127                # Do not change numbers below 
     128                if value == 0: 
     129                    value = _SMALLVALUE 
     130                # For leastsq, it needs a bit step back from the boundary 
     131                val = high + value * _SMALLVALUE 
     132                if value > val: 
     133                    self.res *= 1e+6 
     134                    is_outofbound = True 
     135                    break 
     136 
     137        return is_outofbound 
    18138 
    19139class ScipyFit(FitEngine): 
     
    50170        """ 
    51171        FitEngine.__init__(self) 
    52         self.fit_arrange_dict = {} 
    53         self.param_list = [] 
    54172        self.curr_thread = None 
    55173    #def fit(self, *args, **kw): 
     
    68186            msg = "Scipy can't fit more than a single fit problem at a time." 
    69187            raise RuntimeError, msg 
    70             return 
    71         elif len(fitproblem) == 0 :  
     188        elif len(fitproblem) == 0 : 
    72189            raise RuntimeError, "No Assembly scheduled for Scipy fitting." 
    73             return 
    74190        model = fitproblem[0].get_model() 
    75191        if reset_flag: 
     
    87203         
    88204        # Check the initial value if it is within range 
    89         self._check_param_range(model) 
     205        _check_param_range(model.model, self.param_list) 
    90206         
    91         result = FResult(model=model, data=data, param_list=self.param_list) 
    92         result.pars = fitproblem[0].pars 
     207        result = FResult(model=model.model, data=data, param_list=self.param_list) 
    93208        result.fitter_id = self.fitter_id 
    94209        if handler is not None: 
    95210            handler.set_result(result=result) 
     211        functor = SansAssembly(paramlist=self.param_list, 
     212                               model=model, 
     213                               data=data, 
     214                               handler=handler, 
     215                               fitresult=result, 
     216                               curr_thread=curr_thread, 
     217                               msg_q=msg_q) 
    96218        try: 
    97219            # This import must be here; otherwise it will be confused when more 
     
    99221            from scipy import optimize 
    100222             
    101             functor = SansAssembly(paramlist=self.param_list,  
    102                                    model=model,  
    103                                    data=data, 
    104                                     handler=handler, 
    105                                     fitresult=result, 
    106                                      curr_thread=curr_thread, 
    107                                      msg_q=msg_q) 
    108223            out, cov_x, _, mesg, success = optimize.leastsq(functor, 
    109224                                            model.get_params(self.param_list), 
    110                                                     ftol=ftol, 
    111                                                     full_output=1) 
     225                                            ftol=ftol, 
     226                                            full_output=1) 
    112227        except: 
    113228            if hasattr(sys, 'last_type') and sys.last_type == KeyboardInterrupt: 
     
    142257 
    143258         
    144     def _check_param_range(self, model): 
    145         """ 
    146         Check parameter range and set the initial value inside  
    147         if it is out of range. 
    148          
    149         : model: park model object 
    150         """ 
    151         is_outofbound = False 
    152         # loop through parameterset 
    153         for p in model.parameterset:         
    154             param_name = p.get_name() 
    155             # proceed only if the parameter name is in the list of fitting 
    156             if param_name in self.param_list: 
    157                 # if the range was defined, check the range 
    158                 if numpy.isfinite(p.range[0]): 
    159                     if p.value <= p.range[0]:  
    160                         # 10 % backing up from the border if not zero 
    161                         # for Scipy engine to work properly. 
    162                         shift = self._get_zero_shift(p.range[0]) 
    163                         new_value = p.range[0] + shift 
    164                         p.value =  new_value 
    165                         is_outofbound = True 
    166                 if numpy.isfinite(p.range[1]): 
    167                     if p.value >= p.range[1]: 
    168                         shift = self._get_zero_shift(p.range[1]) 
    169                         # 10 % backing up from the border if not zero 
    170                         # for Scipy engine to work properly. 
    171                         new_value = p.range[1] - shift 
    172                         # Check one more time if the new value goes below 
    173                         # the low bound, If so, re-evaluate the value  
    174                         # with the mean of the range. 
    175                         if numpy.isfinite(p.range[0]): 
    176                             if new_value < p.range[0]: 
    177                                 new_value = (p.range[0] + p.range[1]) / 2.0 
    178                         # Todo:  
    179                         # Need to think about when both min and max are same. 
    180                         p.value =  new_value 
    181                         is_outofbound = True 
    182                          
    183         return is_outofbound 
    184      
    185     def _get_zero_shift(self, range): 
    186         """ 
    187         Get 10% shift of the param value = 0 based on the range value 
    188          
    189         : param range: min or max value of the bounds 
    190         """ 
    191         if range == 0: 
    192             shift = 0.1 
    193         else: 
    194             shift = 0.1 * range 
    195              
    196         return shift 
    197      
     259def _check_param_range(model, param_list): 
     260    """ 
     261    Check parameter range and set the initial value inside 
     262    if it is out of range. 
     263 
     264    : model: park model object 
     265    """ 
     266    # loop through parameterset 
     267    for p in param_list: 
     268        value = model.getParam(p) 
     269        low,high = model.details.setdefault(p,["",None,None])[1:3] 
     270        # if the range was defined, check the range 
     271        if low is not None and value <= low: 
     272            value = low + _get_zero_shift(low) 
     273        if high is not None and value > high: 
     274            value = high - _get_zero_shift(high) 
     275            # Check one more time if the new value goes below 
     276            # the low bound, If so, re-evaluate the value 
     277            # with the mean of the range. 
     278            if low is not None and value < low: 
     279                value = 0.5 * (low+high) 
     280        model.setParam(p, value) 
     281 
     282def _get_zero_shift(limit): 
     283    """ 
     284    Get 10% shift of the param value = 0 based on the range value 
     285 
     286    : param range: min or max value of the bounds 
     287    """ 
     288    return 0.1 * (limit if limit != 0.0 else 1.0) 
     289 
    198290     
    199291#def profile(fn, *args, **kw): 
  • src/sans/fit/__init__.py

    r5777106 r6fe5100  
     1from .AbstractFitEngine import FitHandler 
  • src/sans/perspectives/fitting/basepage.py

    r116e1a7 r5bf0331  
    835835            infor = "warning" 
    836836        else: 
    837             msg = "Error was occured " 
    838             msg += ": No valid parameter values to paste from the clipboard..." 
     837            msg = "Error occured: " 
     838            msg += "No valid parameter values to paste from the clipboard..." 
    839839            infor = "error" 
    840840            wx.PostEvent(self._manager.parent, 
     
    21832183                else: 
    21842184                    tcrtl.SetBackgroundColour("pink") 
    2185                     msg = "Model Error:wrong value entered: %s" % sys.exc_value 
     2185                    msg = "Model Error: wrong value entered: %s" % sys.exc_value 
    21862186                    wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    21872187                    return 
    21882188            except: 
    21892189                tcrtl.SetBackgroundColour("pink") 
    2190                 msg = "Model Error:wrong value entered: %s" % sys.exc_value 
     2190                msg = "Model Error: wrong value entered: %s" % sys.exc_value 
    21912191                wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    21922192                return 
     
    21992199                        #is_modified = True 
    22002200                else: 
    2201                     msg = "Cannot Plot :No npts in that Qrange!!!  " 
     2201                    msg = "Cannot plot: No points in Q range!!!  " 
    22022202                    wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    22032203        else: 
    22042204            tcrtl.SetBackgroundColour("pink") 
    2205             msg = "Model Error:wrong value entered!!!" 
     2205            msg = "Model Error: wrong value entered!!!" 
    22062206            wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    22072207        self.save_current_state() 
     
    22402240                else: 
    22412241                    tcrtl.SetBackgroundColour("pink") 
    2242                     msg = "Model Error:wrong value entered: %s" % sys.exc_value 
     2242                    msg = "Model Error: wrong value entered: %s" % sys.exc_value 
    22432243                    wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    22442244                    return 
    22452245            except: 
    22462246                tcrtl.SetBackgroundColour("pink") 
    2247                 msg = "Model Error:wrong value entered: %s" % sys.exc_value 
     2247                msg = "Model Error: wrong value entered: %s" % sys.exc_value 
    22482248                wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    22492249                return 
     
    22562256                        is_modified = True 
    22572257                else: 
    2258                     msg = "Cannot Plot :No npts in that Qrange!!!  " 
     2258                    msg = "Cannot Plot: No points in Q range!!!  " 
    22592259                    wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    22602260        else: 
    22612261            tcrtl.SetBackgroundColour("pink") 
    2262             msg = "Model Error:wrong value entered!!!" 
     2262            msg = "Model Error: wrong value entered!!!" 
    22632263            wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    22642264        self.save_current_state() 
     
    24312431                self.qmax.SetBackgroundColour("pink") 
    24322432                self.qmax.Refresh() 
    2433                 msg = "Npts of Data Error :" 
    2434                 msg += "No or too little npts of %s." % data.name 
     2433                msg = "Data Error: " 
     2434                msg += "Too few points in %s." % data.name 
    24352435                wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    24362436                self.fitrange = False 
     
    24662466                self.qmax.SetBackgroundColour("pink") 
    24672467                self.qmax.Refresh() 
    2468                 msg = "Npts of Data Error :" 
    2469                 msg += "No or too little npts of %s." % data.name 
     2468                msg = "Data Error: " 
     2469                msg += "Too few points in %s." % data.name 
    24702470                wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    24712471                self.fitrange = False 
     
    25182518                                            
    25192519                        except: 
    2520                             msg = "Wrong Fit parameter range entered " 
     2520                            msg = "Wrong fit parameter range entered" 
    25212521                            wx.PostEvent(self._manager.parent, 
    25222522                                         StatusEvent(status=msg)) 
  • src/sans/perspectives/fitting/console.py

    r5777106 r644ca73  
    55import time 
    66import wx 
    7 import park 
    8 from park.fitresult import FitHandler 
     7from sans.fit import FitHandler 
    98 
    109class ConsoleUpdate(FitHandler): 
     
    8887        Print result object 
    8988        """ 
    90         msg = " \n %s \n" % self.result.__str__() 
     89        msg = " \n %s \n" % str(self.result) 
    9190        wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    9291                      
     
    137136        self.fit_duration += self.elapsed_time 
    138137        str_time = time.strftime("%a, %d %b %Y %H:%M:%S ", time.localtime(t1)) 
    139         UPDATE_INTERVAL = 0.5 
     138        UPDATE_INTERVAL = 5.0 
    140139        u_flag = False 
    141140        if self.fit_duration >= UPDATE_INTERVAL: 
  • src/sans/perspectives/fitting/fit_thread.py

    ra855fec re3efa6b3  
    1818     
    1919    def __init__(self,  
    20                   fn, 
    21                   page_id, 
    22                    handler, 
    23                     batch_outputs, 
    24                     batch_inputs=None,              
    25                   pars=None, 
     20                 fn, 
     21                 page_id, 
     22                 handler, 
     23                 batch_outputs, 
     24                 batch_inputs=None, 
     25                 pars=None, 
    2626                 completefn = None, 
    2727                 updatefn   = None, 
     
    3030                 ftol       = None, 
    3131                 reset_flag = False): 
    32         CalcThread.__init__(self,completefn, 
     32        CalcThread.__init__(self, 
     33                 completefn, 
    3334                 updatefn, 
    3435                 yieldtime, 
     
    8081                list_map_get_attr.append(map_getattr) 
    8182            #from multiprocessing import Pool 
    82             inputs = zip(list_map_get_attr,self.fitter, list_fit_function, 
    83                           list_q, list_q, list_handler,list_curr_thread,list_ftol, 
     83            inputs = zip(list_map_get_attr, self.fitter, list_fit_function, 
     84                         list_q, list_q, list_handler,list_curr_thread,list_ftol, 
    8485                         list_reset_flag) 
    8586            result =  map(map_apply, inputs) 
     
    8788            self.complete(result=result, 
    8889                          batch_inputs=self.batch_inputs, 
    89                            batch_outputs=self.batch_outputs, 
     90                          batch_outputs=self.batch_outputs, 
    9091                          page_id=self.page_id, 
    9192                          pars = self.pars, 
  • src/sans/perspectives/fitting/fitpanel.py

    rb6a181b reff93b8  
    6464        self.sim_page = None 
    6565        self.batch_page = None 
    66         self.fit_engine_type = "scipy" 
     66        self.fit_engine_type = "bumps" 
    6767        ## get the state of a page 
    6868        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate) 
  • src/sans/perspectives/fitting/fitproblem.py

    r5777106 r5bf0331  
    454454        return self.itervalues() 
    455455     
    456     def  set_result(self, result, fid): 
     456    def set_result(self, result, fid): 
    457457        """ 
    458458        """ 
Note: See TracChangeset for help on using the changeset viewer.