def single_lorentzian( self, xdata, ydata, parms, domain, upper=None, plot=True, err=1e-10, maxruns=int(1e8), xlabel=r"$Frequency \, (Hz)$", ylabel=r"$Energy \, (dB)$", title=r"$Spectrum \, and \, Fit$", ): from scipy.optimize import curve_fit import numpy as np import matplotlib.pyplot as plt xpeaks, ypeaks = self.choose_domain(xdata, ydata, domain, upper=upper) yerr = 0.001 * np.ones_like(ypeaks) def lorentzian(x, c, A, G, w0): return c + (A / np.pi) * (0.5 * G) / ((x - w0) ** 2 + (0.5 * G) ** 2) popt, pcov = curve_fit( lorentzian, xpeaks, ypeaks, parms, check_finite=True, xtol=err, maxfev=maxruns, sigma=yerr ) chi_square = np.sum((lorentzian(xpeaks, *popt) - ypeaks) ** 2 / (yerr ** 2)) / (len(xpeaks) - len(popt) - 1) yFit = lorentzian(xpeaks, *popt) yuFit = lorentzian(xpeaks, *parms) if plot == True: plt.figure(figsize=(7, 7)) plt.plot(xdata, ydata, "o", ms=0.3, label=r"$Raw \, Data$") plt.plot(xpeaks, yFit, linewidth=4, alpha=0.6, label=r"$Fitted \, Curve$") plt.plot(xpeaks, yuFit, alpha=0.8, label=r"$Guesses$") plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) plt.legend(loc=0) if self.save_name is not None: plt.savefig(self.save_name + ".png") plt.show() else: pass os.chdir(cwd + "/..") error_code(code=0) return popt, chi_square, yFit, yuFit
def pos_multi_lorentzian(self, parms, nres, domain, upper = None, std_dev = 11, plot = True, err = 1e-10, maxruns = int(1e8), xlabel = r"$Frequency \, (Hz)$", ylabel = r"$Energy \, (dB)$", title = r"$Spectrum \, and \, Fit$", outside_use = False): from scipy.optimize import curve_fit import numpy as np import matplotlib.pyplot as plt ##Finding the peaks## xdata = self.data[:,0] ydata = self.data[:,1] xpeaks, ypeaks = self.choose_domain(xdata, ydata, domain, upper = upper) x_peak_coord, y_peak_coord = self.find_peaks(domain, std_dev) x_peak_coord = x_peak_coord.flatten() y_peak_coord = y_peak_coord.flatten() ##Now we have the peaks, so we'll put them into the initial guesses## for i in range(0, len(y_peak_coord)): parms[1+nres+i] = parms[0]-y_peak_coord[i] parms[2*nres+1+i] = x_peak_coord[i] parms = parms.flatten() ##And set the error...##UNDER CONSTRUCTION yerr = .001*np.ones_like(ypeaks) ##And run the fit## def multi_lorentz(x, *p): y = np.zeros_like(x) + p[0] for i in range(1, len(p)-2*nres): gamma = p[i] amp = p[i+nres] center = p[i+2*nres] y += np.absolute(amp/(1+1.j*(x-center)/(gamma/2))) return y.flatten() popt, pcov = curve_fit(multi_lorentz, xpeaks, ypeaks, parms, check_finite = True, xtol = err, maxfev = maxruns) chi_square = np.sum((-multi_lorentz(xpeaks, *popt)+ypeaks)**2/(yerr)**2)/(len(xpeaks) - len(popt) - 1) yFit = multi_lorentz(xpeaks, *popt) yuFit = multi_lorentz(xpeaks, *parms) if plot == True: plt.figure(figsize = (7,7)) plt.plot(xdata, ydata, 'o', ms = .3, label = r"$Raw \, Data$") plt.plot(xpeaks, yFit, linewidth = 4, alpha = .6, label = r"$Fitted \, Curve$") plt.plot(xpeaks, yuFit, alpha = .8, label = r"$Guesses$") plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) plt.legend(loc = 0) ##include a save_name? plt.show() else: pass os.chdir(cwd+'/..') error_code(code = 0) if outside_use != False: return {"popt":popt, "chi":chi_square, "yFit":yFit, "yuFit":yuFit, "xpeaks":xpeaks} else: return popt, chi_square, yFit, yuFit