Changeset 1cff677 in sasview for park_integration/src/sans
- Timestamp:
- Oct 4, 2011 8:03:59 PM (13 years ago)
- 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:
- 706667b
- Parents:
- 34a60dd
- Location:
- park_integration/src/sans/fit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
park_integration/src/sans/fit/AbstractFitEngine.py
r41517a6 r1cff677 17 17 parameter value in the SANS model. 18 18 """ 19 def __init__(self, name, model ):19 def __init__(self, name, model, data): 20 20 """ 21 21 :param name: the name of the model parameter … … 25 25 park.Parameter.__init__(self, name) 26 26 self._model, self._name = model, name 27 self.data = data 28 self.model = model 27 29 #set the value for the parameter of the given name 28 30 self.set(model.getParam(name)) … … 85 87 PARK wrapper for SANS models. 86 88 """ 87 def __init__(self, sans_model, **kw):89 def __init__(self, sans_model, sans_data=None, **kw): 88 90 """ 89 91 :param sans_model: the sans model to wrap using park interface … … 93 95 self.model = sans_model 94 96 self.name = sans_model.name 97 self.data = sans_data 95 98 #list of parameters names 96 99 self.sansp = sans_model.getParamList() 97 100 #list of park parameter 98 self.parkp = [SansParameter(p, sans_model ) for p in self.sansp]101 self.parkp = [SansParameter(p, sans_model, sans_data) for p in self.sansp] 99 102 #list of parameterset 100 103 self.parameterset = park.ParameterSet(sans_model.name, pars=self.parkp) … … 540 543 self.fit_arrange_dict = {} 541 544 542 def set_model(self, model, id, pars=[], constraints=[]):545 def set_model(self, model, id, pars=[], constraints=[], data=None): 543 546 """ 544 547 set a model on a given in the fit engine. … … 566 569 new_model = model 567 570 if not issubclass(model.__class__, Model): 568 new_model = Model(model )571 new_model = Model(model, data) 569 572 570 573 if len(constraints) > 0: -
park_integration/src/sans/fit/ParkFitting.py
r64d3861 r1cff677 12 12 from park import fit 13 13 from park import fitresult 14 from park.fitresult import FitParameter 15 import park.simplex 14 16 from park.assembly import Assembly 17 from park.assembly import Part 15 18 from park.fitmc import FitSimplex 16 19 import park.fitmc 17 20 from park.fitmc import FitMC 18 21 from park.fit import Fitter 22 from park.formatnum import format_uncertainty 19 23 #from Loader import Load 20 24 from sans.fit.AbstractFitEngine import FitEngine 21 22 23 25 26 class SansFitSimplex(FitSimplex): 27 """ 28 Local minimizer using Nelder-Mead simplex algorithm. 29 30 Simplex is robust and derivative free, though not very efficient. 31 32 This class wraps the bounds contrained Nelder-Mead simplex 33 implementation for `park.simplex.simplex`. 34 """ 35 radius = 0.05 36 """Size of the initial simplex; this is a portion between 0 and 1""" 37 xtol = 1 38 #xtol = 1e-4 39 """Stop when simplex vertices are within xtol of each other""" 40 ftol = 1e-4 41 """Stop when vertex values are within ftol of each other""" 42 maxiter = None 43 """Maximum number of iterations before fit terminates""" 44 def fit(self, fitness, x0): 45 """Run the fit""" 46 self.cancel = False 47 pars = fitness.fit_parameters() 48 bounds = numpy.array([p.range for p in pars]).T 49 result = park.simplex.simplex(fitness, x0, bounds=bounds, 50 radius=self.radius, xtol=self.xtol, 51 ftol=self.ftol, maxiter=self.maxiter, 52 abort_test=self._iscancelled) 53 #print "calls:",result.calls 54 #print "simplex returned",result.x,result.fx 55 # Need to make our own copy of the fit results so that the 56 # values don't get stomped on by the next fit iteration. 57 fitpars = [SansFitParameter(pars[i].name,pars[i].range,v, pars[i].model, pars[i].data) 58 for i,v in enumerate(result.x)] 59 res = fitresult.FitResult(fitpars, result.calls, result.fx) 60 # Compute the parameter uncertainties from the jacobian 61 res.calc_cov(fitness) 62 return res 63 64 class SansFitter(Fitter): 65 """ 66 """ 67 def fit(self, fitness, handler): 68 """ 69 Global optimizer. 70 71 This function should return immediately 72 """ 73 # Determine initial value and bounds 74 pars = fitness.fit_parameters() 75 bounds = numpy.array([p.range for p in pars]).T 76 x0 = [p.value for p in pars] 77 78 # Initialize the monitor and results. 79 # Need to make our own copy of the fit results so that the 80 # values don't get stomped on by the next fit iteration. 81 handler.done = False 82 self.handler = handler 83 fitpars = [SansFitParameter(pars[i].name, pars[i].range, v, 84 pars[i].model, pars[i].data) 85 for i,v in enumerate(x0)] 86 handler.result = fitresult.FitResult(fitpars, 0, numpy.NaN) 87 88 # Run the fit (fit should perform _progress and _improvement updates) 89 # This function may return before the fit is complete. 90 self._fit(fitness, x0, bounds) 91 92 class SansFitMC(SansFitter): 93 """ 94 Monte Carlo optimizer. 95 96 This implements `park.fit.Fitter`. 97 """ 98 localfit = SansFitSimplex() 99 start_points = 10 100 101 def _fit(self, objective, x0, bounds): 102 """ 103 Run a monte carlo fit. 104 105 This procedure maps a local optimizer across a set of initial points. 106 """ 107 park.fitmc.fitmc(objective, x0, bounds, self.localfit, 108 self.start_points, self.handler) 109 110 111 class SansPart(Part): 112 """ 113 Part of a fitting assembly. Part holds the model itself and 114 associated data. The part can be initialized with a fitness 115 object or with a pair (model,data) for the default fitness function. 116 117 fitness (Fitness) 118 object implementing the `park.assembly.Fitness` interface. In 119 particular, fitness should provide a parameterset attribute 120 containing a ParameterSet and a residuals method returning a vector 121 of residuals. 122 weight (dimensionless) 123 weight for the model. See comments in assembly.py for details. 124 isfitted (boolean) 125 True if the model residuals should be included in the fit. 126 The model parameters may still be used in parameter 127 expressions, but there will be no comparison to the data. 128 residuals (vector) 129 Residuals for the model if they have been calculated, or None 130 degrees_of_freedom 131 Number of residuals minus number of fitted parameters. 132 Degrees of freedom for individual models does not make 133 sense in the presence of expressions combining models, 134 particularly in the case where a model has many parameters 135 but no data or many computed parameters. The degrees of 136 freedom for the model is set to be at least one. 137 chisq 138 sum(residuals**2); use chisq/degrees_of_freedom to 139 get the reduced chisq value. 140 141 Get/set the weight on the given model. 142 143 assembly.weight(3) returns the weight on model 3 (0-origin) 144 assembly.weight(3,0.5) sets the weight on model 3 (0-origin) 145 """ 146 147 def __init__(self, fitness, weight=1., isfitted=True): 148 Part.__init__(self, fitness=fitness, weight=weight, 149 isfitted=isfitted) 150 151 self.model, self.data = fitness[0], fitness[1] 152 153 class SansFitParameter(FitParameter): 154 """ 155 Fit result for an individual parameter. 156 """ 157 def __init__(self, name, range, value, model, data): 158 FitParameter.__init__(self, name, range, value) 159 self.model = model 160 self.data = data 161 162 def summarize(self): 163 """ 164 Return parameter range string. 165 166 E.g., " Gold .....|.... 5.2043 in [2,7]" 167 """ 168 bar = ['.']*10 169 lo,hi = self.range 170 if numpy.isfinite(lo)and numpy.isfinite(hi): 171 portion = (self.value-lo)/(hi-lo) 172 if portion < 0: portion = 0. 173 elif portion >= 1: portion = 0.99999999 174 barpos = int(math.floor(portion*len(bar))) 175 bar[barpos] = '|' 176 bar = "".join(bar) 177 lostr = "[%g"%lo if numpy.isfinite(lo) else "(-inf" 178 histr = "%g]"%hi if numpy.isfinite(hi) else "inf)" 179 valstr = format_uncertainty(self.value, self.stderr) 180 model_name = str(None) 181 if self.model is not None: 182 model_name = self.model.name 183 data_name = str(None) 184 if self.data is not None: 185 data_name = self.data.name 186 187 return "%25s %s %s in %s,%s, %s, %s" % (self.name,bar,valstr,lostr,histr, 188 model_name, data_name) 189 def __repr__(self): 190 #return "FitParameter('%s')"%self.name 191 return str(self.__class__) 192 24 193 class MyAssembly(Assembly): 25 194 def __init__(self, models, curr_thread=None): … … 29 198 self._cancel = False 30 199 200 def fit_parameters(self): 201 """ 202 Return an alphabetical list of the fitting parameters. 203 204 This function is called once at the beginning of a fit, 205 and serves as a convenient place to precalculate what 206 can be precalculated such as the set of fitting parameters 207 and the parameter expressions evaluator. 208 """ 209 self.parameterset.setprefix() 210 self._fitparameters = self.parameterset.fitted 211 self._restraints = self.parameterset.restrained 212 pars = self.parameterset.flatten() 213 context = self.parameterset.gather_context() 214 self._fitexpression = park.expression.build_eval(pars,context) 215 #print "constraints",self._fitexpression.__doc__ 216 217 self._fitparameters.sort(lambda a,b: cmp(a.path,b.path)) 218 # Convert to fitparameter a object 219 220 fitpars = [SansFitParameter(p.path,p.range,p.value, p.model, p.data) 221 for p in self._fitparameters] 222 #print "fitpars", fitpars 223 return fitpars 224 225 def all_results(self, result): 226 """ 227 Extend result from the fit with the calculated parameters. 228 """ 229 calcpars = [SansFitParameter(p.path,p.range,p.value, p.model, p.data) 230 for p in self.parameterset.computed] 231 #print "all_results", calcpars 232 result.parameters += calcpars 233 31 234 def eval(self): 32 235 """ … … 171 374 """ 172 375 self.create_assembly(curr_thread=curr_thread) 173 localfit = FitSimplex()376 localfit = SansFitSimplex() 174 377 localfit.ftol = ftol 175 378 176 379 # See `park.fitresult.FitHandler` for details. 177 fitter = FitMC(localfit=localfit, start_points=1)380 fitter = SansFitMC(localfit=localfit, start_points=1) 178 381 if handler == None: 179 382 handler = fitresult.ConsoleUpdate(improvement_delta=0.1) 180 383 result = fit.fit(self.problem, fitter=fitter, handler=handler) 181 384 self.problem.all_results(result) 385 386 #print "park------", self.problem.parts 387 182 388 if result != None: 183 389 if q != None:
Note: See TracChangeset
for help on using the changeset viewer.