yV = y[y < np.percentile(y, 99)] yV = yV[yV > np.percentile(y, 1)] ul = np.mean(yV) + np.std(yV) * 5 dfObs[dfObs['00955'] > ul] = np.nan # fourier df = dfObs[dfObs.notna().values] tt = dfObs.index.values xx = (tt.astype('datetime64[D]') - np.datetime64('1979-01-01')).astype( np.float) t = df.index.values x = (t.astype('datetime64[D]') - np.datetime64('1979-01-01')).astype( np.float) y = df['00955'].values y = y - np.nanmean(y) nt = len(xx) # nt = 1000 # freq = 1/np.linspace(2, nt, nt) # freq = np.arange(1, nt)/nt freq = np.fft.fftfreq(nt)[1:] ls = LombScargle(x, y) power = ls.power(freq) xx = (dfObs.index.values.astype('datetime64[D]') - np.datetime64('1979-01-01')).astype(np.float) ym = np.zeros([len(freq), len(xx)]) for k, f in enumerate(freq): ym[k, :] = ls.model(xx, f) folder = r'C:\Users\geofk\work\waterQuality\tempData\LS' np.save(os.path.join(folder, siteNo + '-full'), ym)
#### generate a lomb-scargle periodogram!!!! sigma = 0.04*Tdur_seconds period_min = 2 period_max = 500 #LS_frequencies, LS_powers = LombScargle(epochs, adjusted_displacements_seconds, sigma).autopower(minimum_frequency=1/period_max, maximum_frequency=1/period_min, samples_per_peak=10) LS_frequencies = np.logspace(np.log10(1/period_max), np.log10(1/period_min), 5000) LS_periods = 1 / LS_frequencies LS_powers = LombScargle(epochs, adjusted_displacements_seconds, sigma).power(LS_frequencies) best_LS_freq = LS_frequencies[np.argmax(LS_powers)] best_LS_period = 1/best_LS_freq LS = LombScargle(epochs, adjusted_displacements_seconds, sigma) best_fit = LS.model(epochs, best_LS_freq) if debug_mode == 'n': ### WANT TO SAVE THEM! plt.plot(LS_periods, LS_powers, color='DodgerBlue', linewidth=2) plt.xscale('log') plt.title('best period = '+str(round(best_LS_period, 2))+' epochs') plt.xlabel('TTV period [epochs]') #plt.tight_layout() plt.savefig(plotdir+'/TTVsim'+str(sim_number)+'_LSperiodogram.pdf', dpi=200) plt.close() #plt.show()
if freqs[0] > xf.min(): peakfreq = freqs[0] except: pass # roughly model OMC based on single frequency sinusoid (if found) if peakfreq is not None: trend_type = "sinusoid" print("periodic component found at P = ", int(1/peakfreq), "d") LS = LombScargle(xtime, yomc) trend = LS.model(xtime, peakfreq) _, Asin, Bcos = LS.model_parameters(peakfreq) sin_priors.append((peakfreq, Asin, Bcos)) edges = [xtime.min()-0.5, xtime.max()+0.5] ngroups = int(np.ceil((xtime.max()-xtime.min())*peakfreq)) for i in range(1,ngroups): edges.append(xtime.min()+i/ngroups*(xtime.max()-xtime.min())) edges = list(np.sort(edges)) # otherwise, chose best polynomial model based on the BIC else:
def LSP(x, y, dy, fVal=[0, 1, 5, 1], norm='standard', figout=None, label=None, freq_set=None): ''' 周期分析 https://docs.astropy.org/en/stable/timeseries/lombscargle.html#periodogram-algorithms 参数: x,y,dy: arrays 时间,星等,误差 figout: str 图片保存名称 fVal: list minimum_frequency,maximum_frequency,samples_per_peak(default 5),nterms(default 1) return: frequency, power, residuals, x_range, y_fit, theta if nterms=1: theta=[off_set,amplitude,phi,best_frequency] y=off_set+amplitude*np.sin(2*np.pi*best_frequency*x+phi) ''' import numpy as np import matplotlib.pyplot as plt from astropy.timeseries import LombScargle if not isinstance(x, np.ndarray): x = np.array(x) y = np.array(y) dy = np.array(dy) fVal[0] = 10**-5 if fVal[0] == 0 else fVal[0] ls = LombScargle(x, y, dy, nterms=fVal[-1], normalization=norm) frequency, power = ls.autopower(minimum_frequency=fVal[0], maximum_frequency=fVal[1], samples_per_peak=fVal[2]) fig, ax = plt.subplots(3) fig.set_size_inches(20, 27) #ax[0].invert_yaxis();ax[2].invert_yaxis(); ax[0].grid() ax[1].grid() ax[2].grid() ax[0].errorbar(x, y, dy, fmt='bo-', label=label) ax[1].set_xlim((frequency[0], frequency[-1])) ax[1].plot(frequency, power, 'b-') ax11 = ax[1].twiny() ax11.set_xlim(ax[1].get_xlim()) x_side = np.linspace(0.001 + frequency[0], frequency[-1], 10) x_side_var = np.round(24 * 60 / x_side, 2) plt.xticks(x_side, x_side_var, rotation=0) best_frequency = frequency[np.argmax(power)] peak_power = power.max() ax[1].plot(best_frequency, peak_power, 'ro') ax[1].legend([ 'spectrum distribution', 'peak frequency ' + str(round(best_frequency, 4)) + 'c/d is period ' + str(round(24 / best_frequency, 4)) + 'h' ], loc='upper right', fontsize=15, frameon=False) if fVal[-1] == 1: for cutoff in ls.false_alarm_level([0.1, 0.05, 0.01]): ax[1].axhline(cutoff, color='black', linestyle='dotted') if freq_set != None: best_frequency = freq_set phase = (x * best_frequency) % 1 y_fit = ls.model(x, best_frequency) residuals = y - y_fit y_fit = y_fit[np.argsort(phase)] ax[2].plot(np.sort(phase), y_fit, 'r-', linewidth=5) ax[2].errorbar(phase, y, dy, fmt='b.', alpha=1) ax[2].legend( ['best fitted curve is ' + str(best_frequency), 'folded data'], loc='upper right', fontsize=15, frameon=False) x_range = np.linspace(x.min(), x.max(), 100) y_fit = ls.model(x_range, best_frequency) ax[0].plot(x_range, y_fit, 'r-', label='fitting curve', linewidth=5) ax[0].legend(loc='upper right', fontsize=15, frameon=False) if figout: plt.savefig(figout, dpi=100) plt.show() if fVal[-1] == 1: print('the false alarm probability for %0.2f (%0.2f min) is %0.2e' % (best_frequency, 24 * 60 / best_frequency, ls.false_alarm_probability(peak_power, method='davies'))) theta = ls.model_parameters(best_frequency) theta[0] = ls.offset() + theta[0] if len(theta) == 3: K = (theta[1]**2 + theta[2]**2)**0.5 phi = np.arcsin(theta[2] / K) theta = [theta[0], K, phi, best_frequency] return frequency, power, residuals, x_range, y_fit, theta
def lombscargle_periodogram(time, flux, error, dt=0, min_period=0.1, max_period=4, peak_points=10, height=0, peak_ind=0, plot=True, xlim=(0, 1)): ''' this function determines the peak period of a given light curve, allows one to choose which peak to select, then plots the periodogram and the folded light curve Parameters ---------- time : array of float contains time data for the light curve flux : array of float contains flux data for the light curve error : array of float contains error data for the light curve dt : float time shift [default = 0] min_period : float minimum period to investigate [default = 0.1 days] max_period : float maximum period to investigate [default = 4 days] peak_points : int number of points around peaks [default = 10] height : float minimum height to consider peaks [default = 0] peak_ind : ind choose a peak number, maximum is default [peak_ind = 0] plot : bool plot a periodogram and the folded lightcurve with best fit sinusoid xlim : tuple x-limits of the folded plot [default = (0, 1)] Returns ------- Pb : tuple contains the best fit parameters for the sine wave (amplitude, period, phase) residuals : array of float contains the residuals between the best fit model and the data ''' time_fixed = time - dt # create the periodogram model = LombScargle(time_fixed, flux, error) frequencies, power = model.autopower(minimum_frequency=(1. / max_period), maximum_frequency=(1 / min_period), samples_per_peak=peak_points) # convert to periods periods = 1 / frequencies # identify and extract peaks inds, peaks = find_peaks(power, height=height) peaks = peaks['peak_heights'] sort_peaks = np.argsort(peaks) inds = inds[sort_peaks] peaks = peaks[sort_peaks] # select peak period = periods[inds[-1 - peak_ind]] # fit the sinusoid flux_fit = model.model(time_fixed, 1 / period) residuals = flux - flux_fit t0, t1, t2 = model.model_parameters(1 / period) # convert theta parameters to amplitude and phase amplitude = np.hypot(t1, t2) * np.sign(flux_fit[0]) phase = -np.arctan(t1 / t2) + np.pi / 2 Pb = (amplitude, period, phase) # plot the periodogram and folded light curve if plot == True: # periodogram fig = plt.figure(figsize=(16, 8)) plt.title('Lomb-Scargle Periodogram of Stellar Variations') plt.xlabel('Period [days]') plt.ylabel('Power [-]') plt.plot(periods, power, 'b-') plt.gca().axvline(x=period, color='k', ls=':') plt.show() # folded light curve plot_folded(time_fixed, flux, error, Pb, flux_fit, dt, xlim) print('%.6f sin(2 pi time / %.4f + %.4f)' % Pb) return Pb, residuals
def main(): names = [ "d-abc_f.by", "d-abc_f.by.001", "d-abc_f.by.002", "d-ab_f.by", "d-ac_f.by", "d-ab_f.by", "c-ab_f.by", "d-bc_f.by", "c-a_f.by", "d-b_f.by", "d-a_f.by" ] names_index = 0 while (names_index < 15): filename = names[names_index] try: file = open(filename) break except: names_index += 1 continue season_lengths = [] last_day = 0 curr_season_length = 0 for line in file.readlines(): words = line.split() day = float(words[0]) if (day - last_day > 1000): #first line last_day = day curr_season_length += 1 continue if (day - last_day > 50): #fix season_lengths.append(curr_season_length) curr_season_length = 0 last_day = day curr_season_length += 1 season_lengths.append(curr_season_length) file.close() newfile = open("seasons.by", "w") file = open(filename) for season_length in season_lengths: times = [] fluxes = [] for n in range(season_length): words = file.readline().split() times.append(float(words[0])) fluxes.append(float(words[1])) times, fluxes = residuals(times, fluxes, 2) for n in range(season_length): newfile.write(str(times[n]) + " " + str(fluxes[n]) + "\n") newfile.write("\n") newfile.close() file.close() # make residual plot data = ascii.read("seasons.by") fig = plt.plot(data["col1"], data["col2"], 'k.') plt.xlabel("Day", fontsize=10) plt.ylabel("Res. Flux", fontsize=10) plt.title("Residuals of Relative Flux", fontsize=15) plt.savefig("residuals.png") # make periodogram t = data["col1"] mag = data["col2"] dmag = 1 #arbitrary, doesn't affect anything baseline = max(t) - min(t) cwd = os.getcwd() starname = cwd.split('/')[-1] ls = LombScargle(t, mag) frequency, power = ls.autopower(minimum_frequency=1 / baseline, maximum_frequency=1 / 2) periods = 1 / frequency best_power = power.max() best_period = periods[list(power).index(best_power)] probabilities = [0.1, 0.05, 0.01] fa_levels = ls.false_alarm_level(probabilities) alpha = 0.01 file = open("/Users/Ilya/Desktop/SURF/best_periods_using_fap.txt", "a") if (best_power > ls.false_alarm_level(alpha)): file.write("{0} {1}\n".format(starname, best_period)) else: file.write("{0}\n".format(starname)) file.close() # make phased data if (best_power > ls.false_alarm_level(alpha)): data = ascii.read(filename) phased_t = [] for element in t: phased_t.append(element % best_period) y_fit = ls.model(phased_t, 1 / best_period) fig, ax = plt.subplots() ax.plot(phased_t, mag, 'k.') ax.plot(phased_t, y_fit, 'b.') plt.savefig("phased.png") plt.show() length = 100 x_values = [1.3**n for n in range(length)] + [1.11] y_values_10 = [fa_levels[0] for n in range(length + 1)] y_values_05 = [fa_levels[1] for n in range(length + 1)] y_values_01 = [fa_levels[2] for n in range(length + 1)] fig, ax = plt.subplots() ax.plot(periods, power, 'k-') ax.plot(x_values, y_values_01, 'b*', markersize=4) ax.plot(x_values, y_values_05, 'b.', markersize=4) ax.plot(x_values, y_values_10, 'b_') ax.set( xlim=(2, baseline * 5), ylim=min(power), xlabel='period (days)', ylabel='Lomb-Scargle Power', xscale='log', title='{0}'.format(starname), ) ax.legend([ "Best Period: {0:.3f} days".format(best_period), "0.01 FAP", "0.05 FAP", "0.10 FAP" ], loc="center right", frameon=False, handlelength=0) plt.savefig("adjusted_periodogram.png")
def make_periodogram(data, ticid, pipeline, outdir=None, period_min=0.1, period_max=20, manual_peak=None, samples_per_peak=50, nterms_0=6): if pipeline in ['spoc', 'kepler']: time = data[LCKEYDICT[pipeline]['time']] flux = data[LCKEYDICT[pipeline]['flux']] err = flux*1e-4 qual = data[LCKEYDICT[pipeline]['quality']] sel = np.isfinite(time) & np.isfinite(flux) & np.isfinite(err) # (qual == 0) time, flux, err = time[sel], flux[sel], err[sel] med_flux = np.nanmedian(flux) flux /= med_flux err /= med_flux elif pipeline == 'cdips': time = data['time'] flux = data['flux'] err = data['err'] else: raise NotImplementedError ########################################## from astropy.timeseries import LombScargle from scipy.signal import find_peaks plt.close('all') fig, ax = plt.subplots() ls = LombScargle(time, flux, err, nterms=nterms_0) freq, power = ls.autopower(minimum_frequency=1/period_max, maximum_frequency=1/period_min, samples_per_peak=samples_per_peak) period = 1/freq ax.plot(period, power) ls_freq_0 = freq[np.argmax(power)] ls_period_0 = 1/ls_freq_0 ax.axvline(ls_period_0, alpha=0.4, lw=1, color='C0') ax.axvline(2*ls_period_0, alpha=0.4, lw=1, color='C0') ax.axvline(0.5*ls_period_0, alpha=0.4, lw=1, color='C0') if manual_peak: ax.axvline(manual_peak, alpha=0.4, lw=1, color='C1') ax.axvline(2*manual_peak, alpha=0.4, lw=1, color='C1') ax.axvline(0.5*manual_peak, alpha=0.4, lw=1, color='C1') peaks, props = find_peaks(power, height=1e-1) print(period[peaks]) tstr = f'LS period = {ls_period_0:.6f} d' ax.set_title(tstr) ax.set_yscale('log') ax.set_xscale('log') ax.set_xlabel('period [d]') ax.set_ylabel('power') if outdir is None: outdir = '../results/quicklooklc/TIC{}'.format(ticid) savpath = os.path.join(outdir, 'ls_periodogram.png') fig.savefig(savpath, dpi=300, bbox_inches='tight') print('made {}'.format(savpath)) ########################################## flux_fit_0 = ls.model(time, ls_freq_0) flux_r1 = flux - flux_fit_0 nterms_1=6 ls = LombScargle(time, flux_r1, err, nterms=nterms_1) freq, power = ls.autopower(minimum_frequency=1/period_max, maximum_frequency=1/period_min) period = 1/freq ls_freq_1 = freq[np.argmax(power)] ls_period_1 = 1/ls_freq_1 flux_fit_1 = ls.model(time, ls_freq_1) flux_r2 = flux_r1 - flux_fit_1 ########## nterms_2=6 ls = LombScargle(time, flux_r2, err, nterms=nterms_2) freq, power = ls.autopower(minimum_frequency=1/period_max, maximum_frequency=1/period_min) period = 1/freq ls_freq_2 = freq[np.argmax(power)] ls_period_2 = 1/ls_freq_2 flux_fit_2 = ls.model(time, ls_freq_2) flux_r3 = flux_r2 - flux_fit_2 ########################################## plt.close('all') fig, axs = plt.subplots(nrows=4, figsize=(14,10), sharex=True) axs[0].scatter(time, flux, c='k', s=1, zorder=1) axs[0].plot(time, flux_fit_0, zorder=2, lw=1) axs[0].set_title(f'model: {nterms_0} fourier terms at {ls_period_0:.6f} days', fontsize='x-small') axs[1].scatter(time, flux_r1, c='k', s=1, zorder=1) axs[1].plot(time, flux_fit_1, zorder=2, lw=1) axs[1].set_title(f'model: {nterms_1} fourier terms at {ls_period_1:.6f} days', fontsize='x-small') axs[2].scatter(time, flux_r2, c='k', s=1, zorder=1) axs[2].plot(time, flux_fit_2, zorder=2, lw=1) axs[2].set_title(f'model: {nterms_2} fourier terms at {ls_period_2:.6f} days', fontsize='x-small') axs[3].scatter(time, flux_r3, c='k', s=1, zorder=1) axs[3].plot(time, flux_fit_2-flux_fit_2, zorder=2, lw=1) axs[3].set_title('', fontsize='x-small') axs[0].set_ylabel('raw') axs[1].set_ylabel('resid 1') axs[2].set_ylabel('resid 2') axs[3].set_ylabel('resid 3') axs[3].set_xlabel('btjd') fig.tight_layout() savpath = os.path.join(outdir, 'ls_models_resids.png') fig.savefig(savpath, dpi=300, bbox_inches='tight') print('made {}'.format(savpath)) ########################################## show_tls = 0 if show_tls: from transitleastsquares import transitleastsquares model = transitleastsquares(time, flux) results = model.power(period_min=period_min, period_max=period_max, M_star_min=0.1, M_star_max=5, R_star=0.5, M_star=0.5) print(42*'-') print( 't0: {}'.format(results.T0)+ '\nperiod: {}'.format(results.period)+ '\nperiod_unc: {}'.format(results.period_uncertainty) ) print(42*'-') ########################################## plt.close('all') fig = plt.figure() ax = plt.gca() ax.axvline(results.period, alpha=0.4, lw=3) plt.xlim(np.min(results.periods), np.max(results.periods)) for n in range(2, 10): ax.axvline(n*results.period, alpha=0.4, lw=1, linestyle="dashed") ax.axvline(results.period / n, alpha=0.4, lw=1, linestyle="dashed") plt.ylabel(r'SDE') plt.xlabel('Period (days)') plt.plot(results.periods, results.power, color='black', lw=0.5) plt.xlim(0, max(results.periods)) savpath = os.path.join(outdir, 'tls_periodogram.png') fig.savefig(savpath, dpi=300, bbox_inches='tight') print('made {}'.format(savpath)) ########################################## plt.close('all') fig = plt.figure() plt.scatter(results.folded_phase, results.folded_y, color='gray', s=2, alpha=0.8, zorder=4, linewidths=0) pd = phase_bin_magseries(results.folded_phase, results.folded_y, binsize=0.01) plt.scatter(pd['binnedphases'], pd['binnedmags'], color='black', s=8, alpha=1, zorder=5, linewidths=0) plt.title(f'period {results.period:.8f}d') plt.xlabel('Phase') plt.ylabel('Relative flux') plt.xticks([0, 0.25, 0.5, 0.75, 1]) plt.grid(which='major', axis='both', linestyle='--', zorder=-3, alpha=0.5, color='gray') pct_80 = np.percentile(results.model_folded_model, 80) pct_20 = np.percentile(results.model_folded_model, 20) center = np.nanmedian(results.model_folded_model) delta_y = (10/6)*np.abs(pct_80 - pct_20) plt.ylim(( center-0.7*delta_y, center+0.7*delta_y )) savpath = os.path.join(outdir, 'phasefold.png') fig.savefig(savpath, dpi=300, bbox_inches='tight') print('made {}'.format(savpath))
We will pick out the highest powered period in the abover periodogram and phase the stellar light curve on that period. ''' # %% period = 1 / frequency[np.argmax(power)].value period # %% bfig = plotting.figure(plot_width=850, plot_height=300, title=f"Phased Lightcurve (TIC{variable_tic_id})") # Plotting the phased light curve bfig.circle(variable_lc["TIME"] % period, variable_lc["FLUX_RAW"], fill_color="black", size=4, line_color=None) # Plotting the periodic fit t_fit = np.linspace(0, period, 100) bfig.line(t_fit, lomb.model(t_fit, 1 / period), color='#1b9f00', line_width=2) # Labeling the axes bfig.xaxis.axis_label = "Phase (days)" bfig.yaxis.axis_label = "Flux" plotting.show(bfig) # %%
def LS_estimator(x, y, fsamp=None, fap=0.1, return_levels=False, max_peaks=2): """ Generates a Lomb-Scargle periodogram and identifies significant frequencies from a data series Assumes that data are nearly evenly sampled Optimized for finding marginal periodic TTV signals in OMC data; may not perform well for other applications Parameters ---------- x : array-like 1D array of x data values; should be monotonically increasing y : array-like 1D array of corresponding y data values, len(x) fsamp: float nominal sampling frequency; if not provided it will be calculated from the data fap : float false alarm probability threshold to consider a frequency significant (default=0.1) Returns ------- xf : ndarray 1D array of frequencies yf : ndarray 1D array of corresponding response freqs : list signficant frequencies faps : list corresponding false alarm probabilities """ # get sampling frequency if fsamp is None: fsamp = 1 / np.min(x[1:] - x[:-1]) # Hann window to reduce ringing hann = sig.windows.hann(len(x)) hann /= np.sum(hann) # identify any egregious outliers out = np.abs(y - np.median(y)) / astropy.stats.mad_std(y) > 5.0 xt = x[~out] yt = y[~out] freqs = [] faps = [] loop = True while loop: lombscargle = LombScargle(xt, yt * hann[~out]) xf, yf = lombscargle.autopower(minimum_frequency=2.0/(xt.max()-xt.min()), \ maximum_frequency=0.25*fsamp, \ samples_per_peak=10) peak_freq = xf[np.argmax(yf)] peak_fap = lombscargle.false_alarm_probability(yf.max(), method='bootstrap') # output first iteration of LS periodogram if len(freqs) == 0: xf_out = xf.copy() yf_out = yf.copy() levels = lombscargle.false_alarm_level([0.1, 0.01, 0.001]) if peak_fap < fap: yt -= lombscargle.model(xt, peak_freq) * len(xt) freqs.append(peak_freq) faps.append(peak_fap) else: loop = False if len(freqs) >= max_peaks: loop = False if return_levels: return xf_out, yf_out, freqs, faps, levels else: return xf_out, yf_out, freqs, faps
def plot_rotation_period( time, flux, err=None, mask=None, method="lombscargle", min_per=0.5, max_per=30, npoints=20, xlims=None, ylims=None, figsize=(10, 5), title=None, ): """ method : str lombscargle or acf (autocorrelation function) """ fig, ax = pl.subplots(1, 2, figsize=figsize, constrained_layout=True) if mask is not None: time, flux = time[~mask], flux[~mask] err = None if err is None else err[~mask] if method == "lombscargle": ls = LombScargle(time, flux, dy=err) frequencies, powers = ls.autopower(minimum_frequency=1.0 / max_per, maximum_frequency=1.0 / min_per) best_freq = frequencies[np.argmax(powers)] peak_period = 1.0 / best_freq periods = 1.0 / frequencies elif method == "acf": raise NotImplementedError("Method not yet available") else: raise ValueError("Use method='lombscargle'") # fit a gaussian to lombscargle power prot, prot_err = get_rotation_period( time, flux, min_per=min_per, max_per=max_per, npoints=npoints, plot=False, ) # left: periodogram n = 0 ax[n].plot(periods, powers, "k-") ax[n].axvline(peak_period, 0, 1, ls="--", c="r", label=f"peak={peak_period:.2f}") ax[n].axvline(prot, 0, 1, ls="-", c="r", label=f"fit={prot:.2f}+/-{prot_err:.2f}") ax[n].legend(title="Best period [d]") ax[n].set_xscale("log") ax[n].set_xlabel("Period [days]") ax[n].set_ylabel("Lomb-Scargle Power") # right: phase-folded lc and sinusoidal model n = 1 offset = 0.5 t_fit = np.linspace(0, 1, 100) - offset y_fit = ls.model(t_fit * peak_period - peak_period / 2, best_freq) ax[n].plot(t_fit * peak_period, y_fit, "r-", lw=3, label="sine model", zorder=3) # fold data phase = ((time / peak_period) % 1) - offset a = ax[n].scatter(phase * peak_period, flux, c=time, cmap=pl.get_cmap("Blues")) pl.colorbar(a, ax=ax[n], label="Time [BTJD]") ax[n].legend() if xlims is None: ax[n].set_xlim(-peak_period / 2, peak_period / 2) else: ax[n].set_xlim(*xlims) if ylims is not None: ax[n].set_ylim(*ylims) ax[n].set_ylabel("Normalized Flux") ax[n].set_xlabel("Phase [days]") fig.suptitle(title) return fig
power = ls.power(freq) xx = (dfObs.index.values.astype('datetime64[D]') - np.datetime64('1979-01-01')).astype(np.float) p = ls.false_alarm_probability(power) indP = np.where(p < 0.1)[0] pd = np.unique(np.abs((1 / freq[indP]).astype(int))) yy = np.zeros(len(tt)) y2 = np.zeros(len(t)) # for d in pd: # if d > 0: # yy = yy+ls.model(xx, 1/d) # y2 = y2+ls.model(x, 1/d) for k in indP.tolist(): yy = yy + ls.model(xx, freq[k]) y2 = y2 + ls.model(x, freq[k]) fig, axes = plt.subplots(2, 1, figsize=(10, 4)) axes[0].plot(tt, yy, '-r', label='Lomb-Scargle') axes[0].plot(t, y, '-*b', label='obs') axes[0].legend() # axes[0].set_xlabel('day') axes[0].set_title(siteNo) axes[1].plot(t, y2 - y, '-*b', label='obs') axes[1].legend() axes[1].set_xlabel('period (day)') plt.tight_layout() fig.show()
def main(): megafile = pandas.read_csv("../halpha.csv") ids = list(megafile["observation_id"]) times = list(megafile["time"]) starnames = list(megafile["star"]) Ha = list(megafile["Ha"]) C1 = list(megafile["C1"]) # Convert times from UTC into float times = [utc_to_jd(datetime.strptime(time, '%Y-%m-%d %H:%M:%S.%f')) for time in times] # Create list of all star names starlist = [] for starname in starnames: if starname not in starlist: starlist.append(starname) #145675, 201092, 221354 for star in (217107,): print(star) # Create lists of all observations of the star. # Keep the two instruments separate. star_times_a, star_times_h = [], [] star_Ha_a, star_Ha_h = [], [] for i in range(len(Ha)): if (starnames[i] == star): if (ids[i][1] == 'j'): star_times_h.append(times[i]) star_Ha_h.append(Ha[i]) else: star_times_a.append(times[i]) star_Ha_a.append(Ha[i]) # # # # # # # # # # # # # # # # # Data Processing Begins Here # # # # # # # # # # # # # # # # # # Remove data points that are obviously errors star_times_a, star_Ha_a = remove_outliers(star_times_a, star_Ha_a) star_times_h, star_Ha_h = remove_outliers(star_times_h, star_Ha_h) # Apply filter before combining data. Applying the filter will remove long-term # trends that may have affected the two sets separately. star_times_a, star_Ha_a = bandpass.band_pass_filter(star_times_a, star_Ha_a, 1/100, 1/4) star_times_h, star_Ha_h = bandpass.band_pass_filter(star_times_h, star_Ha_h, 1/100, 1/4) # Combine the sets from the two instruments. star_times = star_times_a + star_times_h star_Ha = star_Ha_a + star_Ha_h # Create Lomb-Scargle Periodogram model ls = LombScargle(star_times, star_Ha) baseline = max(star_times) - min(star_times) frequency, power = ls.autopower(minimum_frequency=1/baseline, maximum_frequency=1/2) periods = 1 / frequency # Find the best period within a reasonable range best_power = 0 best_period = 1 for i, p in enumerate(power): if (periods[i] > 4 and periods[i] < 80): if (p > best_power): best_power = p best_period = periods[i] # # # # # # # # # # # # # # # # Data Processing Ends Here # # # # # # # # # # # # # # # # FAP = ls.false_alarm_probability(best_power) alpha = 0.001 # Record best period in a file # if (FAP < 1): # file = open("/Users/Ilya/Desktop/SURF/halpha_periods_catalog.txt", "a") # file.write("hd{0}\t{1}\t{2}\n".format(star, str(best_period), str(FAP))) # file.close() # Make plot fig, axs = plt.subplots(3, 1, sharex=False) # Plot filtered data axs[0].plot(star_times, star_Ha, 'k.') axs[0].set(title="hd{0}".format(star)) # Plot periodogram axs[1].plot(periods, power, 'k-') axs[1].set(xlim=(min(periods), max(periods)), ylim=min(power), xlabel='Period (JD)', ylabel='Lomb-Scargle Power', xscale='log') # Plot phased data phased_t = [time % float(best_period) for time in star_times] axs[2].plot(phased_t, star_Ha, 'k.') # Plot best-fit model on top of phased data n = 300 model_t = [i / n * float(best_period) for i in range(n)] y_fit = ls.model(model_t, 1/best_period) axs[2].plot(model_t, y_fit, 'b.') # Add line to periodogram representing FAP = alpha n = 100 x_values = [1.3**i for i in range(n)] + [1.11] y_values_alpha = [ls.false_alarm_level(alpha) for i in range(n + 1)] axs[1].plot(x_values, y_values_alpha, 'b_') axs[1].legend(["{0} FAP".format(alpha)], loc="upper right", frameon=False, handlelength=0) # Plot aliases, harmonics and sampling periods on the periodogram as vertical lines. f_sampling = [1/1, 1/29.5, 1/365] aliases, harmonics = find_aliases(1 / best_period, [-2, -1, 1, 2], f_sampling) for alias in aliases: axs[1].axvline(alias, c="grey") for harmonic in harmonics: axs[1].axvline(harmonic, c="blue") for f in f_sampling: axs[1].axvline(1/f, c="green") plt.show()
import importlib import pandas as pd import numpy as np import os import time # test x = np.arange(5) y = np.random.random(5) ls = LombScargle(x, y) freq = 2 / 5 p = ls.model_parameters(freq) mat = ls.design_matrix(freq) yp = ls.model(x, freq) power = ls.power(freq, normalization='psd') offset = ls.offset() a = np.fft.fft(y) yp1 = p[0] + p[1] * np.sin(2 * np.pi * freq * x) + p[2] * np.cos( 2 * np.pi * freq * x) + ls.offset() mat np.sin(2 * np.pi * freq * x) np.cos(2 * np.pi * freq * x) yp1 = yp * 0 for f in list(x / 5)[1:]: f