Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0

		#### 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()



Ejemplo n.º 3
0
            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:
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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")
Ejemplo n.º 7
0
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))
Ejemplo n.º 8
0
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)

# %%
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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