def get_astropy_model(model): astropy_model = None if model["type"] == "Const": astropy_model = Const1D(model["amplitude"]) elif model["type"] == "Gaussian": astropy_model = Gaussian1D(model["amplitude"], model["mean"], model["stddev"]) elif model["type"] == "Lorentz": astropy_model = Lorentz1D(model["amplitude"], model["x_0"], model["fwhm"]) elif model["type"] == "PowerLaw": astropy_model = PowerLaw1D(model["amplitude"], model["x_0"], model["alpha"]) elif model["type"] == "BrokenPowerLaw": astropy_model = BrokenPowerLaw1D(model["amplitude"], model["x_break"], model["alpha_1"], model["alpha_2"]) if astropy_model: astropy_model = fix_parameters_to_astropy_model(astropy_model, model) return astropy_model
def spectra_Gen_bulk(Bs, QCCs, etas, f_0, f_end, f_res, fudge=1): fs_D = np.zeros((3, len(Bs), 3)) eigs_D = np.zeros((3, len(Bs), 3)) #f_0, f_end, f_res = (0e3, 200e3, 1e3) fs = np.arange(f_0, f_end + f_res, f_res) Lor = Lorentz1D(amplitude=1, x_0=(f_0 + f_end) / 2, fwhm=4e3)(fs) num_f = len(np.arange(f_0, f_end + f_res, f_res)) spectra = np.zeros((num_f, len(Bs))) ths = np.linspace(0, pi, 100) phis = np.linspace(0, 2 * pi, 200) cnt = 0 for k in range(len(ths)): th = ths[k] for l in range(len(phis)): cnt += 1 phi = phis[l] print('Bulk progress: {} %'.format(100 * (cnt) / (len(phis) * len(ths)))) for j, QCC_D in enumerate(QCCs): for i, B in enumerate(Bs): eigs_D[:, i, j], fs_D[:, i, j] = spectra_B(fudge * B, th, phi, QCC_D, etas[j]) #print('Progress: {} %'.format(100*(i+1)/len(Bs_D))) for i, B in enumerate(Bs): peaks = np.ndarray.flatten(fs_D[:, i, :]) _, amp = deltifier(peaks, f_0, f_end, f_res) spectra[:, i] += np.sin(th) * np.convolve(amp, Lor, 'same') return fs, Bs, spectra
def spectra_Gen(ths, phis, Bs, QCCs, etas, f_0, f_end, f_res, fudge=1): #Bs_D = np.linspace(0,0.02,100) #was 100 fs_D = np.zeros((3, len(Bs), 3)) eigs_D = np.zeros((3, len(Bs), 3)) #f_0, f_end, f_res = 3.26768e6 - 2e6, 3.26768e6 + 2e6, 1e3 fs = np.arange(f_0, f_end + f_res, f_res) Lor = Lorentz1D(amplitude=1, x_0=(f_0 + f_end) / 2, fwhm=4e3)(fs) num_f = len(np.arange(f_0, f_end + f_res, f_res)) spectra = np.zeros((num_f, len(Bs))) for k in range(len(ths)): th = ths[k] phi = phis[k] for j, QCC_D in enumerate(QCCs): for i, B in enumerate(Bs): eigs_D[:, i, j], fs_D[:, i, j] = spectra_B(fudge * B, th, phi, QCC_D, etas[j]) #print('Progress: {} %'.format(100*(i+1)/len(Bs_D))) for i, B in enumerate(Bs): peaks = np.ndarray.flatten(fs_D[:, i, :]) _, amp = deltifier(peaks, f_0, f_end, f_res) spectra[:, i] += np.convolve(amp, Lor, 'same') return fs, Bs, spectra
def spectra_Gen_angle(ths, phis, B, QCCs, etas, f_0, f_end, f_res, fudge=1, fwhm=4e3): Bs = [B] fs_D = np.zeros((3, len(Bs), 3)) eigs_D = np.zeros((3, len(Bs), 3)) fs = np.arange(f_0, f_end + f_res, f_res) Lor = Lorentz1D(amplitude=1, x_0=(f_0 + f_end) / 2, fwhm=fwhm)(fs) num_f = len(np.arange(f_0, f_end + f_res, f_res)) spectra = np.zeros((num_f, len(ths))) for i in range(len(QCCs)): for k in range(len(ths)): th = ths[k] phi = phis[k] eigs_D[:, 0, i], fs_D[:, 0, i] = spectra_B(fudge * B, th, phi, QCCs[i], etas[i]) #print('Progress: {} %'.format(100*(i+1)/len(Bs_D))) peaks = np.ndarray.flatten(fs_D[:, 0, i]) _, amp = deltifier(peaks, f_0, f_end, f_res) spectra[:, k] += np.convolve(amp, Lor, 'same') return fs, Bs, spectra
def _init_bgmodel(lorentz_mean=15.0): """Initialize model for background: constant plus Lorentzian""" lorentz_fixed = {'x_0': True, 'fwhm': True} lorentz_bounds = {'amplitude': [0, None]} constant_bounds = {'amplitude': [0, CORE_CMAX]} bgmodel = (Lorentz1D(0.1, lorentz_mean, 100.0, name='Lorentz', bounds=lorentz_bounds, fixed=lorentz_fixed) + Const1D(1.0e-4, bounds=constant_bounds, name='Constant')) return bgmodel
def fit_data_with_lorentz_and_const(x_values, y_values): amplitude = 5. x_0 = 1 fwhm = 0.5 const = 5. g_init = Lorentz1D(amplitude, x_0, fwhm) g_init += Const1D(const) lpost = PSDLogLikelihood(x_values, y_values, g_init) parest = ParameterEstimation() res = parest.fit(lpost, [amplitude, x_0, fwhm, const], neg=True) opt_amplitude = res.p_opt[0] opt_x_0 = res.p_opt[1] opt_fwhm = res.p_opt[2] opt_const = res.p_opt[3] return opt_amplitude, opt_x_0, opt_fwhm, opt_const
def down(self, event): global inf, limite, yhat self.ajuste2 -= 0.01 if self.ajuste2 < 0: self.ajuste2 = 0 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh ', np.round(self.ajuste2, 3), ' found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) limite = self.ajuste2 plt.draw()
def up(self, event): global inf, limite, yhat self.ajuste2 += 0.01 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh: ', np.round(self.ajuste2, 3), ' Found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) plt.annotate(np.str(self.ajuste2), xy=(np.mean(xx), max(yy) / 2)) limite = self.ajuste2 plt.draw()
def spectra_N_angle(ths, phis): B = 0.25 Bs_D = [B] QCCs = [1.354e6] etas = [0.63] fs_D = np.zeros((3, len(Bs_D), 3)) eigs_D = np.zeros((3, len(Bs_D), 3)) f_0, f_end, f_res = (0e5, 50e5, 5e3) fs = np.arange(f_0, f_end + f_res, f_res) Lor = Lorentz1D(amplitude=1, x_0=(f_0 + f_end) / 2, fwhm=50e3)(fs) num_f = len(np.arange(f_0, f_end + f_res, f_res)) spectra = np.zeros((num_f, len(ths))) for k in range(len(ths)): th = ths[k] phi = phis[k] eigs_D[:, 0, 0], fs_D[:, 0, 0] = spectra_B(B, th, phi, QCCs[0], etas[0]) #print('Progress: {} %'.format(100*(i+1)/len(Bs_D))) peaks = np.ndarray.flatten(fs_D[:, 0, :]) _, amp = deltifier(peaks, f_0, f_end, f_res) spectra[:, k] += np.convolve(amp, Lor, 'same') return fs, Bs_D, spectra
def fit_function( dattype="elx", functype="pow", dense=False, profile="gauss_asym", fixed=False, AV_guess=3, ): """ Define the fitting function Parameters ---------- dattype : string [default="elx"] Data type to fit ("elx" or "alax") functype : string [default="pow"] Fitting function type ("pow" for powerlaw or "pol" for polynomial) dense : boolean [default=False] Whether or not to fit the feature around 3 micron profile : string [default="gauss_asym"] Profile to use for the features if dense = True (options are "gauss", "drude", "lorentz", "gauss_asym", "drude_asym", "lorentz_asym") fixed : boolean [default=False] Whether or not to add a fixed feature around 3 micron (for diffuse sightlines) AV_guess : float [default=3] Initial guess for A(V) Returns ------- func : Astropy CompoundModel The fitting function """ # powerlaw model if functype == "pow": func = PowerLaw1D(fixed={"x_0": True}) elif functype == "pol": # polynomial model func = Polynomial1D(degree=6) else: warnings.warn( 'Unknown function type, choose "pow" for a powerlaw or "pol" for a polynomial', stacklevel=2, ) # add profiles for the features if requested if dense: # define different profiles # 1 Gaussian (stddev=FWHM/(2sqrt(2ln2))) gauss1 = Gaussian1D(mean=3, stddev=0.13, bounds={"stddev": (0.1, 0.2)}) # 2 Gaussians (stddev=FWHM/(2sqrt(2ln2))) gauss2 = Gaussian1D( mean=3, stddev=0.13, bounds={"stddev": (0.12, 0.16)} ) + Gaussian1D( mean=3.4, stddev=0.14, bounds={"mean": (3.41, 3.45), "stddev": (0.14, 0.2)} ) # 1 Drude drude1 = Drude1D(x_0=3, fwhm=0.3, bounds={"fwhm": (0.2, 0.5)}) # 2 Drudes drude2 = Drude1D(x_0=3, fwhm=0.3) + Drude1D( x_0=3.4, fwhm=0.15, bounds={"x_0": (3.35, 3.43), "fwhm": (0.14, 0.3)} ) # 1 Lorentzian lorentz1 = Lorentz1D(x_0=3, fwhm=0.3, bounds={"x_0": (2.99, 3.1)}) # 2 Lorentzians lorentz2 = Lorentz1D( x_0=3, fwhm=0.3, bounds={"x_0": (2.99, 3.1), "fwhm": (0.28, 0.4)} ) + Lorentz1D( x_0=3.4, fwhm=0.15, bounds={"x_0": (3.35, 3.43), "fwhm": (0.14, 0.3)} ) # 1 asymmetric Gaussian Gaussian_asym = custom_model(gauss_asymmetric) gauss_asym1 = Gaussian_asym( x_o=3, gamma_o=0.4, bounds={"x_o": (2.9, 3.1), "gamma_o": (0.35, 2), "asym": (-100, 100)}, ) # 2 asymmetric Gaussians gauss_asym2 = Gaussian_asym( x_o=3, gamma_o=0.3, bounds={"x_o": (2.99, 3.04), "gamma_o": (0.28, 0.5), "asym": (-10, 10)}, ) + Gaussian_asym( x_o=3.4, gamma_o=0.15, bounds={ "x_o": (3.3, 3.42), "scale": (0.005, None), "gamma_o": (0.15, 0.5), "asym": (-20, -4), }, ) # 1 "asymmetric" Drude Drude_asym = custom_model(drude_asymmetric) drude_asym1 = Drude_asym( x_o=3.0, gamma_o=0.3, bounds={ "scale": (0, 2), "x_o": (2.5, 3.5), "gamma_o": (-2, 2), "asym": (-50, 50), }, ) # 2 "asymmetric" Drudes drude_asym2 = Drude_asym(x_o=3, gamma_o=0.3) + Drude_asym( x_o=3.4, gamma_o=0.15, bounds={"x_o": (3.35, 3.45)} ) # 1 asymmetric Lorentzian Lorentzian_asym = custom_model(lorentz_asymmetric) lorentz_asym1 = Lorentzian_asym(x_o=3, gamma_o=0.3, bounds={"x_o": (2.95, 3.1)}) # 2 asymmetric Lorentzians lorentz_asym2 = Lorentzian_asym(x_o=3, gamma_o=0.3) + Lorentzian_asym( x_o=3.4, gamma_o=0.15 ) profiles = { "gauss1": gauss1, "drude1": drude1, "lorentz1": lorentz1, "gauss_asym1": gauss_asym1, "drude_asym1": drude_asym1, "lorentz_asym1": lorentz_asym1, "gauss2": gauss2, "drude2": drude2, "lorentz2": lorentz2, "gauss_asym2": gauss_asym2, "drude_asym2": drude_asym2, "lorentz_asym2": lorentz_asym2, } func += profiles[profile] if fixed: # fit a fixed feature for diffuse sightlines Drude_asym = custom_model(drude_asymmetric) func += Drude_asym( x_o=3.017727049, gamma_o=0.462375776, asym=-2.873011454, bounds={"scale": (0, 2)}, fixed={"x_o": True, "gamma_o": True, "asym": True}, ) # convert the function from A(lambda)/A(V) to E(lambda-V) if dattype == "elx": func = func | AxAvToExv(Av=AV_guess) return func
def fit_features_ext(starpair, path): """ Fit the extinction features separately with different profiles Parameters ---------- starpair : string Name of the star pair for which to fit the extinction features, in the format "reddenedstarname_comparisonstarname" (no spaces) path : string Path to the data files Returns ------- waves : np.ndarray Numpy array with wavelengths exts_sub : np.ndarray Numpy array with continuum subtracted extinctions results : list List with the fitted models for different profiles """ # first, fit the continuum, excluding the region of the features fit_spex_ext(starpair, path, exclude=[(2.8, 3.6)]) # retrieve the SpeX data to be fitted, and sort the curve from short to long wavelengths extdata = ExtData("%s%s_ext.fits" % (path, starpair.lower())) (waves, exts, exts_unc) = extdata.get_fitdata(["SpeX_SXD", "SpeX_LXD"]) indx = np.argsort(waves) waves = waves[indx].value exts = exts[indx] exts_unc = exts_unc[indx] # subtract the fitted (powerlaw) continuum from the data, and select the relevant region params = extdata.model["params"] exts_sub = exts - (params[0] * params[3] * waves ** (-params[2]) - params[3]) mask = (waves >= 2.8) & (waves <= 3.6) waves = waves[mask] exts_sub = exts_sub[mask] exts_unc = exts_unc[mask] # define different profiles # 2 Gaussians (stddev=FWHM/(2sqrt(2ln2))) gauss = Gaussian1D(mean=3, stddev=0.13) + Gaussian1D(mean=3.4, stddev=0.06) # 2 Drudes drude = Drude1D(x_0=3, fwhm=0.3) + Drude1D(x_0=3.4, fwhm=0.15) # 2 Lorentzians lorentz = Lorentz1D(x_0=3, fwhm=0.3) + Lorentz1D(x_0=3.4, fwhm=0.15) # 2 asymmetric Gaussians Gaussian_asym = custom_model(gauss_asymmetric) gauss_asym = Gaussian_asym(x_o=3, gamma_o=0.3) + Gaussian_asym( x_o=3.4, gamma_o=0.15 ) # 2 "asymmetric" Drudes Drude_asym = custom_model(drude_asymmetric) drude_asym = Drude_asym(x_o=3, gamma_o=0.3) + Drude_asym(x_o=3.4, gamma_o=0.15) # 2 asymmetric Lorentzians Lorentzian_asym = custom_model(lorentz_asymmetric) lorentz_asym = Lorentzian_asym(x_o=3, gamma_o=0.3) + Lorentzian_asym( x_o=3.4, gamma_o=0.15 ) profiles = [gauss, drude, lorentz, gauss_asym, drude_asym, lorentz_asym] # fit the different profiles fit = LevMarLSQFitter() results = [] for profile in profiles: fit_result = fit(profile, waves, exts_sub, weights=1 / exts_unc, maxiter=10000) results.append(fit_result) print(fit_result) print("Chi2", np.sum(((exts_sub - fit_result(waves)) / exts_unc) ** 2)) return waves, exts_sub, results
def fit_features_spec(star, path): """ Fit the features directly from the spectrum with different profiles Parameters ---------- star : string Name of the reddened star for which to fit the features in the spectrum path : string Path to the data files Returns ------- waves : np.ndarray Numpy array with wavelengths flux_sub : np.ndarray Numpy array with continuum subtracted fluxes results : list List with the fitted models for different profiles """ # obtain the spectrum of the reddened star stardata = StarData(star + ".dat", path) npts = stardata.data["SpeX_LXD"].npts waves = stardata.data["SpeX_LXD"].waves.value flux_unc = stardata.data["SpeX_LXD"].uncs # "manually" obtain the continuum from the spectrum (i.e. read the flux at 2.4 and 3.6 micron) plot_spectrum( star, path, mlam4=True, range=[2, 4.5], exclude=["IRS", "STIS_Opt"], ) # fit the continuum reference points with a straight line ref_waves = [2.4, 3.6] fluxes = [3.33268e-12, 4.053e-12] func = Linear1D() fit = LinearLSQFitter() fit_result = fit(func, ref_waves, fluxes) # subtract the continuum from the fluxes fluxes = stardata.data["SpeX_LXD"].fluxes.value * waves ** 4 - fit_result(waves) # define different profiles # 2 Gaussians (stddev=FWHM/(2sqrt(2ln2))) gauss = Gaussian1D(mean=3, stddev=0.13) + Gaussian1D( mean=3.4, stddev=0.06, fixed={"mean": True} ) # 2 Drudes drude = Drude1D(x_0=3, fwhm=0.3) + Drude1D(x_0=3.4, fwhm=0.15, fixed={"x_0": True}) # 2 Lorentzians lorentz = Lorentz1D(x_0=3, fwhm=0.3) + Lorentz1D( x_0=3.4, fwhm=0.15, fixed={"x_0": True} ) # 2 asymmetric Gaussians Gaussian_asym = custom_model(gauss_asymmetric) gauss_asym = Gaussian_asym(x_o=3, gamma_o=0.3) + Gaussian_asym( x_o=3.4, gamma_o=0.15, fixed={"x_o": True} ) # 2 "asymmetric" Drudes Drude_asym = custom_model(drude_asymmetric) drude_asym = Drude_asym(x_o=3, gamma_o=0.3) + Drude_asym( x_o=3.4, gamma_o=0.15, fixed={"x_o": True} ) # 2 asymmetric Lorentzians Lorentzian_asym = custom_model(lorentz_asymmetric) lorentz_asym = Lorentzian_asym(x_o=3, gamma_o=0.3) + Lorentzian_asym( x_o=3.4, gamma_o=0.15, fixed={"x_o": True} ) # 1 asymmetric Drude drude_asym1 = Drude_asym(x_o=3, gamma_o=0.3) profiles = [ gauss, drude, lorentz, gauss_asym, drude_asym, lorentz_asym, drude_asym1, ] # fit the different profiles fit2 = LevMarLSQFitter() results = [] mask1 = (waves > 2.4) & (waves < 3.6) mask2 = mask1 * (npts > 0) for profile in profiles: fit_result = fit2( profile, waves[mask2], fluxes[mask2], weights=1 / flux_unc[mask2], maxiter=10000, ) results.append(fit_result) print(fit_result) print( "Chi2", np.sum(((fluxes[mask2] - fit_result(waves[mask2])) / flux_unc[mask2]) ** 2), ) return waves[mask1], fluxes[mask1], npts[mask1], results
def filtragem(x, y, ajuste): plt.subplots_adjust(bottom=0.2) box_kernel = Box1DKernel(25) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) yoriginal = copy.copy(yhat) original, = plt.plot(x, yoriginal, 'b-', alpha=0.3) l, = plt.plot(x, yhat, 'k-', alpha=0.8) tresh = 0.05 j = peakutils.indexes(yhat, thres=tresh) inf = min(yhat[j]) linha, = plt.plot((min(x), max(x)), (inf, inf), ls='--', color='blue', lw=0.8) k = peakutils.indexes(yhat, thres=tresh) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) modos, = plt.plot(freqs, psds, 'x', color='green', alpha=0.4, label=labels['lz']) plt.annotate(np.str(tresh), xy=(np.mean(xx), max(yy) / 2)) class Index(object): ajuste = 25 ajuste2 = 0.05 def next(self, event): global yhat self.ajuste += 5 print(self.ajuste) box_kernel = Box1DKernel(self.ajuste) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) original.set_ydata(yoriginal) l.set_ydata(yhat) plt.draw() def prev(self, event): global yhat self.ajuste -= 5 if self.ajuste < 1: self.ajuste = 5 print(self.ajuste) box_kernel = Box1DKernel(self.ajuste) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) original.set_ydata(yoriginal) l.set_ydata(yhat) plt.draw() def up(self, event): global inf, limite, yhat self.ajuste2 += 0.01 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh: ', np.round(self.ajuste2, 3), ' Found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) plt.annotate(np.str(self.ajuste2), xy=(np.mean(xx), max(yy) / 2)) limite = self.ajuste2 plt.draw() def down(self, event): global inf, limite, yhat self.ajuste2 -= 0.01 if self.ajuste2 < 0: self.ajuste2 = 0 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh ', np.round(self.ajuste2, 3), ' found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) limite = self.ajuste2 plt.draw() callback = Index() axprev = plt.axes([0.7, 0.05, 0.1, 0.075]) axnext = plt.axes([0.81, 0.05, 0.1, 0.075]) axup = plt.axes([0.2, 0.05, 0.1, 0.075]) axdown = plt.axes([0.31, 0.05, 0.1, 0.075]) bnext = Button(axnext, 'more') bnext.on_clicked(callback.next) bprev = Button(axprev, 'less') bprev.on_clicked(callback.prev) bup = Button(axup, 'up') bup.on_clicked(callback.up) down = Button(axdown, 'down') down.on_clicked(callback.down) plt.show() return x, yhat, limite
def OBS(kic): path = 'TEMP/' + str(kic) + '/' color = "#ff7f0e" c1 = "#00ff00" c2 = '#66cccc' c3 = '#cc00ff' c4 = '#ee0000' labels = { "l0": '$l=0$', "l1": '$l=1$', "l2": '$l=2$', "lz": 'Lorentz peak' } ############################################################################################################ def separacao(freq, psd): """This function will calculate the distance between two frequencies It is good to automate the calculation of large and small separations""" global X X = [], [] fig = plt.figure(figsize=(17, 5), dpi=130) plt.plot(freq, psd, 'k-', lw=0.5, alpha=0.5) plt.title("Select the high frequency region") plt.xlim(min(freq), max(freq)) plt.ylim(min(psd), max(psd)) def onclick(event): global X x = event.xdata X = np.append(X, x) if len(X) == 1: plt.plot((x, x), (min(psd), max(psd)), 'r--', alpha=0.5, lw=0.8) plt.xlim(min(freq), max(freq)) plt.ylim(min(psd), max(psd)) plt.draw() if len(X) == 2: plt.plot((X[-1], X[-1]), (min(psd), max(psd)), 'r--', alpha=0.5, lw=0.8) plt.fill_betweenx((min(psd), max(psd)), (X[-2], X[-2]), (X[-1], X[-1]), color='red', alpha=0.2) plt.xlim(min(freq), max(freq)) plt.ylim(min(psd), max(psd)) plt.draw() if len(X) > 2: plt.clf() plt.plot(freq, psd, 'k', lw=0.5, alpha=0.5) plt.plot((X[-2], X[-2]), (min(psd), max(psd)), 'r--', alpha=0.5, lw=0.8) plt.plot((X[-1], X[-1]), (min(psd), max(psd)), 'r--', alpha=0.5, lw=0.8) plt.fill_betweenx((min(psd), max(psd)), (X[-2], X[-2]), (X[-1], X[-1]), color='red', alpha=0.2) plt.xlim(min(freq), max(freq)) plt.ylim(min(psd), max(psd)) plt.draw() print('Ultimo click: x = ', x) fig.canvas.mpl_connect('button_press_event', onclick) plt.show() plt.clf() return abs(X[-2] - X[-1]), X[-2], X[-1] def filtragem(x, y, ajuste): plt.subplots_adjust(bottom=0.2) box_kernel = Box1DKernel(25) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) yoriginal = copy.copy(yhat) original, = plt.plot(x, yoriginal, 'b-', alpha=0.3) l, = plt.plot(x, yhat, 'k-', alpha=0.8) tresh = 0.05 j = peakutils.indexes(yhat, thres=tresh) inf = min(yhat[j]) linha, = plt.plot((min(x), max(x)), (inf, inf), ls='--', color='blue', lw=0.8) k = peakutils.indexes(yhat, thres=tresh) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) modos, = plt.plot(freqs, psds, 'x', color='green', alpha=0.4, label=labels['lz']) plt.annotate(np.str(tresh), xy=(np.mean(xx), max(yy) / 2)) class Index(object): ajuste = 25 ajuste2 = 0.05 def next(self, event): global yhat self.ajuste += 5 print(self.ajuste) box_kernel = Box1DKernel(self.ajuste) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) original.set_ydata(yoriginal) l.set_ydata(yhat) plt.draw() def prev(self, event): global yhat self.ajuste -= 5 if self.ajuste < 1: self.ajuste = 5 print(self.ajuste) box_kernel = Box1DKernel(self.ajuste) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) original.set_ydata(yoriginal) l.set_ydata(yhat) plt.draw() def up(self, event): global inf, limite, yhat self.ajuste2 += 0.01 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh: ', np.round(self.ajuste2, 3), ' Found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) plt.annotate(np.str(self.ajuste2), xy=(np.mean(xx), max(yy) / 2)) limite = self.ajuste2 plt.draw() def down(self, event): global inf, limite, yhat self.ajuste2 -= 0.01 if self.ajuste2 < 0: self.ajuste2 = 0 j = peakutils.indexes(yhat, thres=self.ajuste2) inf = min(yhat[j]) infinito = (inf, inf) k = peakutils.indexes(yhat, thres=self.ajuste2) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) print('With tresh ', np.round(self.ajuste2, 3), ' found ', len(psds), ' mods') original.set_ydata(yoriginal) linha.set_ydata(infinito) modos.set_ydata(psds) modos.set_xdata(freqs) limite = self.ajuste2 plt.draw() callback = Index() axprev = plt.axes([0.7, 0.05, 0.1, 0.075]) axnext = plt.axes([0.81, 0.05, 0.1, 0.075]) axup = plt.axes([0.2, 0.05, 0.1, 0.075]) axdown = plt.axes([0.31, 0.05, 0.1, 0.075]) bnext = Button(axnext, 'more') bnext.on_clicked(callback.next) bprev = Button(axprev, 'less') bprev.on_clicked(callback.prev) bup = Button(axup, 'up') bup.on_clicked(callback.up) down = Button(axdown, 'down') down.on_clicked(callback.down) plt.show() return x, yhat, limite f = np.loadtxt(str(path) + 'PS_' + str(kic) + '.txt') freq = f[:, 0] psd = f[:, 1] diff, primeiro, segundo = separacao(freq, psd) l = (primeiro < freq) & (freq < segundo) x, y = freq[l], psd[l] mod = GaussianModel(prefix='gauss_') pars = mod.guess(y, x=x) out = mod.fit(y, pars, x=x) data = out.fit_report() print(data) result = out.minimize(method='leastsq') ci = conf_interval(out, result, p_names=['gauss_center', 'gauss_amplitude'], sigmas=(1, 2, 3, 5)) report = lmfit.printfuncs.report_ci(ci) print(report) numax = np.array(out.params['gauss_center']) plt.annotate('', xy=(primeiro, 0.8 * max(psd)), xytext=(primeiro, max(psd)), arrowprops=dict(shrink=0.025, alpha=0.8, fc=c1, ec='k', headwidth=5)) plt.annotate('', xy=(segundo, 0.8 * max(psd)), xytext=(segundo, max(psd)), arrowprops=dict(shrink=0.025, alpha=0.8, fc=c1, ec='k', headwidth=5)) plt.annotate(r'$\nu_{max}$', xy=(numax, 0.7 * max(psd)), xytext=(numax, max(psd)), arrowprops=dict(alpha=0.5, fc='r', ec='r', headwidth=2.4, width=2)) plt.grid(alpha=0.4) plt.ylabel('PSD[Amplitude Units]') plt.xlabel('Frequency [$\mu$Hz]') plt.title('KIC {}'.format(kic)) plt.plot(freq, psd, 'k-', lw=0.5, alpha=0.5) plt.tight_layout() plt.show() plt.clf() plt.close() deltanu = 135 * ((numax / 3050)**0.8) np.savetxt(str(path) + 'Data_asteroseismic', np.c_[deltanu, numax], header='DeltaNu and Numax') print('DeltaNu: {}\nNumax: {}'.format(deltanu, numax)) j = peakutils.indexes(y, thres=0.015) inf = min(y[j]) plt.axhline(inf, xmin=0.045, xmax=0.95, ls='--', color='blue', lw=0.8) x, yhat, tresh = filtragem(x, y, 25) print(tresh) j = peakutils.indexes(yhat, thres=tresh) inf = min(yhat[j]) plt.axhline(inf, xmin=0.045, xmax=0.95, ls='--', color='blue', lw=0.8) plt.plot(freq[l], yhat, 'k-', lw=0.5) k = peakutils.indexes(yhat, thres=tresh) xx = x[k] yy = yhat[k] s = Lorentz1D(xx, yy, fwhm=0.025) freqs = np.array(s.amplitude) psds = np.array(s.x_0) erro = s.fwhm * psds dados_lorenz = np.c_[freqs, psds, erro] Freq_Region = np.c_[freq[l], yhat] np.savetxt( str(path) + str(kic) + '_data_modos_obs.txt', dados_lorenz, header= 'all peaks (frequencies) of modes detected by lorentz profile, power, error' ) np.savetxt(str(path) + 'High_Freq_Region_' + str(kic) + '.txt', Freq_Region, header='High-frequency region with filter Box1DKernel') for i in range(0, len(freqs)): plt.plot([freqs[i]], [psds[i]], 'x', color='green', alpha=0.4, label=labels['lz']) labels['lz'] = "_nolegend_" plt.tight_layout() plt.legend(loc='best', scatterpoints=1) plt.savefig(str(path) + 'peak_ident_KIC' + str(kic) + '_oversample.png', dpi=170) idx = np.argmax(psd[l]) print('Greater power in the Gaussian region: {}'.format(x[idx])) plt.show()
box = np.ones(box_pts) / box_pts y_smooth = np.convolve(y, box, mode='same') return y_smooth plt.plot(x, y,'o', label='data') plt.plot(x, smooth(y, 3), 'r-', lw=2, label='smooth with box size 3') plt.plot(x, smooth(y, 19), 'g-', lw=2, label='smooth with box size 19') plt.legend(bbox_to_anchor=(1, 1)) plt.show(); ''' Example 4:平滑法2 ''' from astropy.modeling.models import Lorentz1D from astropy.convolution import convolve, Gaussian1DKernel, Box1DKernel lorentz = Lorentz1D(1, 0, 1) x = np.linspace(-5, 5, 100) data_1D = lorentz(x) + 0.1 * (np.random.rand(100) - 0.5) gauss_kernel = Gaussian1DKernel(2) smoothed_data_gauss = convolve(data_1D, gauss_kernel) box_kernel = Box1DKernel(5) smoothed_data_box = convolve(data_1D, box_kernel) plt.plot(data_1D, label='Original') plt.plot(smoothed_data_gauss, label='Smoothed with Gaussian1DKernel') plt.plot(smoothed_data_box, label='Box1DKernel') plt.legend(bbox_to_anchor=(1, 1)) plt.show();
def plot_fit_ice(): fs = 16 plt.rc("xtick", direction="in", labelsize=fs * 0.8) plt.rc("ytick", direction="in", labelsize=fs * 0.8) fig, ax = plt.subplots(2, 1, figsize=(9, 6), sharex=True) # read the spectrum for the H2O ice file = "H2O_NASA.dat" table = pd.read_table(file, comment="#", sep="\s+") table = table[2531:] waves = 1 / table["Freq."] * 1e4 norm = np.max(-table["%T,10K"] + 100) absorbs = (-table["%T,10K"] + 100) / norm # plot the spectrum ax[0].plot(waves, absorbs, color="k", label=r"H$_2$O ice") ax[1].plot(waves, absorbs, color="k", lw=1, ls="--", alpha=0.5, label=r"H$_2$O ice") # fit the spectrum drude = Drude1D(x_0=3.03, fixed={"amplitude": True}) gauss = Gaussian1D(mean=3.03, stddev=0.13, fixed={"amplitude": True}) lorentz = Lorentz1D(x_0=3.03, fixed={"amplitude": True}) fit = LevMarLSQFitter() fit_result1 = fit(drude, waves, absorbs) fit_result2 = fit(gauss, waves, absorbs, maxiter=1000) fit_result3 = fit(lorentz, waves, absorbs, maxiter=10000) # calculate the residuals res1 = absorbs - fit_result1(waves) res2 = absorbs - fit_result2(waves) res3 = absorbs - fit_result3(waves) print("D", np.sum(res1**2)) print("G", np.sum(res2**2)) print("L", np.sum(res3**2)) # plot the fits ax[0].plot( waves, fit_result1(waves), ls="--", label="Drude", ) ax[0].plot( waves, fit_result2(waves), ls=":", label="Gaussian", ) ax[0].plot( waves, fit_result3(waves), ls="-.", label="Lorentz", ) ax[0].legend() # read the spectrum for the mixed ice file = "mix_NASA.dat" table = pd.read_table(file, comment="#", sep="\s+") print(np.max(table["%T,10K"])) table = table[2531:] waves = 1 / table["Freq."] * 1e4 norm = np.max(-table["%T,10K"] + 95) absorbs = (-table["%T,10K"] + 95) / norm # plot the spectrum plt.plot(waves, absorbs, color="k", label=r"mixed ice") # fit the spectrum drude = Drude1D(x_0=3.03, fixed={"amplitude": True}) gauss = Gaussian1D(mean=3.03, stddev=0.13, fixed={"amplitude": True}) lorentz = Lorentz1D(x_0=3.03, fixed={"amplitude": True}) fit = LevMarLSQFitter() fit_result1 = fit(drude, waves, absorbs, maxiter=1000) fit_result2 = fit(gauss, waves, absorbs, maxiter=10000) fit_result3 = fit(lorentz, waves, absorbs, maxiter=10000) # calculate the residuals res1 = absorbs - fit_result1(waves) res2 = absorbs - fit_result2(waves) res3 = absorbs - fit_result3(waves) print("D", np.sum(res1**2)) print("G", np.sum(res2**2)) print("L", np.sum(res3**2)) print(fit_result1, fit_result2, fit_result3) plt.plot( waves, fit_result1(waves), ls="--", label="Drude", ) plt.plot( waves, fit_result2(waves), ls=":", label="Gaussian", ) plt.plot( waves, fit_result3(waves), ls="-.", label="Lorentz", ) ax[1].legend() plt.xlim(2.5, 4) plt.xlabel(r"$\lambda$ [$\mu m$]", fontsize=fs) fig.text( 0.06, 0.5, "Normalized absorbance", rotation="vertical", va="center", ha="center", fontsize=fs, ) plt.subplots_adjust(hspace=0) fig.savefig("/Users/mdecleir/spex_nir_extinction/Figures/lab_ice.pdf", bbox_inches="tight")