def gauss(x, y): print( 'Selecione a regiao do fit gaussiano quantas vezes for necessario') l1, l2 = fit_gauss(x, y) index1 = np.where(abs(x - l1) == min(abs(x - l1)))[0] index1 = np.int(index1) index2 = np.where(abs(x - l2) == min(abs(x - l2)))[0] index2 = np.int(index2) print(index1, index2) x1 = x[index1:index2] y1 = y[index1:index2] mod = GaussianModel() pars = mod.guess(y1, x=x1) out = mod.fit(y1, pars, x=x1) xgauss = copy.copy(x1) ygauss = copy.copy(out.best_fit) #-####### x0 = x[0:index1] y0 = np.zeros(len(y[0:index1])) x2 = x[index2:] y2 = np.zeros(len(y[index2:])) x1 = np.append(x0, x1) x1 = np.append(x1, x2) y1 = np.append(y0, out.best_fit) y1 = np.append(y1, y2) print(out.fit_report(min_correl=0.25)) mod = GaussianModel() pars = mod.guess(y1, x=x1) out = mod.fit(y1, pars, x=x1) #-####### return x1, out.best_fit, xgauss, ygauss
def test_default_inputs_gauss(): area = 1 cen = 0 std = 0.2 x = np.arange(-3, 3, 0.01) y = gaussian(x, area, cen, std) g = GaussianModel() fit_option1 = {'maxfev': 5000, 'xtol': 1e-2} result1 = g.fit(y, x=x, amplitude=1, center=0, sigma=0.5, fit_kws=fit_option1) fit_option2 = {'maxfev': 5000, 'xtol': 1e-6} result2 = g.fit(y, x=x, amplitude=1, center=0, sigma=0.5, fit_kws=fit_option2) assert result1.values != result2.values
def fit(self): logging.info("Running 1D summed fit...") x_mg, y_mg = np.arange(self.shot.width), np.arange(self.shot.height) x_data, y_data = ( np.sum(self.fit_data, axis=0), np.ravel(np.sum(self.fit_data, axis=1)), ) model = GaussianModel() x_result = model.fit(x_data, x=x_mg, center=self.shot.width / 2) y_result = model.fit(y_data, x=y_mg, center=self.shot.height / 2) return x_result, y_result
def GaussCalc(x, y, x1, y1): y = removerBackground(y) y1 = removerBackground(y1) mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) mod = GaussianModel() pars1 = mod.guess(y1, x=x1) out1 = mod.fit(y1, pars1, x=x1) center = out.best_values['center'] sigma = Decon_Gau(out.best_values['sigma'], out1.best_values['sigma']) return ScherrerEquation(sigma, center)
def fit_to_gaussian(self, x, y): gmodel = GaussianModel() params = gmodel.guess(y, x=x) c = params['center'].value n = len(y) q3 = ((np.max(x) - c) / 2) + c min_x = np.min(x) q1 = ((params['center'].value - min_x) / 2) + min_x s = params['sigma'].value h = params['height'].value max_y = np.max(y) if np.max([h, max_y]) < 0.5: amp = 1 / n diff_h = 0.6 - h gmodel.set_param_hint('amplitude', value=amp) gmodel.set_param_hint('amplitude', max=amp * (1 + diff_h)) gmodel.set_param_hint('amplitude', min=amp * diff_h) gmodel.set_param_hint('center', value=c) gmodel.set_param_hint('center', max=q3) gmodel.set_param_hint('center', min=q1) gmodel.set_param_hint('sigma', value=s) gmodel.set_param_hint('sigma', min=s / 2) gmodel.set_param_hint('sigma', max=s * 1.5) gmodel.set_param_hint('height', min=0.6) result = gmodel.fit(y, x=x) # gmodel.print_param_hints() report = result.fit_report() chi_re = re.compile(r'chi-square\s+=\s+([0-9.]+)') cor_re = re.compile(r'C\(sigma, amplitude\)\s+=\s+([0-9.-]+)') chis = np.float32(chi_re.findall(report)) cors = np.float32(cor_re.findall(report)) coeffs = np.concatenate((chis, cors)) mse_model = self.assess_fit(y, result.init_fit - result.best_fit) mse_yhat = self.assess_fit(y, result.residual) return mse_model, mse_yhat, result, report, coeffs
def fit_profile(profile, guess): "Fit a profile to a Gaussian + Contant" x = np.arange(len(profile)) model = GaussianModel(missing='drop') + ConstantModel(missing='drop') result = model.fit(profile, x=x, verbose=False, **guess) return result
def gaussian(x, y): # Gaussian fit to a curve x_shifted = x - x.min() # Shifting to 0 y_shifted = y - y.min() # Shifting to 0 mod = GaussianModel() # Setting model type pars = mod.guess(y_shifted, x=x_shifted) # Estimating fit out = mod.fit(y_shifted, pars, x=x_shifted) # Fitting fit print(out.fit_report(min_correl=0.25)) # Outputting best fit results #print("Gaussian FWHM = ", out.params['fwhm'].value) # Outputting only FWHM out.plot() # Plotting fit std = np.std(x_shifted) mux = np.mean(x_shifted) h_y = np.max(out.best_fit) #print(std, mux, h_y) y_x = h_y/2 x_i = mux - np.sqrt(2*(std**2)* np.log((np.sqrt(2*np.pi)*y_x*std)/ (h_y))) x_f = mux + np.sqrt(2*(std**2)* np.log((np.sqrt(2*np.pi)*y_x*std)/ (h_y))) fwhm = x_f-x_i print(x_i, x_f, fwhm)
def fit(les_x_init, les_y_init, remove): les_x = [] les_y = [] for i in range(len(les_x_init)): if les_x_init[i] not in remove: les_x.append(les_x_init[i]) les_y.append(les_y_init[i]) x = scipy.asarray(les_x) y = scipy.asarray(les_y) gmod = GaussianModel() param = gmod.guess(y, x=x) amplitude = param['amplitude'].value center = param['center'].value sigma = param['sigma'].value the_fit = gmod.fit(y, x=x, amplitude=amplitude, center=center, sigma=sigma) best_res = the_fit.chisqr amplitude = the_fit.params['amplitude'].value center = the_fit.params['center'].value sigma = the_fit.params['sigma'].value best_sol = [amplitude, center, sigma] y_fit = [] for i in range(len(les_x_init)): y_fit.append( gmod.eval(x=les_x_init[i], amplitude=amplitude, center=center, sigma=sigma)) return [best_sol, best_res, y_fit]
def SPErough(data, n_channel_s): fit_input, bins, check = SPE_input(data) amplitude = get_amp(data) gauss = GaussianModel(prefix='g_') s, bins = np.histogram(amplitude, bins=bins) topnoise = fit_input[0] valley = fit_input[1] endvalley = fit_input[2] spebump = fit_input[3] endbin = fit_input[4] idx_1 = endvalley idx_2 = spebump + (spebump-endvalley) if idx_1 < endvalley: idx_1 = endvalley if idx_2 > endbin: idx_2 = endbin if check == 1: gauss.set_param_hint('g_height', value=s[spebump], min=s[spebump]-30, max=s[spebump]+30) gauss.set_param_hint('g_center', value=bins[spebump], min=bins[spebump]-30, max=bins[spebump]+30) gauss.set_param_hint('g_sigma', value=idx_2-idx_1, max=(idx_2-idx_1)+30) result = gauss.fit(s[idx_1:idx_2], x=bins[idx_1:idx_2], weights=1.0/np.sqrt(s[idx_1:idx_2])) else: gauss = 0 result = 0 return gauss, result
def test_lmfit(): """ load data """ wave, flux, flux_err = np.loadtxt( '/hydrogen/projects/song/delCep_order20.dat').T flux_sine = 1 - flux flux_sine = flux_sine * sinebell_like(flux, 1.0) flux_obs = flux_sine + np.random.randn(*flux_sine.shape) * 0.1 wave_mod = wave wave_obs = wave flux_mod = flux_sine rv_grid = np.linspace(-500, 500, 1000) # z_grid = rv_grid / constants.c.value * 1000 ccfv = xcorr_rvgrid(wave_obs, flux_obs, wave_mod, flux_mod, mask_obs=None, rv_grid=rv_grid, sinebell_idx=1) # Gaussian fit using LMFIT from lmfit.models import GaussianModel mod = GaussianModel() x, y = ccfv[0], ccfv[1] # pars = mod.guess(y, x=x) out = mod.fit(y, None, x=x, method="least_squares") # out = mod.fit(y, pars, x=x, method="leastsq") plt.figure() plt.plot(x, y) plt.plot(x, out.best_fit) print(out.fit_report())
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 refine_energies(self, frame_width: int = 20) -> List[Tuple[float, Any]]: """ Refine energy locations using curve fitting. For every peak in `.energies`, a small slice of the data around it is curve fitted to a gaussian and the center used as the refined energy location. Will set the property `.refined_energies` equal to function output Note: The detector energy channel is a `float` here Parameters: frame_width (int): The width of the slice of data around the peak used for curve fitting Returns: (List[Tuple[float, Any]]): List of energy locations as tuple (detector energy channel, actual energy) """ model = GaussianModel() refined = [] for energy in self.energies: domain = (int(max(energy[0] - frame_width / 2, 0)), int( min(energy[0] + frame_width / 2, self.data.shape[0] - 1))) frame = self.data[domain[0]:domain[1]] pars = model.guess(frame, x=np.arange(0, 20)) out = model.fit(frame, pars, x=np.arange(0, 20)) refined.append((out.params["center"].value + domain[0], energy[1])) self.refined_energies = refined self.polynomial_coefficients = None return refined
def peakFit(self, x, y, model = 'gau', pi = None, di = None): ti = time.time() if pi: NumPeaks = len(pi) center = [] fwhm = [] amp = [] numVal = len(x) for i in range(NumPeaks): pImin = pi[i]-di if pImin < 0: pImin = 0 pImax = pi[i] + di if pImax > (numVal-1): pImax = numVal-1 __y = y[pImin:pImax] __x = x[pImin:pImax] __y = np.power(10,__y/10) #np.array(y)- np.min(y) mod = GaussianModel() pars = mod.guess(__y, x=__x) out = mod.fit(__y, pars, x=__x) center.append(out.best_values['center']) fwhm.append(out.best_values['sigma']*2.3548) amp.append(out.best_values['amplitude']) #print 'fit:', time.time()-ti return center, fwhm ,amp
def _fit_gauss(xval, yval): model = GaussianModel() result = model.fit(yval, model.guess(yval, x=xval, amplitude=np.max(yval)), x=xval) return result
def fit_and_plot_scan(self): # self.ui.result_textBrowser.append("Starting Scan Fitting") print("Starting Scan Fitting") try: """Define starting and stopping wavelength values here""" start_nm = int(self.ui.start_nm_spinBox.value()) stop_nm = int(self.ui.stop_nm_spinBox.value()) ref = self.bck_file index = (ref[:, 0] > start_nm) & (ref[:, 0] < stop_nm) x = self.wavelengths x = x[index] data_array = self.intensities result_dict = {} for i in range(data_array.shape[0]): y = data_array[i, index] # intensity yref = ref[index, 1] y = y - yref # background correction y = y - np.mean( y[(x > start_nm) & (x < start_nm + 25)]) # removing any remaining bckgrnd gmodel = GaussianModel(prefix='g1_') # calling gaussian model pars = gmodel.guess(y, x=x) # parameters - center, width, height result = gmodel.fit(y, pars, x=x, nan_policy='propagate') result_dict["result_" + str(i)] = result # self.ui.result_textBrowser.append("Scan Fitting Complete!") print("Scan Fitting Complete!") filename = QtWidgets.QFileDialog.getSaveFileName(self) pickle.dump(result_dict, open(filename[0] + "_fit_result_dict.pkl", "wb")) # self.ui.result_textBrowser.append("Data Saved!") print("Data Saved!") except Exception as e: self.ui.result_textBrowser2.append(str(e)) pass # self.ui.result_textBrowser.append("Loading Fit Data and Plotting") print("Loading Fit Data and Plotting") try: self.fit_scan_file = pickle.load( open(filename[0] + "_fit_result_dict.pkl", 'rb')) self.plot_fit_scan() except Exception as e: self.ui.result_textBrowser2.append(str(e)) pass
def fit(self, xx, yy, fitType): xx = np.asarray(xx) yy = np.asarray(yy) print("XX", xx) print("YY", yy) print(len(xx)) print(len(yy)) print("XX", xx) x1 = xx[0] x2 = xx[-1] y1 = yy[0] y2 = yy[-1] m = (y2 - y1) / (x2 - x1) b = y2 - m * x2 if fitType == "Gaussian": mod = GaussianModel() elif fitType == "Lorentzian": mod = LorentzianModel() else: mod = VoigtModel() pars = mod.guess(yy, x=xx, slope=m) print(pars) mod = mod + LinearModel() pars.add('intercept', value=b, vary=True) pars.add('slope', value=m, vary=True) out = mod.fit(yy, pars, x=xx) return out.best_fit
def find_fraunhofer_center(field: np.ndarray, ic: np.ndarray, debug: bool = False) -> float: """Extract the field at which the Fraunhofer is centered. Parameters ---------- field : np.ndarray 1D array of the magnetic field applied of the JJ. ic : np.ndarray 1D array of the JJ critical current. Returns ------- float Field at which the center of the pattern is located. """ max_loc = np.argmax(ic) width, *_ = peak_widths(ic, [max_loc], rel_height=0.5) width_index = int(round(width[0] * 0.65)) subset_field = field[max_loc - width_index:max_loc + width_index + 1] subset_ic = ic[max_loc - width_index:max_loc + width_index + 1] model = GaussianModel() params = model.guess(subset_ic, subset_field) out = model.fit(subset_ic, params, x=subset_field) if debug: plt.figure() plt.plot(field, ic) plt.plot(subset_field, out.best_fit) plt.show() return out.best_values["center"]
def get_plume_gaussian_model(dat, img_width): '''returns a single gaussian fit for the pd series provided dat = horizontal row of plume time average df''' mod = GaussianModel() pars = mod.guess(dat, x=img_width) # guesses starting value for gaussian out = mod.fit(dat, pars, x=img_width) # finds best fit of gaussian return out
def fitSimpleHist(array, title='E5XX', nbins=25, xlabel='mytit', verbose=False, savedir=None, fileappendix='', ax=None): """ Simple Gaussian fit to an array of datapoints. Output can be saved to file if wanted Input Argument: array -- np.array of input points title -- title of graph. Will also be the filename nbins -- number of histogram bins xlabel -- label on x-axis verbose -- T/F print the fit report savedir -- Directory to save output to, if not specified nothing will be saved. Suggest os.getcwd() or '.' fileappendix -- will add "_fileappendix" to the filename specified by title. """ gausfit = GaussianModel() if (ax == None): fig, ax = plt.subplots(figsize=(15, 3), nrows=1, ncols=1) redarray = array[array >= (array.mean() - 5 * array.std() )] # and array<= (array.mean()+ 5*array.std())] n, bins, patches = ax.hist( redarray[redarray <= array.mean() + 5 * array.std()], nbins) cbins = np.zeros(len(bins) - 1) for k in (range(0, len(bins) - 1)): cbins[k] = (bins[k] + bins[k + 1]) / 2 pars = gausfit.guess(n, x=cbins) fitresult = gausfit.fit(n, pars, x=cbins) if (verbose): print(fitresult.fit_report()) ax.plot(cbins, fitresult.best_fit, 'r-', linewidth=2) mean = fitresult.best_values['center'] fwhm = 2.35 * fitresult.best_values['sigma'] textstring = ' Mean : ' + '{:4.3f}'.format(mean) + '\n' textstring += ' FWHM : ' + '{:4.3f}'.format(fwhm) props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) ax.text(0.05, 0.95, textstring, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props) ax.set_xlabel(xlabel) ax.set_ylabel('Frequency') ax.set_title(title) if savedir != None: filename = os.path.join(savedir, title) if (fileappendix != ''): filename += '_' + fileappendix filename += '.png' plt.savefig(filename, dpi=200, bbox_inches='tight') # plt.show() # return return fitresult
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 fit_gaussian(self, array_x, array_y, figure_number): mod = GaussianModel() pars = mod.guess(array_y, x=array_x) out = mod.fit(array_y, pars, x=array_x) self.sigma_temp = out.params['sigma'].value self.amplitude_temp = out.params['amplitude'].value self.center_temp = out.params['center'].value self.plot_fit_function(array_x, figure_number) return self.sigma_temp, self.amplitude_temp, self.center_temp
def test_default_inputs_gauss(): area = 1 cen = 0 std = 0.2 x = np.arange(-3, 3, 0.01) y = gaussian(x, area, cen, std) g = GaussianModel() fit_option1 = {'maxfev': 5000, 'xtol': 1e-2} result1 = g.fit(y, x=x, amplitude=1, center=0, sigma=0.5, fit_kws=fit_option1) fit_option2 = {'maxfev': 5000, 'xtol': 1e-6} result2 = g.fit(y, x=x, amplitude=1, center=0, sigma=0.5, fit_kws=fit_option2) assert_true(result1.values!=result2.values) return
def fit_gaussian(self): mod = GaussianModel() pars = mod.guess(self.result[:, 1], x=self.result[:, 0]) out = mod.fit(self.result[:, 1], pars, x=self.result[:, 0]) self.sigma = out.params['sigma'].value self.amp = out.params['amplitude'].value self.center = out.params['center'].value print('sigma:' + str(self.sigma), 'amp:' + str(self.amp), 'center' + str(self.center)) self.plot_fit_function(1) return self.sigma, self.amp, self.center
def gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): x, y = self.background_correction() gmodel = GaussianModel(prefix='g1_') # calling gaussian model pars = gmodel.guess(y, x=x) # parameters - center, width, height pars['g1_center'].set(peak_pos, min=min_max_range[0], max=min_max_range[1]) pars['g1_sigma'].set(sigma) result = gmodel.fit(y, pars, x=x, nan_policy='propagate') return result #770 760 780 sigma 15
def bootg(data, flareinds, ind, st=40, end=130, indiv=False, num=100, offset=0): '''Bootstrap gaussian fit for one flare. Inputs: ------- data: sog4 flareinds: flareinds ind: index of flare to bootstrap (used to get inds from flareinds if indiv False) st: used as start index if indiv True end: used as end index if indiv True indiv: use individual index arguments (st,end) rather than ind, which then references flareinds (default False) num: number of bootstrap iterations (default 100) offset: gaussian vertical offset Outputs: -------- bsouts: list of bootstrap model results bsfits: DataFrame with parameters from each bootstrap iteration ''' if indiv: ind1, ind2 = st, end else: ind1, ind2 = flareinds[ind][0], flareinds[ind][1] bsouts = [] for i in range(num): #bootstrap indices of first flare bs = sk.resample(np.arange(ind1, ind2)) bst = np.array(data['MJD-50000'][bs]) bsi = np.array(data['I mag'][bs]) x = bst #uses original (not detrended) data y = np.max(bsi) - bsi + offset mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) bsouts.append(out) bsfits = pd.DataFrame(columns=['center', 'sigma', 'fwhm', 'height', 'amp']) bsfits['center'] = np.zeros(num) #adding to DataFrame i = 0 for b in bsouts: bsfits['center'][i] = b.params['center'].value bsfits['fwhm'][i] = b.params['fwhm'].value bsfits['height'][i] = b.params['height'].value bsfits['amp'][i] = b.params['amplitude'].value bsfits['sigma'][i] = b.params['sigma'].value i += 1 #returns list of model results and DataFrame with compiled best fit parameter values return bsouts, bsfits
def gaussian_fit(x, y, title_name): mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) plt.figure() plt.plot(x, y) plt.plot(x, out.best_fit, 'r-') plt.title(title_name) print(out.fit_report(min_correl = 0.25)) print('Center at ' + str(out.best_values['center']) + ' Angstrom') plt.show()
def fit_curve(ps_list): #--input:ps_list, (x,y) x = np.array([r[0] for r in ps_list]) y = np.array([r[1] for r in ps_list]) mod = GaussianModel() pars = mod.guess(y, x=x) bestresult = mod.fit(y, pars, x=x) return (bestresult.best_fit,x,y,getfloat_attr(bestresult, 'chisqr'),bestresult)
def gaussian_fit(x, y, title_name): mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) plt.figure() plt.plot(x, y) plt.plot(x, out.best_fit, 'r-') plt.title(title_name) print(out.fit_report(min_correl=0.25)) print('Center at ' + str(out.best_values['center']) + ' Angstrom') plt.show()
def fit_gaussian(x, y, debug=False): mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x, weights=(1 / (np.sqrt(y)))) print(out.fit_report()) if debug: plt.figure() out.plot_fit() plt.show() # return out.params['center'].value,out.params['center'].stderr return out.params['center'].value, out.params['sigma'].value
def gaussian_fit(x, y, title_name): mod = GaussianModel() pars = mod.guess(y, x=x) #pars = mod.make_params(amplitude = -2000, sigma = 1, center = 6562.801) out = mod.fit(y, pars, x=x) plt.figure() plt.plot(x, y) plt.plot(x, out.best_fit, 'r-') plt.title(title_name) print(out.fit_report(min_correl = 0.25)) print('Center at ' + str(out.best_values['center']) + ' Angstrom') plt.show()
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 gaussian_fit(x, y, title_name): mod = GaussianModel() pars = mod.guess(y, x=x) #pars = mod.make_params(amplitude = -2000, sigma = 1, center = 6562.801) out = mod.fit(y, pars, x=x) plt.figure() plt.plot(x, y) plt.plot(x, out.best_fit, 'r-') plt.title(title_name) print(out.fit_report(min_correl=0.25)) print('Center at ' + str(out.best_values['center']) + ' Angstrom') plt.show()
def fluxError(self, counts, wavelength, error, continuum): flux_vector = [] E_W_vector = [] cont_avg = np.mean(continuum) #plt.close('all') for i in range(100): #plt.errorbar(wavelength, counts, yerr=error) new_counts = [] j = 0 for point in counts: new_counts.append(np.random.normal(point, error[j])) j = j + 1 new_counts = np.array(new_counts) #So for each N in 1000 a new counts vector is generated randomly #Take this data against the wavelength values and fit a gaussian #each time to compute the flux. Append this to a vector and then #find the standard deviation to get the flux error for that emission line #Note this is to be encorporated in the fitLines module so that each of the emission #lines is fit in turn. Next step here is to construct the model with lmfit, #guess the initial parameters and then fit the gaussian and take #out.best_values('amplitude') as the flux and store in flux_vector #Now use the lmfit package to perform gaussian fits to the data #Construct the gaussian model mod = GaussianModel() #Take an initial guess at what the model parameters are #In this case the gaussian model has three parameters, #Which are amplitude, center and sigma pars = mod.guess(new_counts, x=wavelength) #We know from the redshift what the center of the gaussian is, set this #And choose the option not to vary this parameter #Leave the guessed values of the other parameters pars['center'].set(value=np.mean(wavelength)) #Now perform the fit to the data using the set and guessed parameters #And the inverse variance weights form the fits file out = mod.fit(new_counts, pars, x=wavelength) flux = out.best_values['amplitude'] E_W = out.best_values['amplitude'] / cont_avg flux_vector.append(flux) E_W_vector.append(E_W) #plt.scatter(wavelength, new_counts) #plt.plot(wavelength, out.best_fit) print flux_vector #Now return the standard deviation of the flux_vector as the flux error return { 'flux_error': np.std(flux_vector), 'E_W_error': np.std(E_W_vector) }
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' eknown = xray_line(elem, family)[0]/1000.0 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] 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 gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): x,y = self.background_correction() if self.fit_in_eV is True: peak_pos = 1240/peak_pos sigma = 1240/sigma min_max_range = np.sort(1240/np.asarray(min_max_range)) gmodel = GaussianModel(prefix = 'g1_') # calling gaussian model pars = gmodel.guess(y, x=x) # parameters - center, width, height pars['g1_center'].set(peak_pos, min=min_max_range[0], max=min_max_range[1]) pars['g1_sigma'].set(sigma) result = gmodel.fit(y, pars, x=x, nan_policy='propagate') return result
def fluxError(counts, wavelength, error, continuum): flux_vector = [] E_W_vector = [] cont_avg = np.mean(continuum) #plt.close('all') for i in range(100): #plt.errorbar(wavelength, counts, yerr=error) new_counts=[] j = 0 for point in counts: new_counts.append(np.random.normal(point, error[j])) j = j + 1 new_counts = np.array(new_counts) #So for each N in 1000 a new counts vector is generated randomly #Take this data against the wavelength values and fit a gaussian #each time to compute the flux. Append this to a vector and then #find the standard deviation to get the flux error for that emission line #Note this is to be encorporated in the fitLines module so that each of the emission #lines is fit in turn. Next step here is to construct the model with lmfit, #guess the initial parameters and then fit the gaussian and take #out.best_values('amplitude') as the flux and store in flux_vector #Now use the lmfit package to perform gaussian fits to the data #Construct the gaussian model mod = GaussianModel() #Take an initial guess at what the model parameters are #In this case the gaussian model has three parameters, #Which are amplitude, center and sigma pars = mod.guess(new_counts, x=wavelength) #We know from the redshift what the center of the gaussian is, set this #And choose the option not to vary this parameter #Leave the guessed values of the other parameters pars['center'].set(value = np.mean(wavelength)) #Now perform the fit to the data using the set and guessed parameters #And the inverse variance weights form the fits file out = mod.fit(new_counts, pars, x=wavelength) flux = out.best_values['amplitude'] E_W = out.best_values['amplitude'] / cont_avg flux_vector.append(flux) E_W_vector.append(E_W) #plt.scatter(wavelength, new_counts) #plt.plot(wavelength, out.best_fit) print 'Hello', flux_vector #Now return the standard deviation of the flux_vector as the flux error return {'flux_error' : np.std(flux_vector), 'E_W_error' : np.std(E_W_vector)}
def get_peak_fit(spectrum, actual_peak_info): """ This method fits the peak with a model and returns the fitted curve with fit information. """ theoretical_mz = actual_peak_info['expected_mz'] peak_region = ms_operator.get_peak_fitting_region_2( spectrum, actual_peak_info['index']) x, y, is_apex_flat = ms_operator.get_peak_fitting_values( spectrum, peak_region) g_model = GaussianModel() g_pars = g_model.guess(y, x=x) g_out = g_model.fit(y, g_pars, x=x) # define d as peak resolution (i.e. width on the 50% of the height) d, predicted_peak_mz = ms_operator.get_peak_width_and_predicted_mz( peak_region, spectrum, g_out) xc = numpy.linspace(predicted_peak_mz - prf * d, predicted_peak_mz + prf * d, 5001) yc = g_out.eval(x=xc) # find absolute mass accuracy and ppm for signal related to fit signal_fit_mass_diff = float(x[numpy.where(y == max(y))] - predicted_peak_mz) signal_fit_ppm = signal_fit_mass_diff / predicted_peak_mz * 10**6 # find absolute mass accuracy and ppm for fit related to expected (theoretical) value fit_theory_mass_diff = abs(predicted_peak_mz - theoretical_mz) fit_theory_ppm = fit_theory_mass_diff / theoretical_mz * 10**6 fit_info = { 'model': 'gaussian', 'goodness-of-fit': [g_out.redchi, g_out.aic, g_out.bic], # goodness-of-fit is reduced chi-squared 'fit_theory_absolute_ma': fit_theory_mass_diff, # fitted absolute mass accuracy 'fit_theory_ppm': fit_theory_ppm, # ppm between fitted peak mz and expected (theoretical) mz 'resolution': d, 'raw_intensity_array': y, 'is_apex_flat': is_apex_flat, # probably redundant information 'signal_fit_absolute_ma': signal_fit_mass_diff, 'signal_fit_ppm': signal_fit_ppm } return xc, yc, fit_info
def peakFit(self, x, y): if len(x) == 0: y = self.getdBmSpec() y = y[self.__scalePos] x = self.__scaledWavelength y = np.power(10,y/10) mod = GaussianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.25)) center = out.best_values['center'] fwhm = out.best_values['sigma']*2.3548 return center, fwhm#, amp
def fit_gaussian(y,x): x=array(x) y=array(y) mod=GaussianModel() pars=mod.guess(y,x=x) result=mod.fit(y,pars,x=x) a=result.params['amplitude'].value b=result.params['center'].value c=result.params['sigma'].value best=result.best_fit chsqred=result.redchi chisq=result.chisqr fwhm=result.params['fwhm'].value return a,b,c,best,fwhm,chisq,chsqred
def test_itercb(): x = np.linspace(0, 20, 401) y = gaussian(x, amplitude=24.56, center=7.6543, sigma=1.23) y = y - .20*x + 3.333 + np.random.normal(scale=0.23, size=len(x)) mod = GaussianModel(prefix='peak_') + LinearModel(prefix='bkg_') pars = mod.make_params(peak_amplitude=21.0, peak_center=7.0, peak_sigma=2.0, bkg_intercept=2, bkg_slope=0.0) out = mod.fit(y, pars, x=x, iter_cb=per_iteration) assert(out.nfev == 23) assert(out.aborted) assert(not out.errorbars) assert(not out.success)
def test_reports_created(): """do a simple Model fit but with all the bells-and-whistles and verify that the reports are created """ x = np.linspace(0, 12, 601) data = gaussian(x, amplitude=36.4, center=6.70, sigma=0.88) data = data + np.random.normal(size=len(x), scale=3.2) model = GaussianModel() params = model.make_params(amplitude=50, center=5, sigma=2) params['amplitude'].min = 0 params['sigma'].min = 0 params['sigma'].brute_step = 0.001 result = model.fit(data, params, x=x) report = result.fit_report() assert(len(report) > 500) html_params = result.params._repr_html_() assert(len(html_params) > 500) html_report = result._repr_html_() assert(len(html_report) > 1000)
#!/usr/bin/env python # <examples/doc_model_savemodelresult.py> import matplotlib.pyplot as plt import numpy as np from lmfit.model import save_modelresult from lmfit.models import GaussianModel data = np.loadtxt('model1d_gauss.dat') x = data[:, 0] y = data[:, 1] gmodel = GaussianModel() result = gmodel.fit(y, x=x, amplitude=5, center=5, sigma=1) save_modelresult(result, 'gauss_modelresult.sav') print(result.fit_report()) plt.plot(x, y, 'bo') plt.plot(x, result.init_fit, 'k--') plt.plot(x, result.best_fit, 'r-') plt.show() # <end examples/doc_model_savemodelresult.py>
# ax_res_y2.set_yticks((ax_res.get_yticks() / 100) * yNorm) for xticklabel in ax.get_xticklabels(): xticklabel.set_visible(False) for xticklabel in axy2.get_xticklabels(): xticklabel.set_visible(False) ax.get_yticklabels()[0].set_visible(False) axy2.get_yticklabels()[0].set_visible(False) ax_res.get_yticklabels()[-1].set_visible(False) ax_res_y2.get_yticklabels()[-1].set_visible(False) if legend: ax.legend(loc='best') ax_res.set_xlabel(xlabel) ax.set_ylabel(ylabel) return fig, [ax, axy2, ax_res, ax_res_y2] if __name__ == '__main__': from functions import gaussian from lmfit.models import GaussianModel x = np.linspace(-3, 3, 200) y = gaussian(x, sigma=0.5) * (1 + np.random.normal(0, 0.1, len(x))) gmod = GaussianModel() para = gmod.guess(y, x=x) gfit = gmod.fit(y, para, x=x) models = [gfit.init_fit, gfit.best_fit] plt.close('all') fig, axes = plotResidual(x, y, models, yNorm=1.0, yThresh=0.1) axes[0].set_ylabel('relative [%]') axes[1].set_ylabel('absolute') axes[2].set_xlabel('xxx') plt.show()
def _gen(self): # We checked in the __init__ that this import works. from lmfit.models import GaussianModel, LinearModel # For thread safety (paranoia) make copies of stuff dets = self.detectors target_field = self.target_field motor = self.motor initial_center = self.initial_center initial_width = self.initial_width tol = self.tolerance min_cen = self.min_cen max_cen = self.max_cen seen_x = deque() seen_y = deque() for x in np.linspace( initial_center - self.RANGE * initial_width, initial_center + self.RANGE * initial_width, self.NUM_SAMPLES, endpoint=True, ): yield Msg("set", motor, x) yield Msg("create") ret_mot = yield Msg("read", motor) key, = ret_mot.keys() seen_x.append(ret_mot[key]["value"]) for det in dets: yield Msg("trigger", det, block_group="B") for det in dets: yield Msg("wait", None, "B") for det in dets: ret_det = yield Msg("read", det) if target_field in ret_det: seen_y.append(ret_det[target_field]["value"]) yield Msg("save") model = GaussianModel() + LinearModel() guesses = { "amplitude": np.max(seen_y), "center": initial_center, "sigma": initial_width, "slope": 0, "intercept": 0, } while True: x = np.asarray(seen_x) y = np.asarray(seen_y) res = model.fit(y, x=x, **guesses) old_guess = guesses guesses = res.values if np.abs(old_guess["center"] - guesses["center"]) < tol: break next_cen = np.clip(guesses["center"] + np.random.randn(1) * guesses["sigma"], min_cen, max_cen) yield Msg("set", motor, next_cen) yield Msg("create") ret_mot = yield Msg("read", motor) key, = ret_mot.keys() seen_x.append(ret_mot[key]["value"]) for det in dets: yield Msg("trigger", det, block_group="B") for det in dets: yield Msg("wait", None, "B") for det in dets: ret_det = yield Msg("read", det) if target_field in ret_det: seen_y.append(ret_det[target_field]["value"]) yield Msg("save") yield Msg("set", motor, np.clip(guesses["center"], min_cen, max_cen)) if self.output_mutable is not None: self.output_mutable.update(guesses) self.output_mutable["x"] = np.array(seen_x) self.output_mutable["y"] = np.array(seen_y) self.output_mutable["model"] = res
out.append('%s=%.3f' % (key, val)) print ', '.join(out) print args, kws x = linspace(0., 20, 401) y = gaussian(x, amplitude=24.56, center=7.6543, sigma=1.23) y = y - .20*x + 3.333 + random.normal(scale=0.23, size=len(x)) mod = GaussianModel(prefix='peak_') + LinearModel(prefix='bkg_') pars = mod.make_params() pars['peak_amplitude'].value = 3.0 pars['peak_center'].value = 6.0 pars['peak_sigma'].value = 2.0 pars['bkg_intercept'].value = 0.0 pars['bkg_slope'].value = 0.0 out = mod.fit(y, pars, x=x, iter_cb=per_iteration) pylab.plot(x, y, 'b--') # print(' Nfev = ', out.nfev) print( out.fit_report()) pylab.plot(x, out.best_fit, 'k-') pylab.show() #<end examples/doc_with_itercb.py>
def _gen(self): # We checked in the __init__ that this import works. from lmfit.models import GaussianModel, LinearModel # For thread safety (paranoia) make copies of stuff dets = self.detectors target_field = self.target_field motor = self.motor initial_center = self.initial_center initial_width = self.initial_width tol = self.tolerance min_cen = self.min_cen max_cen = self.max_cen seen_x = deque() seen_y = deque() for x in np.linspace(initial_center - self.RANGE * initial_width, initial_center + self.RANGE * initial_width, self.NUM_SAMPLES, endpoint=True): yield Msg('set', motor, x) yield Msg('create') ret_mot = yield Msg('read', motor) key, = ret_mot.keys() seen_x.append(ret_mot[key]['value']) for det in dets: yield Msg('trigger', det, block_group='B') for det in dets: yield Msg('wait', None, 'B') for det in dets: ret_det = yield Msg('read', det) if target_field in ret_det: seen_y.append(ret_det[target_field]['value']) yield Msg('save') model = GaussianModel() + LinearModel() guesses = {'amplitude': np.max(seen_y), 'center': initial_center, 'sigma': initial_width, 'slope': 0, 'intercept': 0} while True: x = np.asarray(seen_x) y = np.asarray(seen_y) res = model.fit(y, x=x, **guesses) old_guess = guesses guesses = res.values if np.abs(old_guess['center'] - guesses['center']) < tol: break next_cen = np.clip(guesses['center'] + np.random.randn(1) * guesses['sigma'], min_cen, max_cen) yield Msg('set', motor, next_cen) yield Msg('create') ret_mot = yield Msg('read', motor) key, = ret_mot.keys() seen_x.append(ret_mot[key]['value']) for det in dets: yield Msg('trigger', det, block_group='B') for det in dets: yield Msg('wait', None, 'B') for det in dets: ret_det = yield Msg('read', det) if target_field in ret_det: seen_y.append(ret_det[target_field]['value']) yield Msg('save') yield Msg('set', motor, np.clip(guesses['center'], min_cen, max_cen)) if self.output_mutable is not None: self.output_mutable.update(guesses) self.output_mutable['x'] = np.array(seen_x) self.output_mutable['y'] = np.array(seen_y) self.output_mutable['model'] = res
#Module Preparing import numpy as np import matplotlib.pyplot as plt ''' 也可以使用import pylab as pl ''' from lmfit.models import GaussianModel #Read data from file data=np.loadtxt('**实验数据文件**') x=data[:,0] y=data[:,1] #Preparing the Model model=GaussianModel() pars=model.guess(y,x=x) #Do the fit result=model.fit(y,pars,x=x) #Print the fit result print(result.fit_report(min_correl=0.25)) #Draw the plot pl.plot(x,y,color='red',linestyle='--') pl.plot(x,result.best_fit,color='blue',linestyle='-') #Tobe Continue
# MODEL = 'loren' # MODEL = 'voigt' # gamma_free = True if MODEL.lower().startswith('g'): mod = GaussianModel() gamma_free = False figname = '../doc/_images/models_peak1.png' elif MODEL.lower().startswith('l'): mod = LorentzianModel() gamma_free = False figname = '../doc/_images/models_peak2.png' elif MODEL.lower().startswith('v'): mod = VoigtModel() figname = '../doc/_images/models_peak3.png' pars = mod.guess(y, x=x) if gamma_free: pars['gamma'].set(value=0.7, vary=True, expr='') figname = '../doc/_images/models_peak4.png' out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.25)) plt.plot(x, y, 'b-') plt.plot(x, out.best_fit, 'r-') # plt.savefig(figname) plt.show() # <end examples/doc_builtinmodels_peakmodels.py>
def measure_line_index(wave, flux, flux_err=None, mask=None, z=None, line_info=None, num_refit=(100, None), filepath=None, return_type='dict', verbose=False): """ Measure line index / EW and have it plotted Parameters ---------- wave: array-like wavelength vector flux: array-like flux vector flux_err: array-like flux error vector (optional) If un-specified, auto-generate an np.ones array mask: array-like andmask or ormask (optional) If un-specified, auto-generate an np.ones array (evenly weighted) line_info: dict information about spectral line, eg: line_info_dib5780 = {'line_center': 5780, 'line_range': (5775, 5785), 'line_shoulder_left': (5755, 5775), 'line_shoulder_right': (5805, 5825)} num_refit: non-negative integer number of refitting. If 0, no refit will be performed If positive, refits will be performed after adding normal random noise z: float redshift (only specify when z is large) filepath: string path of the diagnostic figure if None, do nothing, else print diagnostic figure return_type: string 'dict' or 'array' if 'array', np.array(return dict.values()) verbose: bool if True, print details Returns ------- line_indx: dict A dictionary type result of line index. If any problem encountered, return the default result (filled with nan). """ try: # 0. do some input check # 0.1> check line_info line_info_keys = line_info.keys() assert 'line_range' in line_info_keys assert 'line_shoulder_left' in line_info_keys assert 'line_shoulder_right' in line_info_keys # 0.2> check line range/shoulder in spectral range assert np.min(wave) <= line_info['line_shoulder_left'][0] assert np.max(wave) >= line_info['line_shoulder_right'][0] # 1. get line information # line_center = line_info['line_center'] # not used line_range = line_info['line_range'] line_shoulder_left = line_info['line_shoulder_left'] line_shoulder_right = line_info['line_shoulder_right'] # 2. shift spectra to rest-frame wave = np.array(wave) flux = np.array(flux) if z is not None: wave /= 1. + z # 3. estimate the local continuum # 3.1> shoulder wavelength range ind_shoulder = np.any([ np.all([wave > line_shoulder_left[0], wave < line_shoulder_left[1]], axis=0), np.all([wave > line_shoulder_right[0], wave < line_shoulder_right[1]], axis=0)], axis=0) wave_shoulder = wave[ind_shoulder] flux_shoulder = flux[ind_shoulder] # 3.2> integrated/fitted wavelength range ind_range = np.logical_and(wave > line_range[0], wave < line_range[1]) wave_range = wave[ind_range] flux_range = flux[ind_range] # flux_err_range = flux_err[ind_range] # not used mask_range = mask[ind_range] flux_err_shoulder = flux_err[ind_shoulder] # mask_shoulder = mask[ind_shoulder] # not used # 4. linear model mod_linear = LinearModel(prefix='mod_linear_') par_linear = mod_linear.guess(flux_shoulder, x=wave_shoulder) # ############################################# # # to see the parameter names: # # model_linear.param_names # # {'linear_fun_intercept', 'linear_fun_slope'} # # ############################################# # out_linear = mod_linear.fit(flux_shoulder, par_linear, x=wave_shoulder, method='leastsq') # 5. estimate continuum cont_shoulder = out_linear.best_fit noise_std = np.std(flux_shoulder / cont_shoulder) cont_range = mod_linear.eval(out_linear.params, x=wave_range) resi_range = 1 - flux_range / cont_range # 6.1 Integrated EW ( # estimate EW_int wave_diff = np.diff(wave_range) wave_step = np.mean(np.vstack([np.hstack([wave_diff[0], wave_diff]), np.hstack([wave_diff, wave_diff[-1]])]), axis=0) EW_int = np.dot(resi_range, wave_step) # estimate EW_int_err num_refit_ = num_refit[0] if num_refit_ is not None and num_refit_>0: EW_int_err = np.std(np.dot( (resi_range.reshape(1, -1).repeat(num_refit_, axis=0) + np.random.randn(num_refit_, resi_range.size) * noise_std), wave_step)) # 6.2 Gaussian model # estimate EW_fit mod_gauss = GaussianModel(prefix='mod_gauss_') par_gauss = mod_gauss.guess(resi_range, x=wave_range) out_gauss = mod_gauss.fit(resi_range, par_gauss, x=wave_range) line_indx = collections.OrderedDict([ ('SN_local_flux_err', np.median(flux_shoulder / flux_err_shoulder)), ('SN_local_flux_std', 1. / noise_std), ('num_bad_pixel', np.sum(mask_range != 0)), ('EW_int', EW_int), ('EW_int_err', EW_int_err), ('mod_linear_slope', out_linear.params[mod_linear.prefix + 'slope'].value), ('mod_linear_slope_err', out_linear.params[mod_linear.prefix + 'slope'].stderr), ('mod_linear_intercept', out_linear.params[mod_linear.prefix + 'intercept'].value), ('mod_linear_intercept_err', out_linear.params[mod_linear.prefix + 'intercept'].stderr), ('mod_gauss_amplitude', out_gauss.params[mod_gauss.prefix + 'amplitude'].value), ('mod_gauss_amplitude_err', out_gauss.params[mod_gauss.prefix + 'amplitude'].stderr), ('mod_gauss_center', out_gauss.params[mod_gauss.prefix + 'center'].value), ('mod_gauss_center_err', out_gauss.params[mod_gauss.prefix + 'center'].stderr), ('mod_gauss_sigma', out_gauss.params[mod_gauss.prefix + 'sigma'].value), ('mod_gauss_sigma_err', out_gauss.params[mod_gauss.prefix + 'sigma'].stderr), ('mod_gauss_amplitude_std', np.nan), ('mod_gauss_center_std', np.nan), ('mod_gauss_sigma_std', np.nan)]) # estimate EW_fit_err num_refit_ = num_refit[1] if num_refit_ is not None and num_refit_ > 2: # {'mod_gauss_amplitude', # 'mod_gauss_center', # 'mod_gauss_fwhm', # 'mod_gauss_sigma'} out_gauss_refit_amplitude = np.zeros(num_refit_) out_gauss_refit_center = np.zeros(num_refit_) out_gauss_refit_sigma = np.zeros(num_refit_) # noise_fit = np.random.randn(num_refit,resi_range.size)*noise_std for i in range(int(num_refit_)): # resi_range_with_noise = resi_range + noise_fit[i,:] resi_range_with_noise = resi_range + \ np.random.randn(resi_range.size) * noise_std out_gauss_refit = mod_gauss.fit(resi_range_with_noise, par_gauss, x=wave_range) out_gauss_refit_amplitude[i],\ out_gauss_refit_center[i],\ out_gauss_refit_sigma[i] =\ out_gauss_refit.params[mod_gauss.prefix + 'amplitude'].value,\ out_gauss_refit.params[mod_gauss.prefix + 'center'].value,\ out_gauss_refit.params[mod_gauss.prefix + 'sigma'].value print(out_gauss_refit_amplitude[i], out_gauss_refit_center[i], out_gauss_refit_sigma[i]) line_indx.update({'mod_gauss_amplitude_std': np.nanstd(out_gauss_refit_amplitude), 'mod_gauss_center_std': np.nanstd(out_gauss_refit_center), 'mod_gauss_sigma_std': np.nanstd(out_gauss_refit_sigma)}) # 7. plot and save image if filepath is not None and os.path.exists(os.path.dirname(filepath)): save_image_line_indice(filepath, wave, flux, ind_range, cont_range, ind_shoulder, line_info) # if necessary, convert to array # NOTE: for a non-ordered dict the order of keys and values may change! if return_type == 'array': return np.array(line_indx.values()) return line_indx except Exception: return measure_line_index_null_result(return_type)
import numpy as np from lmfit.models import GaussianModel data = np.loadtxt('model1d_gauss.dat') x = data[:, 0] y = data[:, 1] y[44] = np.nan y[65] = np.nan # nan_policy = 'raise' # nan_policy = 'propagate' nan_policy = 'omit' gmodel = GaussianModel() result = gmodel.fit(y, x=x, amplitude=5, center=6, sigma=1, nan_policy=nan_policy) print(result.fit_report()) # make sure nans are removed for plotting: x_ = x[np.where(np.isfinite(y))] y_ = y[np.where(np.isfinite(y))] plt.plot(x_, y_, 'bo') plt.plot(x_, result.init_fit, 'k--') plt.plot(x_, result.best_fit, 'r-') plt.show() # <end examples/doc_model_with_nan_policy.py>
dmu = (2. * A * (xx-mu)*s)/(np.pi * fac**2) return np.array([ds, dmu, da]) if __name__ == '__main__': xs = np.linspace(-4, 4, 100) print('**********************************') print('***** Test Gaussian **************') print('**********************************') ys = gaussian(xs, 2.5, 0, 0.5) yn = ys + 0.1*np.random.normal(size=len(xs)) mod = GaussianModel() pars = mod.guess(yn, xs) out = mod.fit(yn, pars, x=xs) out2 = mod.fit(yn, pars, x=xs, fit_kws={'Dfun': dfunc_gaussian, 'col_deriv': 1}) print('lmfit without dfunc **************') print('number of function calls: ', out.nfev) print('params', out.best_values) print('lmfit with dfunc *****************') print('number of function calls: ', out2.nfev) print('params', out2.best_values) print('\n \n') out2.plot(datafmt='.') print('**********************************') print('***** Test Lorentzian ************') print('**********************************') ys = lorentzian(xs, 2.5, 0, 0.5)
#!/usr/bin/env python #<examples/models_doc1.py> from numpy import loadtxt from lmfit import fit_report from lmfit.models import GaussianModel, VoigtModel import matplotlib.pyplot as plt data = loadtxt('test_peak.dat') x = data[:, 0] y = data[:, 1] gmodel = GaussianModel() gmodel.guess_starting_values(y, x=x) gresult = gmodel.fit(y, x=x) print 'With Gaussian: ' print fit_report(gresult.params, min_correl=0.25) print 'Chi-square = %.3f, Reduced Chi-square = %.3f' % (gresult.chisqr, gresult.redchi) plt.plot(x, y, 'k') plt.plot(x, 10*(y-gresult.best_fit), 'r-') vmodel = VoigtModel() vmodel.guess_starting_values(y, x=x) vresult = vmodel.fit(y, x=x) print 'With Voigt: ' print fit_report(vresult.params, min_correl=0.25) print 'Chi-square = %.3f, Reduced Chi-square = %.3f' % (vresult.chisqr, vresult.redchi)
def fitLines(self, flux, wavelength, z, weights): #Convert all into numpy arrays flux = np.array(flux) wavelength = np.array(wavelength) z = np.array(z) weights = np.array(weights) error = np.sqrt(1 / weights) #Fit a polynomial to the continuum background emission of the galaxy #This is the crude way to do it continuum_poly = self.fitPoly(flux, wavelength) #Can also compute the continuum in the more advanced way #masking the emission lines and using a moving average #Define the wavelength values of the relevant emission lines OII3727 = 3727.092 OII3729 = 3729.875 H_beta = 4862.721 OIII4959 = 4960.295 OIII5007 = 5008.239 H_alpha = 6564.614 NII6585 = 6585.27 SII6718 = 6718.29 SII6732 = 6732.68 #Now apply the redshift formula to find where this will be observed #Note that for these SDSS spectra the OII doublet is not in range OII3727_shifted = OII3727 * (1 + z) OII3729_shifted = OII3729 * (1 + z) H_beta_shifted = H_beta * (1 + z) OIII4959_shifted = OIII4959 * (1 + z) OIII5007_shifted = OIII5007 * (1 + z) H_alpha_shifted = H_alpha * (1 + z) NII6585_shifted = NII6585 * (1 + z) SII6718_shifted = SII6718 * (1 + z) SII6732_shifted = SII6732 * (1 + z) #hellofriend #Will choose to mask pm 15 for each of the lines H_beta_index = np.where(np.logical_and(wavelength>=(H_beta_shifted - 15), wavelength<=(H_beta_shifted + 15))) OIII_one_index = np.where(np.logical_and(wavelength>=(OIII4959_shifted - 15), wavelength<=(OIII4959_shifted + 15))) OIII_two_index = np.where(np.logical_and(wavelength>=(OIII5007_shifted - 15), wavelength<=(OIII5007_shifted + 15))) NII_one_index = np.where(np.logical_and(wavelength>=(NII6585_shifted - 15), wavelength<=(NII6585_shifted + 15))) H_alpha_index = np.where(np.logical_and(wavelength>=(H_alpha_shifted - 15), wavelength<=(H_alpha_shifted + 15))) SII_one_index = np.where(np.logical_and(wavelength>=(SII6718_shifted - 15), wavelength<=(SII6718_shifted + 15))) SII_two_index = np.where(np.logical_and(wavelength>=(SII6732_shifted - 15), wavelength<=(SII6732_shifted + 15))) #define the mask 1 values from the index values mask = np.zeros(len(flux)) mask[H_beta_index] = 1 mask[OIII_one_index] = 1 mask[OIII_two_index] = 1 mask[NII_one_index] = 1 mask[H_alpha_index] = 1 mask[SII_one_index] = 1 mask[SII_two_index] = 1 #Now apply these to the flux to mask masked_flux = ma.masked_array(flux, mask=mask) #Make my own with np.mean() continuum = np.empty(len(masked_flux)) for i in range(len(masked_flux)): if (i + 5) < len(masked_flux): continuum[i] = ma.mean(masked_flux[i:i+5]) if np.isnan(continuum[i]): continuum[i] = continuum[i - 1] else: continuum[i] = ma.mean(masked_flux[i-5:i]) if np.isnan(continuum[i]): continuum[i] = continuum[i - 1] #Subtract the continuum from the flux, just use polynomial fit right now counts = flux - continuum_poly #Construct a dictionary housing these shifted emission line values #Note that values for the OII doublet are not present line_dict = {'H_beta' : H_beta_shifted, 'OIII4959' : OIII4959_shifted, 'OIII5007' : OIII5007_shifted, 'H_alpha' : H_alpha_shifted, 'NII6585' : NII6585_shifted, 'SII6718' : SII6718_shifted, 'SII6732' : SII6732_shifted} #Plot the initial continuum subtracted spectrum plt.plot(wavelength, counts) #Initialise a dictionary for the results in the for loop results_dict = {} #Begin for loop to fit an arbitrary number of emission lines for key in line_dict: ######################################################################## #FITTING EACH OF THE EMISSION LINES IN TURN ######################################################################## #We don't want to include all the data in the gaussian fit #Look for the indices of the points closes to the wavelength value #The appropriate range is stored in fit_wavelength etc. #Use np.where to find the indices of data surrounding the gaussian new_index = np.where(np.logical_and(wavelength > (line_dict[key] - 10) , wavelength < (line_dict[key] + 10))) #Select only data for the fit with these indices fit_wavelength = wavelength[new_index] fit_counts = counts[new_index] fit_weights = weights[new_index] fit_continuum = continuum[new_index] fit_error = error[new_index] #Now use the lmfit package to perform gaussian fits to the data #Construct the gaussian model mod = GaussianModel() #Take an initial guess at what the model parameters are #In this case the gaussian model has three parameters, #Which are amplitude, center and sigma pars = mod.guess(fit_counts, x=fit_wavelength) #We know from the redshift what the center of the gaussian is, set this #And choose the option not to vary this parameter #Leave the guessed values of the other parameters pars['center'].set(value = line_dict[key]) pars['center'].set(vary = 'False') #Now perform the fit to the data using the set and guessed parameters #And the inverse variance weights form the fits file out = mod.fit(fit_counts, pars, weights = fit_weights, x=fit_wavelength) #print(out.fit_report(min_correl=0.25)) #Plot the results and the spectrum to check the fit plt.plot(fit_wavelength, out.best_fit, 'r-') #Return the error on the flux error_dict = self.fluxError(fit_counts, fit_wavelength, fit_error, continuum_poly) #Compute the equivalent width con_avg = np.mean(continuum_poly) E_w = out.best_values['amplitude'] / con_avg #The amplitude parameter is the area under the curve, equivalent to the flux results_dict[key] = [out.best_values['amplitude'], error_dict['flux_error'], out.best_values['sigma'], 2.3548200*out.best_values['sigma'], E_w, error_dict['E_W_error']] plt.show() #plt.savefig('fitted_spectrum.png') #The return dictionary for this method is a sequence of results vectors return results_dict