def make_lor(df,num,center,length): """ This method do a single-peak Lorentzian deconvolution for a given dataframe Parameters ---------- df : pandas dataframe df is a column-wise dataframe that records the data you want to deconvolve. num : int a positional keyword, indicating which index of center array the Lorentzian in this method is building its center on. center : array the array recording the centers of all peaks. length : float the maximum allowed variance in the optimized position of peaks from their initila values indicated in the center array. Returns ------- dict model: the single-peak Lorentzian corresponded. paras: the parameters optimized through this function. This is useful in updating the parameters object paras """ pref='l'+str(num)+'_' model=LorentzianModel(prefix=pref) paras.update(model.guess(df,x=norm.Energy,center=center[num])) name=pref+'center' paras[name].set(value=center[num],min=center[num]-length,max=center[num]+length) paras[pref+'amplitude'].set(min=0.0) paras[pref+'sigma'].set(min=0.01) return {'model':model,'paras':paras}
def check_energy(self, f, s, deg): p = int(np.argwhere(s == np.max(s))) freq = f[p] f_mask = (freq - 5e2 < f) & (f < freq + 5e2) x = f[f_mask] y = s[f_mask] mod = LorentzianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) power = si.simps(out.best_fit, x) l = const.c / self.F0 # Calculate corresponding energy with formula: $ E = 0.5 m_{\mathrm{e}} [f_{\mathrm{r}} \lambda_\Re / (2 \cos\theta)]^2 $ E_plasma = (0.5 * const.m_e * (freq * l / (2 * np.cos(deg * np.pi / 180)))**2 / const.eV) res = 0 if self.vol == 1: if bool(15.58 < E_plasma < 18.42): res = 1 elif bool(22.47 < E_plasma < 23.75): res = 2 else: if bool(20.29 < E_plasma < 22.05): res = 1 elif bool(22.45 < E_plasma < 23.87): res = 2 elif bool(25.38 < E_plasma < 27.14): res = 3 return power, res, freq
def test_imagefile_ops(self): self.a2.gridimage() self.a3.gridimage() self.a2.crop(5,-15,5,-5,_=True) self.a3.crop(5,-15,5,-5,_=True) self.b=self.a2//self.a3 self.assertEqual(self.b.shape,(90,80),"Failure to crop image correctly.") self.assertGreater(self.b.max(),0.047,"XMCD Ratio calculation failed") self.assertLess(self.b.min(),-0.05,"XMCD Ratio calculation failed") self.b.normalise() self.assertEqual(self.b.max(),1.0,"Normalise Image failed") self.assertEqual(self.b.min(),-1.0,"Normalise Image failed") self.profile=self.b.profile_line((0,0),(100,100)) self.profile.plot() self.b.mask=self.a2.image>25E3 self.hist=self.b.hist(bins=200) self.hist.column_headers=["XMCD Signal","Frequency"] self.hist.labels=None g1=LorentzianModel(prefix="g1_") g2=LorentzianModel(prefix="g2_") params=g1.make_params() params.update(g2.make_params()) double_peak=g1+g2 g1=np.argmax(self.hist.y[:100]) # Location of first peak g2=np.argmax(self.hist.y[100:])+100 for k, p in zip(params,[0.25,self.hist.x[g1],self.hist.y[g1]/np.sqrt(2),0.5,self.hist.y[g1], 0.25,self.hist.x[g2],self.hist.y[g2]/np.sqrt(2),0.5,self.hist.y[g2]]): params[k].value=p print(g1,g2,params) self.res=self.hist.lmfit(double_peak,p0=params,output="report") self.hist.add_column(self.res.init_fit,header="Initial Fit") self.hist.add_column(self.res.best_fit,header="Best Fit") self.hist.setas="xyyy" self.hist.plot(fmt=["b+","b--","r-"]) plt.close("all")
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 add_peak(prefix, center, amplitude=0.005, sigma=0.05): peak = LorentzianModel(prefix=prefix) pars = peak.make_params() pars[prefix + 'center'].set(center) pars[prefix + 'amplitude'].set(amplitude) pars[prefix + 'sigma'].set(sigma, min=0) return peak, pars
def fitLorentzian(x,y): signalGuess = max(y)-min(y) # centerGuess = x[np.argmax(y)] centerGuess = (max(x)+min(x))/2. span = max(x)-min(x) sigmaGuess = span/10. x_bg = np.concatenate((x[:10],x[10:])) y_bg = np.concatenate((y[:10],y[10:])) background = LinearModel() pars = background.guess(y_bg, x=x_bg) peak = LorentzianModel() pars.update( peak.make_params()) pars['center'].set(centerGuess)#,min=min(x),max=max(x)) pars['sigma'].set(sigmaGuess,max=span/2.) pars['amplitude'].set(signalGuess*sigmaGuess*np.pi,min=0.00000001) pars.add('signal', expr='amplitude/(sigma*pi)') pars.add('background', expr='intercept+slope*center') pars.add('contrast', expr='amplitude/(sigma*pi*background)') pars.add('centerDoubled', expr='2*center') pars.add('shift', expr='2*center-9192631770') pars.add('fwhmDoubled', expr='4*sigma') model = peak + background init = model.eval(pars, x=x) out = model.fit(y, pars, x=x) #print out.fit_report() return init,out
def lorFitFunc(fitOut,minimum,maximum,ptNumber=100,prefix=None): x = np.linspace(minimum,maximum,ptNumber) lorentzian = LorentzianModel() if prefix==None: params = fitOut.best_values else: params = getKeysWithoutPrefix(fitOut.best_values,prefix) lor = lorentzian.func(x=x,center=params["center"],sigma=params["sigma"],amplitude=params["amplitude"]) return x, lor
def calculateQ_1peak(filename, time, taper, lambda0, slope, modulation_coefficient, rg): q = readlvm(filename) q = q.ravel() q = q / taper - 1 valley = q.min() valley_index = np.argmin(q) q_valley = q[valley_index - rg:valley_index + rg] l_valley = time[valley_index - rg:valley_index + rg] q_valley = q_valley * -1 peaks, peak_info = find_peaks(q_valley, height=-valley) #results_half = peak_widths(q_valley, peaks, rel_height=0.5) mod = LorentzianModel() x = np.asarray(list(range(0, 2 * rg))) pars = mod.guess(q_valley, x=x) out = mod.fit(q_valley, pars, x=x) res = out.fit_report() info = res.split("\n") variables = parse_info(info, 1) h_res, w_res, c_res = variables['height'], variables['fwhm'], variables[ 'center'] print(h_res, w_res, c_res) l = lambda0 + l_valley[int(float(c_res))] * slope * modulation_coefficient d_lambda = (l_valley[1] - l_valley[0]) * float(w_res) * slope * modulation_coefficient Q = l / d_lambda return Q, float(h_res) * 100, l
def __LorentzianFit(self): """ Fitting by Lorentzian Lambda function will written in __LorentzianFunc Lorentzian parameter will be written in __fit_param amplitude: 'amplitude', center frequency: 'center', sigma: 'sigma', fwhm: 'fwhm', height: 'height' """ x, y = self.__freq, self.__intensity / self.__reference_intensity mod = LorentzianModel() pars = mod.guess(1 - y, x=x) out = mod.fit(1 - y, pars, x=x) def loren(a, x, x0, sigma): return a/np.pi * sigma / \ ((x-x0)**2+sigma**2) # Lorentzian template function self.__LorentzianFunc = lambda x: 1 - \ loren(out.values['amplitude'], x, out.values['center'], out.values['sigma']) self.__fit_param = out.values self.__CalcTemp(out.values['center'] * 1000)
def add_lz_peak(prefix: str, center: float, amplitude: float = 0.005, sigma: float = 0.05) -> Tuple[LorentzianModel, Parameters]: peak = LorentzianModel(prefix=prefix) pars = peak.make_params() pars[prefix + "center"].set(center) pars[prefix + "amplitude"].set(amplitude, min=0) pars[prefix + "sigma"].set(sigma, min=0) return peak, pars
def lor_mod(N): ''' Returns a model consisting of N lorentzian curves ''' # initialize model model = LorentzianModel(prefix='lor1_') # Add N-1 lorentzians for i in range(N - 1): model += LorentzianModel(prefix='lor' + str(i + 2) + '_') return model
def lorentzian_model_w_lims(self, peak_pos, sigma, min_max_range): x, y = self.background_correction() lmodel = LorentzianModel(prefix='l1_') # calling lorentzian model pars = lmodel.guess(y, x=x) # parameters - center, width, height pars['l1_center'].set(peak_pos, min=min_max_range[0], max=min_max_range[1]) pars['l1_sigma'].set(sigma) result = lmodel.fit(y, pars, x=x, nan_policy='propagate') return result
def mult_params_peaks_Lorentzian(x, y): #http://cars9.uchicago.edu/software/python/lmfit/builtin_models.html loren_mod1 = LorentzianModel(prefix='l1_') pars = loren_mod1.guess(y, x) loren_mod2 = LorentzianModel(prefix='l2_') pars.update(loren_mod2.make_params()) loren_mod3 = LorentzianModel(prefix='l3_') pars.update(loren_mod3.make_params()) mod = loren_mod1 + loren_mod2 + loren_mod3 init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.5)) plot_components = False plt.plot(x, y, 'b') plt.plot(x, init, 'k--') plt.plot(x, out.best_fit, 'r-') if plot_components: comps = out.eval_components(x=x) plt.plot(x, comps['l1_'], 'b--') plt.plot(x, comps['l2_'], 'b--') plt.plot(x, comps['l3_'], 'b--')
def fit(): global fitx global fity fitx =fitx fity =fity a.clear mod = LorentzianModel() pars = mod.guess(fity,x=fitx) out = mod.fit(fity,pars, x=fitx) a.plot(fitx, fity) dataPlot.draw()
def params_Lorentzian(x, y): mod = LorentzianModel() params = mod.guess(y, x) print(params) out = mod.fit(y, params, x=x) print(out.fit_report(min_correl=0.3)) init = mod.eval(params, x=x) plt.figure(2) plt.plot(x, y, 'b') plt.plot(x, init, 'k--') plt.plot(x, out.best_fit, 'r-')
def lorentzian(x, y): # Lorentzian fit to a curve x_shifted = x - x.min() # Shifting to 0 y_shifted = y - y.min() # Shifting to 0 mod = LorentzianModel() # 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("Lorentzian FWHM = ", out.params['fwhm'].value) # Outputting only FWHM out.plot() # Plotting fit
def fitsample(data, theta_initial, theta_final): x = data[:,0] y = data[:,1] m = (x > theta_initial) & (x < theta_final) x_fit = x[m] y_fit = y[m] pseudovoigt1 = VoigtModel(prefix = 'pv1_') pars= pseudovoigt1.make_params() pars['pv1_center'].set(13.5, min = 13.4, max = 13.6) pars['pv1_sigma'].set(0.05, min= 0.01, max = 0.1) pars['pv1_amplitude'].set(70, min = 1, max = 100) #pars['pv1_fraction'].set(0.5) lorentz2 = LorentzianModel(prefix = 'lor2_') pars.update(lorentz2.make_params()) pars['lor2_center'].set(13.60, min = 13.4, max = 13.9) pars['lor2_sigma'].set(0.1, min= 0.01) pars['lor2_amplitude'].set(10, min = 1, max = 50 ) #pars['lor2_fraction'].set(0.5) line1 = LinearModel(prefix ='l1_') pars.update(line1.make_params()) pars['l1_slope'].set(0) pars['l1_intercept'].set(240, min = 200, max = 280) mod = pseudovoigt1 + lorentz2 + line1 v = pars.valuesdict() result = mod.fit(y_fit, pars, x=x_fit) #print(result.fit_report()) pv1_pos = result.params['pv1_center'].value pv1_height = result.params['pv1_height'].value lor2_pos = result.params['lor2_center'].value lor2_height = result.params['lor2_height'].value #peak_area = pars['gau1_fwhm'].value*peak_amp #plt.xlim([theta_initial, theta_final]) #plt.ylim([100, 500]) #plt.semilogy(x_fit, y_fit, 'bo') #plt.semilogy (x_fit, result.init_fit, 'k--') #plt.semilogy(x_fit, result.best_fit, 'r-') #plt.show() return pv1_pos, pv1_height, lor2_pos, lor2_height
def fitcurve(self, w, f, xrange, nistlines, **kwargs): w = np.array(w)[xrange] f = np.array(f)[xrange] x = np.array(w) y = np.array(-f) + np.max( np.array(f)) #invert the spectrum upside down mod = LorentzianModel() pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) report = out.fit_report(min_correl=0.25) """extract lorentzian parameters from the report output""" center = float(report.split('center:')[1].split( '+/-', 1)[0]) #x (wavelenth) value of the maximum amp = float(report.split('amplitude:')[1].split( '+/-', 1)[0]) #y (flux) value of the maximum fwhm = float(report.split('fwhm:')[1].split( '+/-', 1)[0]) #full width at half maximum #get chi-squared value of the fit chi_sq = float( report.split('reduced chi-square')[0].split( 'chi-square = ')[1]) iterations = int( report.split('# data points')[0].split('# function evals = ')[1]) #Plot inverted data points, Lorentzian curve, and absorption lines from NIST fig = plt.figure(figsize=(6, 4)) plt.plot(x, y, 'bo', label='Inverted') plt.plot(x, out.best_fit, 'r-', color='g', label='Best Lorentz fit') line_error = [] for i in range(len(nistlines)): line_error.append(center - nistlines[i]) plt.axvline(x=nistlines[i], ymin=0, ymax=1, linewidth=.5, color='r') plt.axvline(x=center - fwhm, ymin=0, ymax=1, linewidth=.5, color='k') plt.axvline(x=center + fwhm, ymin=0, ymax=1, linewidth=.5, color='k') #Print summary for each fitted curve if kwargs.get('showCurv', True) == True: plt.show() print 'Center of function: ', center print 'Fit iterations: ', iterations print 'Chi-squared: ', chi_sq print 'Wavelength range: ', w[0], '-', w[-1] else: plt.close() #don't show plot return center, amp, fwhm, chi_sq, line_error
def test_PeakLogicFiles_add_lz_peak(mocker): TEST_PREFIX = "test" TEST_CENTER = -0.4 EXPECTED_PEAK = LorentzianModel(prefix="test") EXPECTED_PARAMS = EXPECTED_PEAK.make_params( center=-0.4, amplitude=0.005, sigma=0.05 ) mocker.patch("SWV_AnyPeakFinder.SWV_AnyPeakFinder.PeakFinderApp") app = swv.PeakFinderApp() logic = swv.PeakLogicFiles(app) _, actual_params = logic.add_lz_peak(TEST_PREFIX, TEST_CENTER) # assert EXPECTED_PEAK == actual_peak # FIXME assert EXPECTED_PARAMS == actual_params
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 ChoosePeakType(self, peaktype, i): """ This function helps to create the `CompositeModel() <https://lmfit.github.io/lmfit-py/model.html#lmfit.model.CompositeModel>`_ . Implemented models are: `GaussianModel() <https://lmfit.github.io/lmfit-py/builtin_models.html#lmfit.models.GaussianModel>`_ , `LorentzianModel() <https://lmfit.github.io/lmfit-py/builtin_models.html#lmfit.models.LorentzianModel>`_ , `VoigtModel() <https://lmfit.github.io/lmfit-py/builtin_models.html#lmfit.models.VoigtModel>`_ , `BreitWignerModel() <https://lmfit.github.io/lmfit-py/builtin_models.html#lmfit.models.BreitWignerModel>`_ . Parameters ---------- peaktype : string Possible line shapes of the peaks to fit are 'breit_wigner', 'lorentzian', 'gaussian', and 'voigt'. i : int Integer between 0 and (N-1) to distinguish between N peaks of the same peaktype. It is used in the prefix. Returns ------- lmfit.models.* : class Returns either VoigtModel(), BreitWignerModel(), LorentzianModel(), or GaussianModel() depending on the peaktype with *Model(prefix = prefix, nan_policy = 'omit'). The prefix contains the peaktype and i. """ prefix = peaktype + '_p' + str(i + 1) + '_' if peaktype == 'voigt': return VoigtModel(prefix=prefix, nan_policy='omit') elif peaktype == 'breit_wigner': return BreitWignerModel(prefix=prefix, nan_policy='omit') elif peaktype == 'lorentzian': return LorentzianModel(prefix=prefix, nan_policy='omit') elif peaktype == 'gaussian': return GaussianModel(prefix=prefix, nan_policy='omit')
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 __init__(self, type): self.peak = [None] * (defPar.NumPeaks) if type == 0: for i in range(0, defPar.NumPeaks): self.peak[i] = PseudoVoigtModel(prefix="p" + str(i) + "_") self.typec = "PseudoVoigt" elif type == 1: for i in range(0, defPar.NumPeaks): self.peak[i] = GaussianModel(prefix="p" + str(i) + "_") self.typec = "Gauss" elif type == 2: for i in range(0, defPar.NumPeaks): self.peak[i] = LorentzianModel(prefix="p" + str(i) + "_") self.typec = "Lorentz" elif type == 3: for i in range(0, defPar.NumPeaks): self.peak[i] = VoigtModel(prefix="p" + str(i) + "_") self.typec = "Voigt" else: print("Warning: type undefined. Using PseudoVoigt") for i in range(0, defPar.NumPeaks): self.peak[i] = PseudoVoigtModel(prefix="p" + str(i) + "_") self.typec = "PVoigt"
def __init__(self, name, motor, motor_field, center, sigma=1, amplitude=math.pi, noise_multiplier=None, **kwargs): # Eliminate noise if not requested noise = noise_multiplier or 0. lorentz = LorentzianModel() def func(): # Evaluate position in distribution m = motor.read()[motor_field]['value'] v = lorentz.eval(x=np.array(m), amplitude=amplitude, sigma=sigma, center=center) # Add uniform noise v += np.random.uniform(-1, 1) * noise return v # Instantiate Reader super().__init__(name=name, func=func, **kwargs)
def guess(self, y, x=None, **kwargs): r"""Guess starting values for the parameters of a model. Parameters ---------- y : :class:`~numpy:numpy.ndarray` Intensities x : :class:`~numpy:numpy.ndarray` energy values kwargs : dict additional optional arguments, passed to model function. Returns ------- :class:`~lmfit.parameter.Parameters` parameters with guessed values """ amplitude = 1.0 center = 0.0 tau = 1.0 dcf = 1.0 if x is not None: # Use guess method from the Lorentzian model p = LorentzianModel().guess(y, x) center = p['center'] # Assume diff*q*q and tau^(-1) same value tau = hbar / (2 * p['sigma']) dcf = 1.0 / (self.q * self.q * tau) return self.make_params(amplitude=amplitude, center=center, tau=tau, dcf=dcf)
def make_lorentzian_model(self): """ This method creates a model of lorentzian 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 object params: lmfit.parameter.Parameters object, returns an object of the class Parameters with all parameters for the lorentzian model. """ model = LorentzianModel() + ConstantModel() params = model.make_params() return model, params
def onclick(event): global X plt.clf() x = event.xdata y = event.ydata print('waint...') L1 = LorentzianModel(prefix='L1_') pars = L1.guess(psd, x=freq) pars.update(L1.make_params()) pars['L1_center'].set(x, min=x - 10, max=x + 10) #pars['L1_sigma'].set(y, min=0) pars['L1_amplitude'].set(y, min=0) out = L1.fit(psd, pars, x=freq) X = out.best_fit plt.title(str(ordem) + " Lorenzian fit") plt.ylabel('PSD[ppm$^2$/$\mu$Hz]') plt.xlabel('Frequency [$\mu$Hz]') plt.minorticks_on() plt.tick_params(direction='in', which='major', top=True, right=True, left=True, length=8, width=1, labelsize=15) plt.tick_params(direction='in', which='minor', top=True, right=True, length=5, width=1, labelsize=15) plt.tight_layout() plt.loglog(freq, psd, 'k', lw=0.5, alpha=0.5) plt.plot(freq, out.best_fit, 'k-', lw=0.5, alpha=0.5) plt.xlim(min(freq), max(freq)) plt.ylim(min(psd), max(psd)) plt.draw() print('Done')
def onePeakLorentzianFit(self): try: nRow, nCol = self.dockedOpt.fileInfo() self.gausFit.binFitData = plab.zeros((nRow, 0)) self.gausFit.OnePkFitData = plab.zeros( (nCol, 6)) # Creates the empty 2D List for j in range(nCol): yy = self.dockedOpt.TT[:, j] xx = plab.arange(0, len(yy)) x1 = xx[0] x2 = xx[-1] y1 = yy[0] y2 = yy[-1] m = (y2 - y1) / (x2 - x1) b = y2 - m * x2 mod = LorentzianModel() pars = mod.guess(yy, x=xx, slope=m) mod = mod + LinearModel() pars.add('intercept', value=b, vary=True) pars.add('slope', value=m, vary=True) out = mod.fit(yy, pars, x=xx, slope=m) self.gausFit.OnePkFitData[j, :] = ( out.best_values['amplitude'], 0, out.best_values['center'], 0, out.best_values['sigma'], 0) # Saves fitted data of each fit fitData = out.best_fit binFit = np.reshape(fitData, (len(fitData), 1)) self.gausFit.binFitData = np.concatenate( (self.gausFit.binFitData, binFit), axis=1) if self.gausFit.continueGraphingEachFit == True: self.gausFit.graphEachFitRawData(xx, yy, out.best_fit, 'L') return False except: return True
def guess_peak_lorentzian(data, x=None, **kwargs): y = np.abs(np.squeeze(np.real(data))) x = np.squeeze(x) idx = np.argsort(x) x = x[idx] y = y[idx] # prepare fitting a lorentzian m_lin = LinearModel() m_lorentzian = LorentzianModel() p_lin = m_lin.guess(y, x=x) p_lorentzian = m_lorentzian.guess(y - m_lin.eval(x=x, params=p_lin), x=x) m = m_lin + m_lorentzian p = p_lin + p_lorentzian r = m.fit(y, x=x, params=p) return (r.best_values["center"], r.best_values["sigma"], r.best_values["amplitude"] / (np.pi * r.best_values["sigma"]))
def twoPeakLorentzianFit(self): try: nRow, nCol = self.dockedOpt.fileInfo() self.gausFit.binFitData = zeros((nRow, 0)) self.gausFit.TwoPkGausFitData = zeros((nCol, 12)) # Creates the empty 2D List for j in range(nCol): yy1 = [] yy2 = [] yy = self.dockedOpt.TT[:, j] i = 0 for y in yy: if i < len(yy)/2: yy1.append(y) else: yy2.append(y) i += 1 xx = arange(0, len(yy)) xx1 = arange(0, len(yy)/2) xx2 = arange(len(yy)/2, len(yy)) x1 = xx[0] x2 = xx[-1] y1 = yy[0] y2 = yy[-1] m = (y2 - y1) / (x2 - x1) b = y2 - m * x2 mod1 = LorentzianModel(prefix='p1_') mod2 = LorentzianModel(prefix='p2_') pars1 = mod1.guess(yy1, x=xx1) pars2 = mod2.guess(yy2, x=xx2) mod = mod1 + mod2 + LinearModel() pars = pars1 + pars2 pars.add('intercept', value=b, vary=True) pars.add('slope', value=m, vary=True) out = mod.fit(yy, pars, x=xx, slope=m) self.gausFit.TwoPkGausFitData[j, :] = (out.best_values['p1_amplitude'], 0, out.best_values['p1_center'], 0, out.best_values['p1_sigma'], 0, out.best_values['p2_amplitude'], 0, out.best_values['p2_center'], 0, out.best_values['p2_sigma'], 0) # Saves fitted data of each fit fitData = out.best_fit binFit = np.reshape(fitData, (len(fitData), 1)) self.gausFit.binFitData = np.concatenate((self.gausFit.binFitData, binFit), axis=1) if self.gausFit.continueGraphingEachFit == True: self.gausFit.graphEachFitRawData(xx, yy, out.best_fit, 'L') return False except Exception as e: QMessageBox.warning(self.myMainWindow, "Error", "There was an error \n\n Exception: " + str(e)) return True
def test_imagefile_ops(self): self.a2.gridimage() self.a3.gridimage() self.a2.crop(5,-15,5,-5,_=True) self.a3.crop(5,-15,5,-5,_=True) self.b=self.a2//self.a3 self.assertEqual(self.b.shape,(90,80),"Failure to crop image correctly.") self.assertGreater(self.b.max(),0.047,"XMCD Ratio calculation failed") self.assertLess(self.b.min(),-0.05,"XMCD Ratio calculation failed") self.b.normalise() self.assertEqual(self.b.max(),1.0,"Normalise Image failed") self.assertEqual(self.b.min(),-1.0,"Normalise Image failed") self.profile=self.b.profile_line((0,0),(100,100)) self.profile.plot() self.b.mask=self.a2.image>25E3 self.hist=self.b.hist(bins=200) self.hist.column_headers=["XMCD Signal","Frequency"] self.hist.labels=None g1=LorentzianModel(prefix="g1_") g2=LorentzianModel(prefix="g2_") params=g1.make_params() params.update(g2.make_params()) double_peak=g1+g2 g1=np.argmax(self.hist.y[:100]) # Location of first peak g2=np.argmax(self.hist.y[100:])+100 for k, p in zip(params,[0.25,self.hist.x[g1],self.hist.y[g1]/np.sqrt(2),0.5,self.hist.y[g1], 0.25,self.hist.x[g2],self.hist.y[g2]/np.sqrt(2),0.5,self.hist.y[g2]]): params[k].value=p print(g1,g2,params) self.res=self.hist.lmfit(double_peak,p0=params,output="report") self.hist.add_column(self.res.init_fit,header="Initial Fit") self.hist.add_column(self.res.best_fit,header="Best Fit") self.hist.setas="xyyy" self.hist.plot(fmt=["b+","b--","r-"]) plt.close("all")
def fitDoubleLorentzian(x,y) : signalGuess = 0.5*(max(y)-min(y)) centerGuess = (max(x)+min(x))/2. span = max(x)-min(x) sigmaGuess = span/10. x_bg = np.concatenate((x[:10],x[10:])) y_bg = np.concatenate((y[:10],y[10:])) background = LinearModel() pars = background.guess(y_bg, x=x_bg) peak1 = LorentzianModel(prefix="p1_") pars.update(peak1.make_params()) pars['p1_center'].set(centerGuess,min=min(x),max=max(x)) pars['p1_sigma'].set(sigmaGuess,max=span/2.) pars['p1_amplitude'].set(signalGuess*sigmaGuess*np.pi,min=0.00000001) pars.add('p1_signal', expr='p1_amplitude/(p1_sigma*pi)') pars.add('background', expr='intercept+slope*p1_center') pars.add('p1_contrast', expr='p1_amplitude/(p1_sigma*pi*background)') pars.add('p1_centerDoubled', expr='2*p1_center') pars.add('p1_shift', expr='2*p1_center-9192631770') pars.add('p1_fwhmDoubled', expr='4*p1_sigma') peak2 = LorentzianModel(prefix="p2_") pars.update(peak2.make_params()) pars['p2_center'].set(centerGuess,min=min(x),max=max(x)) pars.add('broadScale',value=2.0, min=1.9, max=100.0) pars['p2_sigma'].set(sigmaGuess*2,max=span/2.,expr='p1_sigma*broadScale') pars['p2_amplitude'].set(signalGuess*sigmaGuess*np.pi,min=0.00000001) pars.add('p2_signal', expr='p2_amplitude/(p2_sigma*pi)') pars.add('p2_contrast', expr='p2_amplitude/(p2_sigma*pi*background)') pars.add('p2_centerDoubled', expr='2*p2_center') pars.add('p2_shift', expr='2*p2_center-9192631770') pars.add('p2_fwhmDoubled', expr='4*p2_sigma') model = peak1 + peak2 + background init = model.eval(pars, x=x) out = model.fit(y, pars, x=x) print out.fit_report() return init,out
def fit_lz_peaks(potentials, currents): min_y = float(min(currents)) model = QuadraticModel(prefix="Background") params = model.make_params() # a=0, b=0, c=0 params.add("a", 0, min=0) params.add("b", 0) params.add("c", 0, min=min_y) peak = LorentzianModel(prefix="peak") pars = peak.make_params() pars.add("center", -0.3) pars.add("amplitude", 0.005, min=0) pars.add("sigma", 0.05, min=0) model = model + peak params.update(pars) # _ = model.eval(params, x=potentials) # not needed result = model.fit(currents, params, x=potentials) comps = result.eval_components() return result.best_fit, float(max(comps["peak"]))
def fitTwoLorentzians(x,y): background = PolynomialModel(2) pars = background.make_params() peak1 = LorentzianModel(prefix='p1_') pars.update( peak1.make_params()) peak2 = LorentzianModel(prefix='p2_') pars.update( peak2.make_params()) # Guess some parameters from data to help the fitting span = max(x)-min(x) c1Guess = (y[-1]-y[0])/(x[-1]-x[0]) c0Guess = y[0]-c1Guess*x[0] bgGuess = background.func(x=x,c0=c0Guess,c1=c1Guess,c2=0) signalGuess=min(y-bgGuess) sigmaGuess = span/50. amplitudeGuess = signalGuess*(sigmaGuess*np.pi) # Fit variables initialization pars.add('splitting',value=min(x)+span*0.56,min=0.0000001,max=max(x)-min(x)) pars['c2'].set(0.) pars['c1'].set(c1Guess) pars['c0'].set(c0Guess) pars['p1_center'].set(min(x)+span*0.45,min=min(x),max=max(x)) pars['p2_center'].set(min(x)+span*0.55,expr='p1_center+splitting') # pars['p2_center'].set(min(x)+span*0.55,min=min(x),max=max(x)) pars['p1_amplitude'].set(amplitudeGuess,max=amplitudeGuess/100.) pars['p2_amplitude'].set(amplitudeGuess,max=amplitudeGuess/100.) pars['p1_sigma'].set(sigmaGuess, min=sigmaGuess/1000.,max=sigmaGuess*1000.) pars['p2_sigma'].set(sigmaGuess, min=sigmaGuess/1000.,max=sigmaGuess*1000.) #Add some useful parameters to evaluate pars.add('p1_signal', expr='p1_amplitude/(p1_sigma*pi)') pars.add('p2_signal', expr='p2_amplitude/(p2_sigma**pi)') pars.add('p1_contrast', expr='-p1_amplitude/(p1_sigma*pi*(c0+c1*p1_center+c2*p1_center**2))') pars.add('p2_contrast', expr='-p2_amplitude/(p2_sigma*pi*(c0+c1*p2_center+c2*p2_center**2))') model = peak1 + peak2 + background init = model.eval(pars, x=x) out = model.fit(y, pars, x=x) print out.fit_report() return init,out
def fit_lorentzian(y: np.ndarray, x: np.ndarray) -> np.ndarray: """Fits profile to lorentzian. Used with np.apply_along_axis. Parameters ---------- y y values of profile to be fitted. Units: none. x x values of profiles to be fitted Units: Hz. Returns ------- result_params A numpy array of the returning parameters ['Center', 'HWHM', 'max height', 'chi sq']. Units: [same as x, same as x, None, None]. """ model = LorentzianModel() center_guess = x[y.argmax()] HWHM_guess = x[y.argmax()] / 1000 params = model.make_params(amplitude=y.max() * np.pi * HWHM_guess, center=center_guess, sigma=HWHM_guess) result = model.fit(y, params, x=x) result_params = np.array([ result.params["center"].value, result.params["sigma"].value, result.params["height"].value, result.chisqr, ]) return result_params
def prepareFittingModels(roiCoordsList, modelType): modelList = [] paramList = [] index = 1 for region in roiCoordsList: individualModelsList = [] individualParamsList = [] if isinstance(region, dict): # If the region is just a single region, make it a list so the for loops pulls a dict rather than a dict entry region = [region] for entry in region: prefixName = 'v' + str(index) + '_' index += 1 # pull info out of region dict selectedXVals = entry['x'] selectedYVals = entry['y'] mod = None if modelType.lower() == 'voigt': mod = VoigtModel(prefix=prefixName) elif modelType.lower() == 'psuedovoigt': mod = PseudoVoigtModel(prefix=prefixName) elif modelType.lower() == 'lorentzian': mod = LorentzianModel(prefix=prefixName) elif modelType.lower() == 'gaussian': mod = GaussianModel(prefix=prefixName) elif modelType.lower() == 'pearsonvii': mod = Pearson7Model(prefix=prefixName) assert mod, "Entered model type is not supported" individualModelsList.append(mod) pars = mod.guess(selectedYVals, x=selectedXVals, negative=False) pars[prefixName + 'center'].set(min=min(selectedXVals), max=max(selectedXVals)) pars[prefixName + 'amplitude'].set(min=0) pars[prefixName + 'sigma'].set(min=0) if modelType.lower() == 'voigt': pars[prefixName + 'gamma'].set(value=0.3, vary=True, expr='', min=0) individualParamsList.append(pars) combinedModel = individualModelsList[0] combinedParams = individualParamsList[0] if len(individualModelsList) > 1: for model, params in zip(individualModelsList[1:], individualParamsList[1:]): combinedModel += model combinedParams += params modelList.append(combinedModel) paramList.append(combinedParams) return modelList, paramList
# Show the images as well profile.subplot(221) strctural.imshow(figure=profile.fig, title="Structural Image") profile.subplot(223) xmcd.imshow(figure=profile.fig, title="XMCD Image") # Make a histogram of the intesity values hist = xmcd.hist(bins=200) hist.column_headers = ["XMCD Signal", "Frequency"] hist.labels = None hist.fig = profile.fig # Construct a two Lorentzian peak model peak1 = LorentzianModel(prefix="peak1_") peak2 = LorentzianModel(prefix="peak2_") params = peak1.make_params() params.update(peak2.make_params()) double_peak = peak1 + peak2 def guess(self, data, **kwargs): """Function to guess the parameters of two Lorentzian peaks.""" x = kwargs.get("x") l = len(data) i1 = np.argmax(data[: l // 2]) # Location of first peak i2 = np.argmax(data[l // 2 :]) + l // 2 params = self.make_params() for k, p in zip(
import matplotlib.pyplot as plt import pandas as pd from lmfit.models import LorentzianModel dframe = pd.read_csv('peak.csv') model = LorentzianModel() params = model.guess(dframe['y'], x=dframe['x']) result = model.fit(dframe['y'], params, x=dframe['x']) print(result.fit_report()) result.plot_fit() plt.show()