def loadParameters(inits=None, is_flat=False, kind=None, pc_map={}): """ Generates and returns an lmfit Parameters object with bounded parameters initialized for flat or non flat model fit """ lmParams = lmParameters() pnames = ['a', 'tr', 'v', 'ssv', 'z', 'xb', 'si', 'sso'] pfit = list(set(inits.keys()).intersection(pnames)) bounds = get_bounds(kind=kind) for pkey, pclist in pc_map.items(): if is_flat: break # exit pfit.remove(pkey) if hasattr(inits[pkey], '__iter__'): vals = inits[pkey] else: vals = inits[pkey] * np.ones(len(pclist)) mn = bounds[pkey][0] mx = bounds[pkey][1] for k, v in zip(pclist, vals): if isinstance(v, np.ndarray): v = np.asscalar(v) lmParams.add(k, value=v, vary=True, min=mn, max=mx) for pk in pfit: inits = scalarize_params(inits, pfit) if is_flat: mn = bounds[pk][0] mx = bounds[pk][1] lmParams.add(pk, value=inits[pk], vary=True, min=mn, max=mx) else: lmParams.add(pk, value=inits[pk], vary=False) return lmParams
def loadParameters(self, params=None, is_flat=False, kind=None, pc_map={}): """ Generates and returns an lmfit Parameters object with bounded parameters initialized for flat or non flat model fit """ if params is None: params = self.inits p = deepcopy(params) lmParams = lmParameters() pfit = list(set(p.keys()).intersection(self.allparams)) bounds = self.get_bounds() for pkey, pclist in self.pc_map.items(): if is_flat: break # exit pfit.remove(pkey) if hasattr(p[pkey], '__iter__'): vals = p[pkey] else: vals = p[pkey] * np.ones(len(pclist)) mn = bounds[pkey][0] mx = bounds[pkey][1] for k, v in zip(pclist, vals): if isinstance(v, np.ndarray): v = np.asscalar(v) lmParams.add(k, value=v, vary=True, min=mn, max=mx) for pk in pfit: p = self.scalarize_params(p, pc_map=pfit, is_flat=is_flat) if is_flat: mn = bounds[pk][0] mx = bounds[pk][1] lmParams.add(pk, value=p[pk], vary=True, min=mn, max=mx) else: lmParams.add(pk, value=p[pk], vary=False) return lmParams
def fittingOptionGetter(self) -> Optional[FittingOptions]: """ get all the fitting options and put them into a dictionary """ if DEBUG: print("GUI...: ", 'getter in gui called') # get the current model selected model = self.getCurrentModel() if model is None: return None # get the parameters for current model parameters = lmParameters() for i in range(self.param_table.rowCount()): table_item = self.param_table.verticalHeaderItem(i) assert isinstance(table_item, QtWidgets.QTableWidgetItem) param_name = table_item.text() param = lmParameter(param_name) item0 = self.param_table.cellWidget(i, 0) item1 = self.param_table.cellWidget(i, 1) item2 = self.param_table.cellWidget(i, 2) item3 = self.param_table.cellWidget(i, 3) assert isinstance(item0, QtWidgets.QCheckBox) assert isinstance(item1, OptionSpinbox) assert isinstance(item2, NumberInput) assert isinstance(item3, NumberInput) param.vary = not item0.isChecked() param.value = item1.value() param.min = item2.value() param.max = item3.value() parameters[param_name] = param fitting_options = FittingOptions(model, parameters, self.dry_run) if DEBUG: print("GUI...: ", 'getter in gui got', fitting_options) return fitting_options
def fitting_process(self, dataIn: Optional[DataDictBase] = None) -> Optional[Dict[str, Optional[DataDictBase]]]: if dataIn is None: return None if len(dataIn.axes()) > 1 or len(dataIn.dependents()) > 1: return dict(dataOut=dataIn) dataIn_opt = dataIn.get('__fitting_options__') dataOut = dataIn.copy() # no fitting option selected in gui if self.fitting_options is None: if dataIn_opt is not None: self._fitting_options = dataIn_opt else: return dict(dataOut=dataOut) if dataIn_opt is not None: if DEBUG: print("NODE>>>: ", "Emit initial option from node!", dataIn_opt) self.default_fitting_options.emit(dataIn_opt) # fitting if DEBUG: print("NODE>>>: ", f"node got fitting option {self.fitting_options}") axname = dataIn.axes()[0] x = dataIn.data_vals(axname) y = dataIn.data_vals(dataIn.dependents()[0]) assert isinstance(self.fitting_options, FittingOptions) fit = self.fitting_options.model(x, y) if self.fitting_options.dry_run: guess_params = lmParameters() for pn, pv in fit.guess(x, y).items(): guess_params.add(pn, value=pv) guess_opts = FittingOptions(self.fitting_options.model, guess_params, False) self.guess_fitting_options.emit(guess_opts) if DEBUG: print("NODE>>>: ", f"guess param in node. Emit guess_opts: {guess_opts}") # show dry run result fit_result = fit.run(dry=True) result_y = fit_result.eval(coordinates=x) dataOut['guess'] = dict(values=result_y, axes=[axname, ]) else: fit_result = fit.run(params=self.fitting_options.parameters) assert isinstance(fit_result, FitResult) lm_result = fit_result.lmfit_result if lm_result.success: dataOut['fit'] = dict(values=lm_result.best_fit, axes=[axname,]) dataOut.add_meta('info', lm_result.fit_report()) return dict(dataOut=dataOut)
def convert_to_pars_obj(self, par_list: Optional[List] = None) -> lmParameters: """ Create an lmfit compatible container with the `Parameters` converted from the base object. :param par_list: If only a single/selection of parameter is required. Specify as a list :type par_list: List[str] :return: lmfit Parameters compatible object :rtype: lmParameters """ if par_list is None: # Assume that we have a BaseObj for which we can obtain a list par_list = self._object.get_fit_parameters() pars_obj = lmParameters().add_many( [self.__class__.convert_to_par_object(obj) for obj in par_list]) return pars_obj
def loadParameters_RL(inits, pvary, pflat, nlevels=1, kind='dpm'): """ Generates and returns an lmfit Parameters object with bounded parameters initialized for flat or non flat model fit """ lmParams = lmParameters() bounds = get_bounds(kind=kind) if nlevels > 1: varyIDs = ['{}_{}'.format(pkey, str(l)) for l in np.arange(nlevels)] for pkey in pvary: mn = bounds[pkey][0] mx = bounds[pkey][1] for i in range(nlevels): varyID = pkey if nlevels>1: varyID = '{}_{}'.format(pkey, str(l)) lmParams.add(varyID, value=inits[pkey], vary=True, min=mn, max=mx) for pk in pflat: lmParams.add(pk, value=inits[pk], vary=False) return lmParams
def generate(mod_pars, body_pars, photo_data, rv_data, fit_method, ncores, fname): nbodies, epoch, max_h, orbit_error, rv_body, rv_corr = mod_pars masses, radii, fluxes, u1, u2, a, e, inc, om, ln, ma = body_pars lmparams = lmParameters() # lmparams.add('N', value=N, vary=False) # lmparams.add('epoch', value=epoch, vary=False) # lmparams.add('maxh', value=maxh, vary=False) # lmparams.add('orbit_error', value=orbit_error, vary=False) for i in range(nbodies): lmparams.add('mass_{0}'.format(i), value=masses[i], min=0.0, max=0.1, vary=False) lmparams.add('radius_{0}'.format(i), value=radii[i], min=0.0, max=1.0, vary=False) lmparams.add('flux_{0}'.format(i), value=fluxes[i], min=0.0, max=1.0, vary=False) lmparams.add('u1_{0}'.format(i), value=u1[i], min=0.0, max=1.0, vary=False) lmparams.add('u2_{0}'.format(i), value=u2[i], min=0.0, max=1.0, vary=False) # if i < N-1: # params['flux_{0}'.format(i)].vary = False # params['u1_{0}'.format(i)].vary = False # params['u2_{0}'.format(i)].vary = False if i > 0: lmparams.add('a_{0}'.format(i), value=a[i - 1], min=0.0, max=10.0, vary=False) lmparams.add('e_{0}'.format(i), value=e[i - 1], min=0.0, max=1.0, vary=False) lmparams.add('inc_{0}'.format(i), value=inc[i - 1], min=0.0, max=np.pi, vary=False) lmparams.add('om_{0}'.format(i), value=om[i - 1], min=0.0, max=twopi) lmparams.add('ln_{0}'.format(i), value=ln[i - 1], min=0.0, max=twopi) lmparams.add('ma_{0}'.format(i), value=ma[i - 1], min=0.0, max=twopi) print('Generating maximum likelihood values...') results = minimize(residual, lmparams, args=(mod_pars, photo_data, rv_data, ncores, fname), iter_cb=per_iteration, method=fit_method) # Save the final outputs print "Writing report..." report_fit(results.params) utilfuncs.report_as_input(mod_pars, utilfuncs.get_lmfit_parameters(mod_pars, results.params), fname) # Return best fit values return utilfuncs.get_lmfit_parameters(mod_pars, results.params)