def pyfxcor(inspec, template, vmin=-200., vmax=200., res=3, rej=1000): rv, cc = pyasl.crosscorrRV(inspec[0], inspec[1], template[0], template[1], vmin, vmax, res, skipedge=rej) cen_gs = np.argmax(cc) perfx, perfy = rv[cen_gs - 5:cen_gs + 6], cc[cen_gs - 5:cen_gs + 6] try: gauss = ConstantModel() + GaussianModel() pars = gauss.make_params() pars['center'].set(value=rv[np.argmax(cc)], vary=True) pars['amplitude'].set(value=max(cc), vary=True) pars['sigma'].set(vary=True) pars['c'].set(value=0, vary=True) out = gauss.fit(perfy, pars, x=perfx) ct = out.best_values['center'] cterr = out.params['center'].stderr except: return 'error', '' return ct, cterr
def Rectangle(signal, guess): if guess == False: return [0, 0, 0] else: amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] step_mod = Rectangle() const_mod = ConstantModel() pars = step_mod.guess(Y, x=X, center=centre) pars += const_mod.guess(Y, x=X) mod = step_mod + const_mod result = mod.fit(Y, pars, x=X) # write error report #print result.fit_report() fwhm = result.best_values['sigma'] * 2.3548 print fwhm return X, result.best_fit, result.redchi, 0
def gauss_step_const(signal, guess): """ Fits high contrast data very well """ if guess == False: return [0, 0] else: amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] # gauss_mod = Model(gaussian) gauss_mod = Model(gaussian) const_mod = ConstantModel() step_mod = StepModel(prefix='step') pars = gauss_mod.make_params(height=amp, center=centre, width=stdev / 3., offset=offset) # pars = gauss_mod.make_params(amplitude=amp, center=centre, sigma=stdev / 3.) gauss_mod.set_param_hint('sigma', value = stdev / 3., min=stdev / 2., max=stdev) pars += step_mod.guess(Y, x=X, center=centre) pars += const_mod.guess(Y, x=X) mod = const_mod + gauss_mod + step_mod result = mod.fit(Y, pars, x=X) # write error report #print result.fit_report() print "contrast fit", result.redchi return X, result.best_fit, result.redchi
def GaussConst(signal, guess): amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center=centre, sigma=stdev, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center'].min = centre - 5. pars['gauss_center'].max = centre + 5. pars['gauss_sigma'].max = stdev + 5. mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) fwhm = result.best_values['gauss_sigma'] #* 2.3548 centr = result.best_values['gauss_center'] # Values within two stdevs i.e. 95% pl.plot(np.repeat(centr - fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') pl.plot(np.repeat(centr + fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') return X, result.best_fit, result.best_values['gauss_sigma'] * 4
def Box(signal, guess): amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = RectangleModel(prefix='gauss_', mode='logistic') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params( center1=centre-stdev*3, center2=centre+stdev*3, sigma1=0, sigma2=0, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center1'].min = centre-stdev*3 - 3 pars['gauss_center2'].max = centre-stdev*3 + 3 pars['gauss_center2'].min = centre+stdev*3 - 3 pars['gauss_center2'].max = centre+stdev*3 + 3 mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) c1 = result.best_values['gauss_center1'] c2 = result.best_values['gauss_center2'] pl.legend() return X, result.best_fit, c2-c1
def GaussConst(signal, guess): amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:, 0] Y = data[:, 1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center=centre, sigma=stdev, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center'].min = centre - 5. pars['gauss_center'].max = centre + 5. pars['gauss_sigma'].max = stdev + 5. mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) fwhm = result.best_values['gauss_sigma'] #* 2.3548 centr = result.best_values['gauss_center'] # Values within two stdevs i.e. 95% pl.plot(np.repeat(centr - fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') pl.plot(np.repeat(centr + fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') return X, result.best_fit, result.best_values['gauss_sigma'] * 4
def Box(signal, guess): amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:, 0] Y = data[:, 1] gauss_mod = RectangleModel(prefix='gauss_', mode='logistic') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center1=centre - stdev * 3, center2=centre + stdev * 3, sigma1=0, sigma2=0, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center1'].min = centre - stdev * 3 - 3 pars['gauss_center2'].max = centre - stdev * 3 + 3 pars['gauss_center2'].min = centre + stdev * 3 - 3 pars['gauss_center2'].max = centre + stdev * 3 + 3 mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) c1 = result.best_values['gauss_center1'] c2 = result.best_values['gauss_center2'] pl.legend() return X, result.best_fit, c2 - c1
def GaussConst(signal, guess): if guess == False: return [0, 0, 0] else: amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') #pars = lorentz_mod.make_params(amplitude=amp, center=centre, sigma=stdev / 3.) #lorentz_mod.set_param_hint('sigma', value = stdev / 3., min=0., max=stdev) pars = gauss_mod.guess(Y, x=X, center=centre, sigma=stdev / 3., amplitude=amp) #pars += step_mod.guess(Y, x=X, center=centre) pars += const_mod.guess(Y, x=X) pars['gauss_sigma'].vary = False mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) # write error report #print result.fit_report() fwhm = result.best_values['gauss_sigma'] * 2.3548 return X, result.best_fit, result.redchi, fwhm
def fit_peaks( x, y, peak_pos, bg="constant", sigma_guess=2, center_pm=20, sigma_min=0.5, amplitude_max_m=3.0, bg_pm=100, ): mod = ConstantModel() for i, p in enumerate(peak_pos): mod += LorentzianModel(prefix="p%s_" % i) pars = mod.make_params() for i, p in enumerate(peak_pos): pars["p%s_center" % i].set(p, min=p - center_pm, max=p + center_pm) pars["p%s_sigma" % i].set(sigma_guess, min=sigma_min) # pars['p%s_amplitude' % i].set(10**2, min=0.0) pars["p%s_amplitude" % i].set( amplitude_max_m * y[find_nearest_index(x, p)], min=0.0 ) pars["c"].set(0, min=-1 * bg_pm, max=bg_pm) out = mod.fit(y, pars, x=x, method="leastsq") out.peak_pos = peak_pos return out
def fitgaussian_sample(sample, components, svg, verbose, center, cmin, cmax, amp, amin, sigma, smin): '''Fits gaussian curve to dyad coverage for a single sample.''' print('Fits gaussian curve to dyad coverage of sample {}'.format(sample)) input = sample + '-dyad.txt' dyads = pd.read_csv(input, sep='\t', index_col=0, comment='#') x = dyads.index.values y = dyads['Relative Frequency'].values if not amp: amp = dyads['Relative Frequency'].max() * 100 if not center: center = 0.0 if not sigma: sigma = dyads.index.max() / 2 plt.figure() plt.title(sample) plt.xlabel('Position relative to dyad (bp)') plt.ylabel('Relative Frequency') plt.xlim(x[0], x[len(x) - 1]) plt.xticks(list(range(x[0], x[len(x) - 1] + 1, 25))) plt.plot(dyads.index.values, dyads['Relative Frequency'].values, color='red') plot_output = sample + '-dyad-gaussian.png' try: constant = ConstantModel(prefix='c_') pars = constant.make_params() pars['c_c'].set(value=dyads['Relative Frequency'].min(), min=0.0, max=dyads['Relative Frequency'].max()) gauss = GaussianModel(prefix='g_') pars.update(gauss.make_params()) pars['g_center'].set(value=center, min=cmin, max=cmax) pars['g_sigma'].set(value=sigma, min=smin) pars['g_amplitude'].set(value=amp, min=amin) mod = constant + gauss init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) if components: plt.plot(x, init, 'b--', label='Initial fit') if verbose: print(out.fit_report(min_correl=0.5)) plt.plot(x, out.best_fit, 'b-', label='Best fit') if components: comps = out.eval_components(x=x) plt.plot(x, np.repeat(comps['c_'], len(x)), 'g--', label='Constant component') plt.plot(x, comps['g_'], 'm--', label='Gaussian component') except Exception as e: logging.warning( 'could not fit gaussian curve to sample {}'.format(sample), e) if components: plt.legend(loc='lower right') plt.savefig(plot_output) if svg: plot_svg_output = sample + '-dyad-gaussian.svg' plt.savefig(plot_svg_output, transparent=True) plt.close()
def FWHM(counts, lower_bound, upper_bound): X = range(lower_bound, upper_bound) Y = counts[lower_bound:upper_bound] # Fit a guassian mean = sum(X * Y) / sum(Y) sigma = np.sqrt(sum(Y * (X - mean)**2) / sum(Y)) # pi = [max(Y),mean,sigma] # popt, pcov = curve_fit(gauss, X, Y, p0=pi) # print(popt) # fit_a, fit_mu, fit_stdev = popt # fit guassian using other method model = GaussianModel(prefix='peak_') + ConstantModel() # make a model that is a Gaussian + a constant: model = GaussianModel(prefix='peak_') + ConstantModel() # make parameters with starting values: params = model.make_params(c=1.0, peak_center=mean, peak_sigma=sigma, peak_amplitude=max(Y)) # run fit result = model.fit(Y, params, x=X) print('fwhm: ', result.params['peak_fwhm'].value, 'centroid: ', result.params['peak_center'].value) # find FWHM # fwhm = 2*np.sqrt(2*np.log(2))*np.abs(fit_stdev) # cent = fit_mu return result.params['peak_fwhm'].value, result.params['peak_center'].value
def fit_s21mag(x_val, y_val): peak = GaussianModel() offset = ConstantModel() model = peak + offset pars = offset.make_params(c=np.median(y_val)) pars += peak.guess(y_val, x=x_val, amplitude=-0.5) result = model.fit(y_val, pars, x=x_val) return result
def model(self): """Returns the sum of all peak models.""" model = ConstantModel(prefix="BASE_") model.set_param_hint("c", vary=False, value=0) self.params += model.make_params() for peak in self._peaks: model += peak.model return model
def __init__(self, nexp=0, sum_one=False): self.sum_one_flag = sum_one self.model = ConstantModel() self.nexp = 0 self.errors = None self.params = None self.res = None for _ in range(nexp): self.add_exp()
def __init__(self, nexp=0, moddef=" "): self.definition = moddef self.model = ConstantModel() self.nexp = 0 self.errors = None self.params = None self.res = None for _ in range(nexp): self.add_exp()
def fitNpeaks(f, y, npeaks=5, thres=0.02, min_dist=5, width=300, plot_prefix=None, model=SkewedGaussianModel, offset=True): # Guess initial peak centres using peakutils indexes = peakutils.indexes(y, thres=thres, min_dist=min_dist) peaksfound = len(indexes) assert peaksfound >= npeaks, "Looking for %s or more peaks only found %s of them!" % ( npeaks, peaksfound) peak_f = peakutils.interpolate(f, y, ind=indexes) # Oder peaks by decreaing height and keep only the first npeaks peak_heights = indexes peak_order = peak_heights.argsort()[::-1] peak_heights = peak_heights[peak_order[:npeaks]] peak_f = peak_f[peak_order[:npeaks]] amplitude_scale = 1.0 peak_amplitudes = peak_heights * amplitude_scale # This is lmfit's annoying definition of a Gaussian `amplitude' print('Initial peaks guessed at ', peak_f) # Make multipeak model peaks = [] for i in range(npeaks): prefix = 'g{:d}_'.format(i + 1) peaks.append(model(prefix=prefix)) if i == 0: pars = peaks[i].make_params(x=f) else: pars.update(peaks[i].make_params()) if model == SkewedGaussianModel: pars[prefix + 'center'].set(peak_f[i], min=f.min(), max=f.max()) pars[prefix + 'sigma'].set(width, min=0.1 * width, max=10 * width) pars[prefix + 'gamma'].set(0, min=-5, max=5) pars[prefix + 'amplitude'].set(peak_amplitudes[i]) elif model == GaussianModel: pars[prefix + 'center'].set(peak_f[i], min=f.min(), max=f.max()) pars[prefix + 'sigma'].set(width, min=0.1 * width, max=10 * width) pars[prefix + 'amplitude'].set(peak_amplitudes[i]) model = peaks[0] for i in range(1, npeaks): model += peaks[i] if offset: model += ConstantModel() pars.update(ConstantModel().make_params()) pars['c'].set(0) # Fit first spectrum, creating the ModelResult object which will be used over and over fit = model.fit(y, pars, x=f) return fit
def fit_s21mag(x_val, y_val): x_val_midpoint = int(np.round(len(x_val) / 2)) peak = GaussianModel() offset = ConstantModel() model = peak + offset pars = offset.make_params(c=np.median(y_val)) pars += peak.guess(y_val, x=x_val, amplitude=-0.05, center=x_val[x_val_midpoint]) result = model.fit(y_val, pars, x=x_val) return result
def make_gaussian_model(self): """ This method creates a model of a gaussian with an offset. @return tuple: (object model, object params) Explanation of the objects: object lmfit.model.CompositeModel model: A model the lmfit module will use for that fit. Here a gaussian model. Returns an object of the class lmfit.model.CompositeModel. object lmfit.parameter.Parameters params: It is basically an OrderedDict, so a dictionary, with keys denoting the parameters as string names and values which are lmfit.parameter.Parameter (without s) objects, keeping the information about the current value. The used model has the Parameter with the meaning: 'amplitude' : amplitude 'center' : center 'sigm' : sigma 'fwhm' : full width half maximum 'c' : offset For further information have a look in: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.GaussianModel """ model = GaussianModel() + ConstantModel() params = model.make_params() return model, params
def model_at_depth(tree, depth, property_name): r"""Generate a fit model at a particular tree depth Parameters ---------- tree : :class:`~idpflex.cnextend.Tree` Hierarchical tree depth: int depth level, starting from the tree's root (depth=0) property_name : str Name of the property to create the model for Returns ------- :class:`~lmfit.model.CompositeModel` A model composed of a :class:`~idpflex.bayes.TabulatedFunctionModel` for each node plus a :class:`~lmfit.models.ConstantModel` accounting for a flat background """ # noqa: E501 mod = ConstantModel() for node in tree.nodes_at_depth(depth): p = node[property_name] m = TabulatedFunctionModel(p.x, p.y, prefix='n{}_'.format(node.id)) m.set_param_hint('center', vary=False) m.set_param_hint('amplitude', value=1.0 / (1 + depth)) mod += m return mod
def fit_s21mag(x_val, y_val): peak = LorentzianModel() offset = ConstantModel() model = peak pars = peak.guess(y_val, x=x_val, amplitude=-0.05) result = model.fit(y_val, pars, x=x_val) return result
def fit_peak_df(df, model=GaussianModel, params=None, fit_range=(-np.inf, np.inf), x_field=None, fit_field='nphe2_mean', out_field='peak_fit'): """ Fits DataFrame with selected peak model. Appends residuals column to DataFrame. """ # Data fit_min, fit_max = fit_range df_ranged = df[(df.index > fit_min) & (df.index < fit_max)] if x_field: x = np.array(df_ranged[x_field]) full_x = np.array(df[x_field]) else: x = np.array(df_ranged.index.get_values()) full_x = np.array(df.index.get_values()) y = np.array(df_ranged[fit_field].values) full_y = np.array(df[fit_field].values) # Models if isinstance(model, str): try: model = PEAK_MODELS[model] except KeyError: print("Undefined model: {}, using default".format(model)) peak_mod = model(prefix='peak_') const_mod = ConstantModel(prefix='const_') result_model = const_mod + peak_mod # Parameters if not params: pars = const_mod.make_params(c=y.min()) pars += peak_mod.guess(y, x=x, center=0) else: pars = params # Fitting result = result_model.fit(y, params=pars, x=x) peak_eval = result.eval(x=full_x) y_res = full_y - peak_eval df[out_field] = pd.Series(peak_eval, index=df.index) df[out_field + '_res'] = pd.Series(y_res, index=df.index) return df, result
def gaussian_fit(self, x, y, paras=None, method=None): g1model = GaussianModel(prefix='g1_') g2model = GaussianModel(prefix='g2_') g3model = GaussianModel(prefix='g3_') cmodel = ConstantModel() paras_fit = g1model.guess(data=y, x=x) paras_fit.update(g2model.make_params()) paras_fit.update(g3model.make_params()) paras_fit['g1_amplitude'].set(min=0.) paras_fit['g2_amplitude'].set(min=0.) paras_fit['g3_amplitude'].set(min=0.) paras_fit['g1_center'].set(min=paras['g1_center'] - 300., value=paras['g1_center'], max=paras['g1_center'] + 300.) paras_fit['g2_center'].set(min=paras['g2_center'] - 300., value=paras['g2_center'], max=paras['g2_center'] + 300.) paras_fit['g3_center'].set(min=paras['g3_center'] - 300., value=paras['g3_center'], max=paras['g3_center'] + 300.) paras_fit['g1_sigma'].set(min=100, value=paras['g1_sigma'], max=paras['g1_sigma'] + 50.) paras_fit['g2_sigma'].set(min=100, value=paras['g2_sigma'], max=paras['g2_sigma'] + 50.) paras_fit['g3_sigma'].set(min=100, value=paras['g3_sigma'], max=paras['g3_sigma'] + 50.) paras_fit.update(cmodel.make_params()) model = g1model + g2model + g3model + cmodel result = model.fit(y, x=x, params=paras_fit, mothod=method) yfit = result.best_fit y_para = result.best_values residual = y - yfit return yfit, y_para, result, residual
def xrf_calib_init_roi(mca, roiname): """initial calibration step for MCA: find energy locations for one ROI """ if not isLarchMCAGroup(mca): print('Not a valid MCA') return energy = 1.0 * mca.energy chans = 1.0 * np.arange(len(energy)) counts = mca.counts bgr = getattr(mca, 'bgr', None) if bgr is not None: counts = counts - bgr if not hasattr(mca, 'init_calib'): mca.init_calib = OrderedDict() roi = None for xroi in mca.rois: if xroi.name == roiname: roi = xroi break if roi is None: return words = roiname.split() elem = words[0].title() family = 'Ka' if len(words) > 1: family = words[1].title() if family == 'Lb': family = 'Lb1' try: eknown = xray_line(elem, family).energy / 1000.0 except: eknown = 0.001 llim = max(0, roi.left - roi.bgr_width) hlim = min(len(chans) - 1, roi.right + roi.bgr_width) segcounts = counts[llim:hlim] maxcounts = max(segcounts) ccen = llim + np.where(segcounts == maxcounts)[0][0] ecen = ccen * mca.slope + mca.offset bkgcounts = counts[llim] + counts[hlim] if maxcounts < 2 * bkgcounts: mca.init_calib[roiname] = (eknown, ecen, 0.0, ccen, None) else: model = GaussianModel() + ConstantModel() params = model.make_params(amplitude=maxcounts, sigma=(chans[hlim] - chans[llim]) / 2.0, center=ccen - llim, c=0.00) params['center'].min = -10 params['center'].max = hlim - llim + 10 params['c'].min = -10 out = model.fit(counts[llim:hlim], params, x=chans[llim:hlim]) ccen = llim + out.params['center'].value ecen = ccen * mca.slope + mca.offset fwhm = out.params['fwhm'].value * mca.slope mca.init_calib[roiname] = (eknown, ecen, fwhm, ccen, out)
def test_stepmodel_erf(): x, y = get_data() stepmod = StepModel(form='linear') const = ConstantModel() pars = stepmod.guess(y, x) pars = pars + const.make_params(c=3*y.min()) mod = stepmod + const out = mod.fit(y, pars, x=x) assert(out.nfev > 5) assert(out.nvarys == 4) assert(out.chisqr > 1) assert(out.params['c'].value > 3) assert(out.params['center'].value > 1) assert(out.params['center'].value < 4) assert(out.params['amplitude'].value > 50) assert(out.params['sigma'].value > 0.2) assert(out.params['sigma'].value < 1.5)
def test_stepmodel_erf(): x, y = get_data() stepmod = StepModel(form='linear') const = ConstantModel() pars = stepmod.guess(y, x) pars = pars + const.make_params(c=3 * y.min()) mod = stepmod + const out = mod.fit(y, pars, x=x) assert (out.nfev > 5) assert (out.nvarys == 4) assert (out.chisqr > 1) assert (out.params['c'].value > 3) assert (out.params['center'].value > 1) assert (out.params['center'].value < 4) assert (out.params['amplitude'].value > 50) assert (out.params['sigma'].value > 0.2) assert (out.params['sigma'].value < 1.5)
def fit_lm_g(x,y,inits): ##https://stackoverflow.com/questions/44573896/python-fit-gaussian-to-noisy-data-with-lmfit # gmodel = LorentzianModel() # gmodel = VoigtModel() gmodel = GaussianModel() cmodel = ConstantModel() model = gmodel + cmodel params = model.make_params(sigma = inits[2], amplitude = inits[0], center = inits[1]) result = model.fit(y, params, x=x) # print(params) return result
def make_multiplegaussian_model(self, no_of_gauss=None): """ This method creates a model of multiple gaussians with an offset. The parameters are: 'amplitude', 'center', 'sigma', 'fwhm' and offset 'c'. For function see: http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html#models.LorentzianModel @return lmfit.model.CompositeModel model: Returns an object of the class CompositeModel @return lmfit.parameter.Parameters params: Returns an object of the class Parameters with all parameters for the lorentzian model. """ model = ConstantModel() for ii in range(no_of_gauss): model += GaussianModel(prefix='gaussian{0}_'.format(ii)) params = model.make_params() return model, params
def abel_invert(self, y_lim, x_range, parameters=None, model=None): if model is None: # Create the lmfit model model = GaussianModel() model += ConstantModel() params = model.make_params() params['c'].set(0.45) params['center'].set(0, vary=False) params['sigma'].set(min=0.001) if parameters is not None: for key, value in parameters.items(): params[key].set(**value) f = FloatProgress(min=0.3, max=4.5) display(f) fit_data = [] abel_data = [] xx = x_range self.abel_extent = [-xx, xx, y_lim[0], y_lim[1]] for yy in np.arange(y_lim[0], y_lim[1], 1 / self.scale): f.value = yy self.create_lineout(start=(yy, -xx), end=(yy, xx), lineout_width_mm=1 / self.scale) # The data obtained by the lineout y = self.lo x = self.mm out = model.fit(y, params, x=x) fit_data.append(out.best_fit) abel_data.append( self.abel_gauss(x, out.best_values['sigma'], out.best_values['amplitude']) * 10) #*10 converts from mm^-1 to cm^-1 # Change the lists to numpy arrays and flip them fit_data = np.array(fit_data)[::-1] abel_data = np.array(abel_data)[::-1] extent = [-x_range, x_range, y_lim[0], y_lim[1]] origin = [ int(len(fit_data) + y_lim[0] * self.scale), int(len(fit_data[0]) / 2) ] self.fit = DMFromArray(fit_data, self.scale, extent=extent, origin=origin) self.abel = DMFromArray(abel_data, self.scale, extent=extent, origin=origin) return self.fit, self.abel
def prepare_model(nexp): emodel = ConstantModel() + ExponentialModel(prefix='a') + ExponentialModel( prefix='b') pars.add('e', value=0, min=0) pars.add('cntrl', value=1, min=1 - 1e-5, max=1 + 1e-5) pars['cntrl'].expr = 'c' pars['cntrl'].vary = True expr = '{}amplitude' all_expr = '' for i in range(1, 1): pars['cntrl'].expr += ' + ' + expr.format(Prefixes[i]) return emodel, pars
def GaussConst(signal, guess): """ Fits a Gaussian function Plots fwhm and 2*sigma gap widths for comparison with the analytically calculated one """ amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center=centre, sigma=stdev, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center'].min = centre - 5. pars['gauss_center'].max = centre + 5. pars['gauss_sigma'].max = stdev + 5. mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) fwhm = result.best_values['gauss_sigma'] #* 2.3548 centr = result.best_values['gauss_center'] # Values within two stdevs i.e. 95% pl.plot(np.repeat(centr - fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') pl.plot(np.repeat(centr + fwhm * 2, len(Y)), np.arange(len(Y)), 'b-', label="Sigma * 2") pl.plot(np.repeat(centr - fwhm * 2.3548 / 2., len(Y)), np.arange(len(Y)), 'y--') pl.plot(np.repeat(centr + fwhm * 2.3548 / 2., len(Y)), np.arange(len(Y)), 'y--', label="FWHM") return X, result.best_fit, result.best_values['gauss_sigma'] * 4, centr
def Step(signal, guess): if guess == False: return [0, 0, 0] else: amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] step_mod = StepModel(prefix='step') const_mod = ConstantModel(prefix='const_') pars = step_mod.guess(Y, x=X, center=centre) pars += const_mod.guess(Y, x=X) mod = step_mod + const_mod result = mod.fit(Y, pars, x=X) # write error report #print result.fit_report() return X, result.best_fit, result.redchi, 0
def pyfxcor(inspec, template, obj, vmin=-400., vmax=400., res=3, rej=200): rv, cc = pyasl.crosscorrRV(inspec[0], inspec[1], template[0], template[1], vmin, vmax, res, skipedge=rej) cen_gs = np.argmax(cc) perfx, perfy = rv[cen_gs-5:cen_gs+6], cc[cen_gs-5:cen_gs+6] try: gauss = ConstantModel() + GaussianModel() pars = gauss.make_params() pars['center'].set(value=rv[np.argmax(cc)], vary=True) pars['amplitude'].set(value=max(cc), vary=True) pars['sigma'].set(vary=True) pars['c'].set(value=0, vary=True) out = gauss.fit(perfy, pars, x=perfx) ct = out.best_values['center'] cterr = out.params['center'].stderr except: plt.plot(inspec[0], inspec[1]) plt.savefig(obj+'.png', dpi=300) pl.clf() return 'error', '' plt.subplot(311) plt.plot(rv, cc) curraxlim = plt.axis() out.plot_fit(numpoints=100) plt.axis(curraxlim) plt.subplot(312) plt.plot(obj[1][0], obj[1][1], 'r-', linewidth=0.5) plt.subplot(313) plt.plot(inspec[0], inspec[1], 'b-', linewidth=0.5) plt.savefig(obj[0]+'.png', dpi=300) plt.clf() return ct, cterr
def GaussStepConst(signal, guess): """ Fits high contrast data very well """ if guess == False: return [0, 0, 0] else: amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] # gauss_mod = Model(gaussian) gauss_mod = Model(gaussian) const_mod = ConstantModel() step_mod = StepModel(prefix='step') gauss_mod.set_param_hint('width', value = stdev / 2., min=stdev / 3., max=stdev) gauss_mod.set_param_hint('fwhm', expr='2.3548*width') pars = gauss_mod.make_params(height=amp, center=centre, width=stdev / 2., offset=offset) pars += step_mod.guess(Y, x=X, center=centre) pars += const_mod.guess(Y, x=X) pars['width'].vary = False mod = const_mod + gauss_mod + step_mod result = mod.fit(Y, pars, x=X) # write error report #print result.fit_report() fwhm = result.best_values['width'] * 2.3548 return X, result.best_fit, result.redchi, fwhm
cont = 3.0 # continuum level randamp = 3. # amplitude of gaussian noise x = np.arange(0,xmax) y = randamp * np.random.randn(xmax) + jrr.spec.onegaus(x, aa, bb, cc, cont) err = randamp * np.random.randn(xmax) plt.plot(x, y, color='black') # Let's try fitting that gaussian w the python version of MPFIT p0 = (50., xmax/2, 5, 2) fa = {'x':x, 'y':y, 'err':err} m = mpfit.mpfit(myfunct, p0, functkw=fa) # There has got to be a less kludgy way to do line below bestfit = jrr.spec.onegaus(x, m.params[0], m.params[1], m.params[2], m.params[3]) plt.plot(x, bestfit, color='blue') # The same, but with LMFIT mod1 = GaussianModel() mod2 = ConstantModel() # The continuum level mod = mod1 + mod2 pars = mod1.guess(y, x=x) + mod2.guess(y, x=x) # This is cool. It made rough guesses for us. pars['c'].min = 0 # Set bounds on continuum pars['c'].max = 10 # Set bounds on continuum #pars['amplitude'].vary = False # Fix a parameter out = mod.fit(y, pars, x=x, weights=1/err**2) # Fitting is done here. plt.plot(x, out.best_fit, color='orange') print(out.fit_report(min_correl=0.25)) plt.show() # This is actually more elegant. I think I should learn LMFIT and use it...
def lmfit_mngauss(x,y, *params): """ Fit multiple gaussians from two spectra that are multiplied together INPUT: x - is the wavelength array y - is the normalized flux params - is a tuple of 2 list/arrays of initial guess values for the each spectras parameters (this controls the number of gaussians to be fitted number of gaussians: len(params)/3 - 3 parameters per Gaussian) OUTPUT: mod - the lmfit model object used for the fit out - the lmfit fit object that contains all the results of the fit init- array with the initial guess model (usefull to see the initial guess when plotting) """ m_params = params[0] m_mods = [] prefixes = [] for i in range(0, len(m_params), 3): pref = "gm%02i_" % (i/3) gauss_i = GaussianModel(prefix=pref) if i == 0: pars = gauss_i.guess(y, x=x) else: pars.update(gauss_i.make_params()) A = m_params[i] l_cen = m_params[i+1] sigma = m_params[i+2] pars[pref+'amplitude'].set(A) pars[pref+'center'].set(l_cen) pars[pref+'sigma'].set(sigma) m_mods.append(gauss_i) prefixes.append(pref) m_mod = m_mods[0] if len(m_mods) > 1: for m in m_mods[1:]: m_mod += m m_one = ConstantModel(prefix="m_one_") prefixes.append("m_one_") pars.update(m_one.make_params()) pars['m_one_c'].set(value=1, vary=False) try: n_params = params[1] n_mods = [] #prefixes = [] for j in range(0, len(n_params), 3): pref = "gn%02i_" % (j/3) gauss_j = GaussianModel(prefix=pref) pars.update(gauss_j.make_params()) A = n_params[j] l_cen = n_params[j+1] sigma = n_params[j+2] pars[pref+'amplitude'].set(A) pars[pref+'center'].set(l_cen) pars[pref+'sigma'].set(sigma) n_mods.append(gauss_j) prefixes.append(pref) n_mod = n_mods[0] if len(n_mods) > 1: for n in n_mods[1:]: n_mod += n n_one = ConstantModel(prefix="n_one_") prefixes.append("n_one_") pars.update(n_one.make_params()) pars['n_one_c'].set(value=1, vary=False) mod = (m_one + m_mod) * (n_one + n_mod) except: print("Error with second spectra, only fitting first") mod = m_one + m_mod init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) print("Printed prefixes", prefixes) #print(init) return mod, out, init
def call_constant(x, y, ylock): const = ConstantModel(prefix='constant_') pars = const.guess(y, x=x) pars['constant_c'].set(ylock, min=ylock-0.01, max=ylock+0.0001) return const, pars
def CurveFitting(self, frec, Pxx, iaf, ax): 'Non-Linear Least-Squares Minimization and Curve-Fitting for Python' # ----- adjusting a model to the obtained PSD ----- # model 1: constante g1 = ConstantModel(prefix = 'g1_') pars = g1.guess(Pxx, x = frec) pars['g1_c'].set(0) # model 2: k2/f^-1 g2 = PowerLawModel(prefix = 'g2_') pars += g2.guess(Pxx, x = frec) pars['g2_exponent'].set(-1) #model 3: probability density function g3 = GaussianModel(prefix = 'g3_') pars += g3.guess(Pxx, x = frec) pars['g3_center'].set(iaf, min = iaf-2, max = iaf+2) # model 4: probability density function g4 = GaussianModel(prefix = 'g4_') pars += g4.guess(Pxx, x = frec) pars['g4_center'].set(20, min = 16, max = 25) # final model gA = g1 + g2 + g3 + g4 outA = gA.fit(Pxx, pars, x = frec) diffA= np.sum(Pxx - outA.best_fit) gB = g1 + g2 + g3 outB = gB.fit(Pxx, pars, x = frec) diffB= np.sum(Pxx - outB.best_fit) gC = g1 + g2 outC = gC.fit(Pxx, pars, x = frec) diffC= np.sum(Pxx - outC.best_fit) diffs= np.abs([diffA, diffB, diffC]) idx = np.where(diffs == np.min(diffs))[0][0] out = [outA, outB, outC][idx] # ----- plotting the desire PSD ----- # original and fitted curves ax.plot(frec, Pxx, 'k', linewidth = 2, label = 'PSD') ax.plot(frec, out.best_fit, 'b.-', linewidth = 2, markersize = 9, label ='BestModel') ax.set_xlim(frec[0], 32) ax.set_ylim(ymin = 0) ax.tick_params(axis = 'both', labelsize = 16) ax.set_xlabel('Frequency [Hz]', fontsize = 'x-large') ax.grid() # components of the fitted curved comps = out.eval_components(x = frec) g12 = comps['g1_'] + comps['g2_'] ax.plot(frec, g12, 'g--', linewidth = 2, label = 'PowerLawModel') idx1, idx2 = np.where(frec >= 5)[0][0], np.where(frec <= 15)[0][-1] # final value on the subplot if out != outC: diffs = out.best_fit[idx1:idx2] - g12[idx1:idx2] peak1 = np.amax(diffs) idx = np.where(diffs == peak1)[0] idx+= len(out.best_fit[:idx1]) ax.plot((frec[idx],frec[idx]), (g12[idx],out.best_fit[idx]), 'r-o', linewidth = 3, markersize = 9) ax.text(frec[idx], g12[idx], str(np.around(peak1, decimals=2)), horizontalalignment='right', verticalalignment='top', color='r', fontsize='xx-large') else: peak1 = 0 # optional valued on the subplot diffs = Pxx[idx1:idx2] - g12[idx1:idx2] peak2 = np.amax(diffs) idx = np.where(peak2 == diffs)[0] idx+= len(Pxx[:idx1]) ax.plot((frec[idx],frec[idx]), (g12[idx], Pxx[idx]), 'r-*', linewidth = 3, markersize = 11) ax.text(frec[idx], Pxx[idx], str(np.around(peak2, decimals=2)), horizontalalignment='left', verticalalignment='top', color='r', fontsize='xx-large') ax.legend(loc='upper right', shadow=True) return peak1, peak2