Example #1
0
def powerSpectra(t):
    #period is an np array of 100000 points linearly spaced between 0 and 10
    #we will be looking for periods between 0 and 10 days. adjust if need be
    period = np.linspace(.1, 10, 100000)
    
    #omega is the angular frequency of the period
    omega = 2 * np.pi / period
	
    #compute lobm-scargle ps
    PS=lomb_scargle(t['Date'].values,t['R'].values,t['Rerr'].values, omega, generalized=True)
    
    PSwindow=lomb_scargle(t['Date'].values, np.ones_like(t['R'].values), 1 , omega, generalized=False, subtract_mean=False)
    
    #D = lomb_scargle_bootstrap(t['Date'].values,t['R'].values,t['Rerr'].values, omega, generalized=True, N_bootstraps=1000, random_state=0)
    #sig1, sig5 = np.percentile(D, [99, 95])
    #print str(sig5)+" "+str(sig1)
    
    #create quick plot of power spectra
    fig=plt.figure(figsize=(16,8))
    ax1=fig.add_subplot(211)
    ax1.plot(period, PS, '-', c='black', lw=1, zorder=1)
    ax1.set_ylabel('data PSD')
    ax1.set_ylim(0,1)
    #ax1.plot([period[0], period[-1]], [sig1, sig1], ':', c='black')
    #ax1.plot([period[0], period[-1]], [sig5, sig5], ':', c='black')
    ax2=fig.add_subplot(212)
    ax2.plot(period, PSwindow, '-', c='black', lw=1, zorder=1)
    ax2.set_ylabel('window PSD')
    
    
    plt.show()
    return pd.DataFrame({"PS":PS, "omega":omega, "period":period})
def run_ls(times,yvals,yerrs,plot=False):

    min_freq = 2*np.pi/(max(times)-min(times))
    max_freq = np.median(np.pi/np.diff(times))
    #print min_freq,max_freq
    omega = np.linspace(min_freq,max_freq,10000)
    period = 2*np.pi/omega
    P_LS = lomb_scargle(times,yvals,yerrs,omega,generalized=True)
    #print P_LS

    fund_loc = np.argmax(abs(P_LS))
    fund_period = period[fund_loc]
    print_period = "Prot = {:.2f}".format(fund_period)

    if plot:

        plt.figure()
        ax1 = plt.subplot(111,xscale="log")
        ax1.plot(period,P_LS,"b-",zorder=1,label=print_period)
        #ax.plot([period[0],period[-1]],[sig1,sig1],"b:")
        #ax.plot([period[0],period[-1]],[sig5,sig5],"b:")
        ax1.set_xlim(period[-1], period[0])
        ax1.set_ylim(-0.05, 0.85)
    
        ax1.set_xlabel(r'period (days)')
        ax1.set_ylabel('power')
        ax1.legend()

    #print print_period
    return fund_period
Example #3
0
def periodo_significativo(x, y, dy):
    period = 10**np.linspace(0, 2, 10000)
    omega = 2 * np.pi / period
    PS = lomb_scargle(x, y, dy, omega, generalized=True)
    power_p = period[np.argmax(PS)]
    double_power_p = 2. * power_p
    P_value = power_p
    return P_value
Example #4
0
    def periodogram(self, time, signal):

        LS_lc = lomb_scargle(time,
                             signal,
                             self.error,
                             self.__psd_freq * (2.0 * np.pi),
                             generalized=True)
        return 1.0 / self.__psd_freq, LS_lc
def LombScargleSingleFreq(xIn, yIn, f, err=1):
    """Calculate Lomb-Scargle periodogram power at a single frequency weighted
    as in cumming 1999

    """
    power = lomb_scargle(xIn, yIn, err, [f, .005], generalized=True)[0]
    power = power / (1 - power) * (len(xIn) - 3) / 2
    return power
Example #6
0
def periodo_significativo(x, y, dy):
    period = 10**np.linspace(
        0, 2,
        10000)  # starting around 1 day until 10^2 for find the 2nd period
    omega = 2 * np.pi / period
    PS = lomb_scargle(x, y, dy, omega, generalized=True)
    power_p = period[np.argmax(PS)]
    double_power_p = 2. * power_p
    return PS, power_p, double_power_p, period
 def ls_astroML(self):
     """
     calculate periodogram using generalized Lomb-Scargle periodogram from AstroML
     function description: http://www.astroml.org/modules/generated/astroML.time_series.lomb_scargle.html
     example: http://www.astroml.org/book_figures/chapter10/fig_LS_example.html
     """
     LS_lc = lomb_scargle(self.time, self.signal, self.error, self.__psd_freq*(2.0*np.pi), generalized=True)
     
     return 1.0/self.__psd_freq, LS_lc
def GLS(time,flux,flux_err):
    '''Statistics, Data Mining, and Machine Learning in Astronomy 
    Ivezic, Connolly, VanderPlas, and Gray
    Great job of Ivezic et al
    '''
    from astroML.time_series import lomb_scargle
    #significance levels 90%,99%,99.9%
    sig = np.array([0.1, 0.01, 0.001])
    #range of frequencies to performa analysis
    #from 0.5 to 100 days, or 0.01 to 2.0 d-1. Use 100,000 freqs
    Pomega = np.linspace(0.01, 2., 10000)
    Py,Z = lomb_scargle(time,flux,flux_err,Pomega,generalized=True,significance=sig)
    return Pomega,Py,Z 
Example #9
0
def get_LS(t,y,yerr=None):
	if yerr == None:
		yerr = np.ones(len(y))

	min_t = 2.0*np.mean(np.abs(np.diff(t))) # Nyquist freq
	max_t = np.max(t) - np.min(t)

	max_f = 1./min_t
	min_f = 1./max_t

	freqs = np.linspace(min_f,max_f,len(t))

	return freqs,lomb_scargle(t,y,yerr,2.*np.pi*freqs,generalized=True) 
 def CalculatePeriodogram(self):
     """Calculate the Lomb-Scargle periodogram."""
     if self.freqs is None:
         deltaFreq = 28
         nFreqs = (self.obsTimes[-1]-self.obsTimes[0])*deltaFreq*4
         nFreqs = 5000
         self.freqs = np.linspace(log(2), log(30*365), nFreqs)
         self.freqs = np.exp(self.freqs)
         self.freqs = np.pi*2/self.freqs
     self.periodogram = lomb_scargle(self.obsTimes, self.velocities,
                                     self.velocityErrors, self.freqs,
                                     generalized=True)
     self.periodogram = (self.periodogram / (1-self.periodogram.max())
                         * (len(self.velocities) - 3) / 2)
Example #11
0
def get_LS(t, y, yerr=None):
    if yerr is None:
        yerr = np.ones(len(y))

    min_t = 2.0 * np.mean(np.abs(np.diff(t)))  # Nyquist freq
    max_t = np.max(t) - np.min(t)

    max_f = 1. / min_t
    min_f = 1. / max_t

    freqs = np.linspace(min_f, max_f, len(t))

    return freqs, lomb_scargle(t,
                               y,
                               yerr,
                               2. * np.pi * freqs,
                               generalized=True)
def get_period_sigf(jd, mag, mag_e):  #parameters: time, mag, mag error
    omega = frequency_grid(0.1, 1850)  # grid of frequencies
    p = lomb_scargle(
        jd, mag, mag_e, omega,
        generalized=True)  # Lomb-Scargle power associated to omega
    peak = max(p)  #power associated with best_period
    best_period = LS_peak_to_period(omega,
                                    p)  #estimates a period from periodogram

    # Get significance via bootstrap
    D = lomb_scargle_bootstrap(jd,
                               mag,
                               mag_e,
                               omega,
                               generalized=True,
                               N_bootstraps=1000,
                               random_state=0)
    sig1, sig5 = np.percentile(
        D, [99, 95])  # 95% and 99% confidence, to compare with peak

    return best_period, peak, sig5, sig1
Example #13
0
def astroML_peaks(freq, flux, f, num):
    """Target function

    Computes the Lomb-Scarge periodogram. The astroML module
    is not compatible with python 3.

    Parameters
    ----------
    f: array_like
        angular frequencies for periodogram
    """
    from astroML.time_series import lomb_scargle
    # dy is a sequence of observational errors
    dy = np.ones(len(flux))*1e-3
    pgram = lomb_scargle(freq, flux, dy, f, generalized=False)
    # find local maxima not at the edge of the periodogram
    maxmask = np.r_[False, pgram[1:] > pgram[:-1]] &\
                np.r_[pgram[:-1] > pgram[1:], False]
    sortarg = np.argsort(pgram[maxmask])
    peak_freqs = f[maxmask][sortarg[-num:]]
    peak_flux = pgram[maxmask][sortarg[-num:]]
    return pgram, peak_freqs, peak_flux
Example #14
0
    def _periodogram(t, y, dy, omegas):
        """
        Evaluate periodogram.

        Args:

            t (np.ndarray) - timepoints

            y (np.ndarray) - values

            dy (np.ndarray) - estimated measurement error

            omega (np.ndarray) - spectral frequencies tests

        Returns:

            PS (np.ndarray) - normalized power spectrum

        """
        kw = dict(generalized=True, subtract_mean=True)
        PS = lomb_scargle(t, y, dy, omegas, **kw)
        return PS
Example #15
0
def whiteNoiseLS(t=np.array([]), u=np.array([]), \
                     omegas=np.array([]), nTrials=100, \
                     pctile=1., Verbose=True):
    """Wrapper to do the lomb-scargle on white noise datasets"""

    if Verbose:
        print "whiteNoiseLS INFO - Starting %i trials..." % (nTrials)

    nData = np.size(t)
    aNoiseLS = np.zeros((nTrials, np.size(omegas)))
    for iNoise in range(nTrials):
        magNoise = np.random.normal(size=nData) * u
        lsNoise = lomb_scargle(t,magNoise, u, \
                                   omegas, \
                                   generalized=False)

        aNoiseLS[iNoise] = lsNoise

    lsNoiseUpper = np.percentile(aNoiseLS, 100. - pctile, axis=0)

    # return the lomb-scargle of the upper percentile and also an
    # example LS periodogram.
    return lsNoiseUpper, lsNoise
Example #16
0
def LS_window_white_noise(t, omega, y=0, dy=1,
                           generalized=False, subtract_mean=False,
                           random_state=None, N_mock=100,
                           hist=False, plot_hist=True,Nbins=200):
    """Use a monte carlo simulation to compute Lomb-Scargle white noise 
        significance for the given spectral window
    Parameters
    ----------
    The first set of parameters are passed to the lomb_scargle algorithm
    t : array_like
        sequence of times
    omega : array_like
        frequencies at which to evaluate p(omega)
    generalized : bool
        if True (default) use generalized lomb-scargle method
        otherwise, use classic lomb-scargle.
    subtract_mean : bool
        if True (default) subtract the sample mean from the data before
        computing the periodogram.  Only referenced if generalized is False
    Remaining parameters control the bootstrap
    N_mock : int
        number of simulations
    random_state : None, int, or RandomState object
        random seed, or random number generator
    Returns
    -------
    D : ndarray
        distribution of the height of the highest peak
    if hist=True:
        omegaD : ndarray
            distribution of the angular frecuencies corresponding to D
    """
    random_state = check_random_state(random_state)
    t = np.asarray(t)
    #dy = np.ones_like(y)

    D = np.zeros(N_mock)
    omegaD= np.zeros(N_mock)
    #PS_mock_all=[]
    #PS_mock_max=np.array([])
    #omega_mock_max=np.array([])
    for i in range(N_mock):
        #ind = random_state.randint(0, len(y), len(y))
        y = np.random.normal(y, dy , size=len(t))
        #print y 
        p = lomb_scargle(t, y, dy, omega,
                         generalized=generalized, subtract_mean=subtract_mean)
        #print p
        D[i] = p.max()
        omegaD[i]=omega[p.argmax()]
        
        
    #max_PS_mock=np.max(PS_mock_all,axis=0)
    if hist:
        
        if plot_hist:
            from matplotlib import pyplot as plt
            frecD=omegaD.copy()/(2*np.pi)
            
            plt.figure('white noise peak hist')
            plt.hist(frecD,normed=True, bins=Nbins)
            plt.hist(frecD,normed=True,histtype='step')

            plt.figure('white noise peak cumhist')
            Xcum=np.sort(D)
            Ycum=np.array(range(N_mock))/float(N_mock)
            plt.plot(Xcum,Ycum)
            #plt.xlim(Xcum,Xcum)
            plt.grid()
            plt.minorticks_on()
            plt.xlabel('')

        return D,omegaD
    else:
        return D
Example #17
0
def LS_bootstrap_sig(t, y, dy, omega,
                           generalized=True, subtract_mean=True,
                           N_bootstraps=100, random_state=None,
                           hist=False, plot_hist=True,Nbins=200):
    """Use a bootstrap analysis to compute Lomb-Scargle significance
    Parameters
    ----------
    The first set of parameters are passed to the lomb_scargle algorithm
    t : array_like
        sequence of times
    y : array_like
        sequence of observations
    dy : array_like
        sequence of observational errors
    omega : array_like
        frequencies at which to evaluate p(omega)
    generalized : bool
        if True (default) use generalized lomb-scargle method
        otherwise, use classic lomb-scargle.
    subtract_mean : bool
        if True (default) subtract the sample mean from the data before
        computing the periodogram.  Only referenced if generalized is False
    Remaining parameters control the bootstrap
    N_bootstraps : int
        number of bootstraps
    random_state : None, int, or RandomState object
        random seed, or random number generator
    Returns
    -------
    D : ndarray
        distribution of the height of the highest peak
    """
    random_state = check_random_state(random_state)
    t = np.asarray(t)
    y = np.asarray(y)
    dy = np.asarray(dy) + np.zeros_like(y)

    D = np.zeros(N_bootstraps)
    omegaD= np.zeros(N_bootstraps)
    
    for i in range(N_bootstraps):
        ind = random_state.randint(0, len(y), len(y))
        #print[ind]
        p = lomb_scargle(t, y[ind], dy[ind], omega,
                         generalized=generalized, subtract_mean=subtract_mean)
        D[i] = p.max()
        omegaD[i]=omega[p.argmax()]
    if hist:
        
        if plot_hist:
            from matplotlib import pyplot as plt
            frecD=omegaD.copy()/(2*np.pi)
            
            plt.figure('bootstrap hist')
            plt.hist(frecD,normed=True, bins=Nbins)
            plt.hist(frecD,normed=True,histtype='step')

            plt.figure('bootstrap cumhist')
            Xcum=np.sort(D)
            Ycum=np.array(range(N_bootstraps))/float(N_bootstraps)
            plt.plot(Xcum,Ycum)
            #plt.xlim(Xcum,Xcum)
            plt.grid()
            plt.minorticks_on()
            plt.xlabel('')

        return D,omegaD
    else:
        return D
Example #18
0
        mag2sig = np.append(mag2sig, 
                            1.0875 * sigflux2[i] / (flux2[i] + flux_ref2))
        mag2date = np.append(mag2date, mjd2[i])
    else:
        # compute upper flux limit and plot as arrow or triangle
        upperlim2 = np.append(upperlim2, 
                              zp2[i] - 2.5 * np.log10(snu * sigflux2[i]))
        upperlim2date = np.append(upperlim2date, mjd1[i])
        
#------------------------------------------------------------
# Compute periodogram
period = np.linspace(1, 50, 100000)
omega = 2 * np.pi / period
#PS = lomb_scargle(t, y_obs, dy, omega, generalized=True)

PS = lomb_scargle(mag1date, mag1, mag1sig, omega, generalized = True)

#------------------------------------------------------------
# Get significance via bootstrap
D = lomb_scargle_bootstrap(mag1date, mag1, mag1sig, omega, generalized = True,
                           N_bootstraps=500, random_state=0)
sig1, sig5 = np.percentile(D, [99, 95])

#------------------------------------------------------------
# Plot the results
fig = plt.figure(figsize=(5, 3.75))
fig.subplots_adjust(left=0.1, right=0.9, hspace=0.25)

# First panel: the data
ax = fig.add_subplot(211)
ax.errorbar(mag1date, mag1, mag1sig, fmt='.k', lw=1, ecolor='gray')
Example #19
0
def LSP(dates, RVs, errs, pmin=0.1, pmax=3000., n=10000):
    period_list = np.linspace(pmin, pmax, n)
    freqs = 2. * np.pi / period_list
    PG = lomb_scargle(dates, RVs, errs, freqs, generalized=True)
    return period_list, PG
Example #20
0
def LS_bootstrap_err_est(t, y, dy, omega,
                           generalized=True, subtract_mean=True,
                           N_bootstraps=100, random_state=None,
                           hist=False, plot_hist=True,Nbins=200):
    """Use a bootstrap analysis to compute Lomb-Scargle error estimation
    Parameters
    ----------
    The first set of parameters are passed to the lomb_scargle algorithm
    t : array_like
        sequence of times
    y : array_like
        sequence of observations
    dy : array_like
        sequence of observational errors
    omega : array_like
        frequencies at which to evaluate p(omega)
    generalized : bool
        if True (default) use generalized lomb-scargle method
        otherwise, use classic lomb-scargle.
    subtract_mean : bool
        if True (default) subtract the sample mean from the data before
        computing the periodogram.  Only referenced if generalized is False
    Remaining parameters control the bootstrap
    N_bootstraps : int
        number of bootstraps
    random_state : None, int, or RandomState object
        random seed, or random number generator
    Returns
    -------
    D : ndarray
        distribution of the height of the highest peak
    """
    random_state = check_random_state(random_state)
    t = np.asarray(t)
    y = np.asarray(y)
    dy = np.asarray(dy) + np.zeros_like(y)

    D = np.zeros(N_bootstraps)
    omegaD= np.zeros(N_bootstraps)
    
    for i in range(N_bootstraps):
        ind = random_state.randint(0, len(y), len(y))
        #print(ind)
        #print(t[ind], y[ind], dy[ind])
        #print(subtract_mean)
        ###el vector de tiempo es patológico, dado que hay una observación aislada en dos días distintos, aunque no sea correcto del todo vamos a conservar los dos puntos en esas noches en concreto para evitar que el mook periodogram de resultados raros (i.e. periodo=0) 
        ##ind[-2]=11
        ##ind[-1]=-1
        p = lomb_scargle(t[ind], y[ind], dy[ind], omega,
                         generalized=generalized, subtract_mean=subtract_mean)
        D[i] = p.max()
        omegaD[i]=omega[p.argmax()]
        
        #if omegaD[i]==min(omega):
        #    from matplotlib import pyplot as plt
        #    plt.plot(omega,p)
        #    plt.figure()
        #    print(t[ind],y[ind],dy[ind])
            
            
    if hist:
        
        if plot_hist:
            from matplotlib import pyplot as plt
            frecD=omegaD.copy()/(2*np.pi)
            
            plt.figure('bootstrap hist')
            plt.hist(frecD,normed=True, bins=Nbins)
            plt.hist(frecD,normed=True,histtype='step')

            plt.figure('bootstrap cumhist')
            Xcum=np.sort(D)
            Ycum=np.array(range(N_bootstraps))/float(N_bootstraps)
            plt.plot(Xcum,Ycum)
            #plt.xlim(Xcum,Xcum)
            plt.grid()
            plt.minorticks_on()
            plt.xlabel('')

        return D,omegaD
    else:
        return D
Example #21
0
dy1 = 0.1 + 0.1 * np.random.random(y_obs1.shape)
y_obs1 += np.random.normal(0, dy1)

y_obs2 = np.sin(np.pi * t_obs / 3)
dy2 = 10 * dy1
y_obs2 = y_obs2 + np.random.normal(dy2)

y_window = np.ones_like(y_obs1)

t = np.linspace(0, 100, 10000)
y = np.sin(np.pi * t / 3)

#------------------------------------------------------------
# Compute the periodogram
omega = np.linspace(0, 5, 1001)[1:]
P_obs1 = lomb_scargle(t_obs, y_obs1, dy1, omega)
P_obs2 = lomb_scargle(t_obs, y_obs2, dy2, omega)
P_window = lomb_scargle(t_obs,
                        y_window,
                        1,
                        omega,
                        generalized=False,
                        subtract_mean=False)
P_true = lomb_scargle(t, y, 1, omega)

omega /= 2 * np.pi

#------------------------------------------------------------
# Prepare the figures
fig = plt.figure(figsize=(5, 2.5))
fig.subplots_adjust(bottom=0.15,
Example #22
0
#------------------------------------------------------------
# Generate Data
np.random.seed(0)
N = 30
P = 0.3

t = np.random.randint(100, size=N) + 0.3 + 0.4 * np.random.random(N)
y = 10 + np.sin(2 * np.pi * t / P)
dy = 0.5 + 0.5 * np.random.random(N)
y_obs = np.random.normal(y, dy)

#------------------------------------------------------------
# Compute periodogram
period = 10**np.linspace(-1, 0, 10000)
omega = 2 * np.pi / period
PS = lomb_scargle(t, y_obs, dy, omega, generalized=True)

#------------------------------------------------------------
# Get significance via bootstrap
D = lomb_scargle_bootstrap(t,
                           y_obs,
                           dy,
                           omega,
                           generalized=True,
                           N_bootstraps=1000,
                           random_state=0)
sig1, sig5 = np.percentile(D, [99, 95])

#------------------------------------------------------------
# Plot the results
fig = plt.figure(figsize=(5, 3.75))
Example #23
0
def PeriodogramRbandDRW(QSOId, k):
    import matplotlib.pyplot as plt
    #import h5py
    import numpy as np
    #    #########################################################################################################
    #    #import light curve
    #    from QSOLightCurveH5FinalCatalog import QSOLightCurvesFinalCatalog
    #    MJD, mag, magErr = QSOLightCurvesFinalCatalog(QSOId)
    #
    #
    #    #sort the observations with time
    #
    #    SortedInd = np.argsort(MJD)
    #    MJD = MJD[SortedInd]
    #    mag = mag[SortedInd]
    #    magErr = magErr[SortedInd]
    #
    #    ##########################################################################################################
    #    #weighted by the photometric average observations in one night bins
    #    from BinLightCurve import BinLightCurve
    #    MJD, mag, magErr = BinLightCurve(MJD, mag, magErr)
    #
    #    MJD = MJD-np.min(MJD)
    #
    #####################################################
    #Replace with PG1302 light curve
    ######################################################
    #    just insert a file containing the real data you want to run PLS ond DRW on
    data = np.loadtxt('C:/Python27/Data/pg1302_data_LINEAR+CRTS+ASASSN.txt')
    #    print data
    MJD = data[:, 0]
    #    mag=data[:,1]
    magErr = data[:, 2]

    SortedInd = np.argsort(MJD)
    MJD = MJD[SortedInd]
    #    mag = mag[SortedInd]
    magErr = magErr[SortedInd]

    #    #find frequency grid
    from OptimalFrequencyGrid import OptimalFrequencyGrid
    omega, omegaSlope = OptimalFrequencyGrid(MJD)

    #################################################################################################
    #indices to downsample the uniform grid
    deltat = 1
    from MinimumTimeResolution import MinimumTimeResolution
    ind, NumberOfPoints = MinimumTimeResolution(MJD, deltat)
    #

    #    #################################################################################################
    #    #identify best fit parameters for DRW model
    #    import h5py
    #    filename='../QSO1000Iterations'+str(k)+'/QSO1'+str(QSOId)+'_1000Iterations.h5'
    #    f=h5py.File(filename,"r")
    #    BestFitTau=f['/'+str(QSOId)+'/BestFitTau']
    #    BestFitTau=BestFitTau.value
    #    BestFitSigma=f['/'+str(QSOId)+'/BestFitSigma']
    #    BestFitSigma=BestFitSigma.value
    #
    #    BestFitMean=f['/'+str(QSOId)+'/BestFitMean']
    #    BestFitMean=BestFitMean.value
    #    f.close()
    #

    #############################################
    #Fix sigma and tau from Charisi+2015
    #############################################
    BestFitTau = 100
    BestFitSigma = .11
    BestFitMean = 14

    #    from ChiSquareMinimization import ChiSquareMinimization
    #    BestFitSigma, BestFitTau, BestFitMean, ChiSq=ChiSquareMinimization(mag, magErr, MJD)
    #    print BestFitSigma
    #    print BestFitTau
    #    print BestFitMean
    #    print ChiSq

    ###############################################################################################
    # DRW Simulations
    N_bootstraps = 10
    from SimulateTimeSeries import SimulateTimeSeriesDRW
    x = SimulateTimeSeriesDRW(BestFitTau, BestFitSigma, NumberOfPoints, ind,
                              MJD, magErr, BestFitMean, N_bootstraps, deltat)
    print(type(x))
    plt.errorbar(MJD, x, yerr=magErr, fmt='o', ecolor='black')
    plt.show()

    #    MaxPsim=np.max(Psim,axis=0)
    #    AvgPsim=np.mean(Psim,axis=0)
    #
    #    ################################################################################################
    #    #periodogram
    from astroML.time_series import lomb_scargle
    P_LS = lomb_scargle(MJD, x, magErr, omegaSlope, generalized=True)

    #    fining the highest peak in the DRW curve's periodogram
    max_peak = np.amax(P_LS)
    print max_peak

    plot1, = plt.plot(omegaSlope, P_LS, '-', c='blue', lw=1, zorder=1)
    plt.xlabel('Frequency (2pi/days)')
    plt.ylabel('P_LS')
    plt.title("LS Periodogram of LINEAR+CRTS+ASASSN Simulated DRW Curve")
    plt.legend([plot1], [
        "LINEAR+CRTS+ASASSN Simulated Curve",
    ])
Example #24
0
y_obs = y + np.random.normal(dy)

omega_0 = 2 * np.pi / P

#######################################################################
# Generate the plot with and without the original typo

for typo in [True, False]:
    #------------------------------------------------------------
    # Compute the Lomb-Scargle Periodogram
    sig = np.array([0.1, 0.01, 0.001])
    omega = np.linspace(17, 22, 1000)

    # Notice the typo: we used y rather than y_obs
    if typo is True:
        P_S = lomb_scargle(t, y, dy, omega, generalized=False)
        P_G = lomb_scargle(t, y, dy, omega, generalized=True)
    else:
        P_S = lomb_scargle(t, y_obs, dy, omega, generalized=False)
        P_G = lomb_scargle(t, y_obs, dy, omega, generalized=True)

    #------------------------------------------------------------
    # Get significance via bootstrap
    D = lomb_scargle_bootstrap(t, y_obs, dy, omega, generalized=True,
                               N_bootstraps=1000, random_state=0)
    sig1, sig5 = np.percentile(D, [99, 95])

    #------------------------------------------------------------
    # Plot the results
    fig = plt.figure(figsize=(5, 3.75))
Example #25
0
def go(times=np.array([]), mags=np.array([]), unctys=np.array([]), \
           dayNo=np.array([]), \
           nCols=4, \
           test=True, nNights=8, logPer=True,
           nNoise=1000, pctile=5., \
           lsOnAll=True, degPoly=2, errScale=1.0, showFit=True, \
           filName='UnknownYear.txt', write=False, binLS=False, select=True, writeLS=False, \
           figPrep=True):

    if figPrep:
        plt.style.use('./MNRAS_Style.mplstyle')
    else:
        plt.style.use('ggplot')
    """Plots (time, mag, error) data partitioned by day number. 

    if test=True, data are generated up to nNights.

    If degPoly < 0, no detrending is performed."""

    # if test is set, generate the data
    if test:
        times, mags, unctys = genData(nNights=nNights)
        dayNo = np.asarray(times, 'int')

    # now break into an n x 4 grid
    nPanels = int(np.max(dayNo) + 1)  # can tweak this if we're counting from
    # 1
    nRows = int(np.ceil(nPanels / np.float(nCols)))

    # The lightcurve figure
    fig1 = plt.figure(1)
    fig1.clf()

    # The lomb-scargle figure
    figLS = plt.figure(3)
    figLS.clf()

    # now for the white-noise test
    figLSnoise = plt.figure(4)
    figLSnoise.clf()

    # remove spacing between plots - for all the figures
    for fig in [fig1, figLS, figLSnoise]:
        fig.subplots_adjust(hspace=0.02, wspace=0.05)

    # list of axes (so that we can get them back later)
    lAxes = []
    hrMin = 99.
    hrMax = -99.

    # we can generalize this later. For the moment, let's do separate
    # variables per figure
    perMin = 99.
    perMax = -99.
    lsMin = 999.
    lsMax = -999.

    if logPer:
        perMin = 1e-1
        perMax = 10.

    # axes list for the l-s and the gaussian noise l-s
    lAxesLS = []
    lAxesLSnoise = []

    coloSim = 'g'
    print "nPanels: %i, nRows:%i, nCols:%i" % (nPanels, nRows, nCols)

    sigTable = Table([[0.], [0.]], names=('JD', 'std'))

    ## 2019-04-11 - let's set up a master 'detrended' array for the LS
    detMJD = np.array([])
    detMag = np.array([])
    detUnc = np.array([])

    # 2019-04-18 WIC - hacked to handle less orthodox panel ordering
    rowNotEmpty = False

    # loop through the panels
    # hack for 17:
    #iPanels = [3,5]
    #for iPlot in iPanels:
    for iPlot in range(nPanels):
        bThis = dayNo == iPlot

        # 2019-04-18 WIC - hack for labeline
        if iPlot % nCols < 1:
            rowNotEmpty = False

        if np.sum(bThis) < 10:
            print "Bad interval: %i, %i points" % (iPlot, np.sum(bThis))
            continue

        # add the panel
        ax = fig1.add_subplot(nRows, nCols, iPlot + 1)

        # times from the beginning of the dataset. NOTE - when doing
        # this with real data, we can use the actual decimal day
        # number. With simulated data, though, we use the first time
        # in each interval.
        hrs = 24. * (times[bThis] - np.min(times[bThis]))

        # do the plot
        dum = ax.errorbar(hrs, mags[bThis], unctys[bThis], \
                              ls='None', ecolor='b', \
                              marker='o', color='b', \
                              ms=2, alpha=0.5, elinewidth=1)

        # Set the label for the day number
        sLabel = 'Night %i' % (iPlot + 1)

        # Label the day number
        dumAnno = ax.annotate(sLabel, (0.95, 0.95), \
                                  xycoords='axes fraction', \
                                  ha='right', va='top', \
                                  fontsize=12, color='k')

        # if we're more than nCols from the end, hide the horizontal
        # axis
        if nPanels - iPlot > nCols and iPlot > 0:
            ax.tick_params(labelbottom='off')
        else:
            ax.set_xlabel('Time (hours)')

            # 2019-04-18 WIC - another hack to suppress the last time label to avoid overlap

            #xticks = ax.xaxis.get_major_ticks()
            #xticks[-1].set_visible(False)

        #2019-04-19 WIC - that hack again
        if not rowNotEmpty:
            ax.set_ylabel(r'$\Delta R$ (mag)')
            rowNotEmpty = True

            # 2019-04-18 WIC -
            # if this is anything other than the upper-left corner, hide the uppermost tick since it'll overlap
            if iPlot > 0:
                yticks = ax.yaxis.get_major_ticks()
                yticks[0].set_visible(False)

        else:

            #        if iPlot % nCols > 0:
            ax.tick_params(labelleft='off')


#        else:
#            ax.set_ylabel(r'$\Delta R$')

# record the maximum axis length so that we can access it
# later
        hrMax = np.max([hrMax, np.max(hrs)])
        hrMin = np.min([hrMin, np.min(hrs)])

        lAxes.append(ax)

        # 2019-04-02: Find the standard deviation and output to the terminal

        sigz, pars = findResidualSigma(hrs,
                                       mags[bThis],
                                       unctys[bThis],
                                       errScale=errScale,
                                       degPoly=degPoly)

        # let's re-produce the detrended points and stack them back on to the master array
        thisDetMag = mags[bThis] - np.polyval(pars, hrs)
        detMJD = np.hstack((detMJD, times[bThis]))
        detMag = np.hstack((detMag, thisDetMag))
        detUnc = np.hstack((detUnc, unctys[bThis]))

        # Show the poly-fit in Figure 1

        if showFit:
            fit = ax.plot(hrs, np.polyval(pars, hrs), 'r--', lw=2)

        print "Night %i: stddev %.5f" % (iPlot + 1, sigz)

        # Create a table with the format (JD, sigma)

        meanTime = np.mean(times[bThis])

        sigTable.add_row([meanTime, sigz])

        # now - IF there are enough datapoints - we do the
        # Lomb-Scargle
        if np.size(hrs) < 40:
            continue

        dtMin = np.min(hrs[1::] - hrs[0:-1])
        dtRange = np.max(hrs) - np.min(hrs)

        # Generate periods array out of this and do the L-S
        #pers = np.logspace(np.log10(dtMin*2.), np.log10(dtRange*1.0),1000)
        pers = np.logspace(np.log10(dtMin * 2.), np.log10(7.), 200)
        omegas = 2.0 * np.pi / pers

        lsBin = lomb_scargle(hrs, mags[bThis], unctys[bThis], \
                                 omegas, \
                                 generalized=False)

        # Do the same exercise for gaussian white-noise
        # print "Starting %i trials..." % (nNoise)
        lsNoiseUpper, lsNoise = whiteNoiseLS(hrs, unctys[bThis], \
                                                 omegas, nNoise, \
                                                 pctile)

        #aNoiseLS = np.zeros((nNoise, np.size(omegas)))
        #for iNoise in range(nNoise):
        #    magNoise = np.random.normal(size=np.size(hrs))*unctys[bThis]
        #    lsNoise = lomb_scargle(hrs, magNoise, unctys[bThis], \
        #                               omegas, \
        #                               generalized=False)

        #    # slot this in to the simulation array
        #    aNoiseLS[iNoise] = lsNoise

        ## do upper and lower bounds from the noise
        #lsNoiseUpper = np.percentile(aNoiseLS, 100.-pctile, axis=0)
        #lsNoiseLower = np.percentile(aNoiseLS, pctile, axis=0)

        # OK now we plot the LS for this particular axis. Just like
        # before, this time for a different figure.
        axLS = figLS.add_subplot(nRows, nCols, iPlot + 1)
        axLSnoise = figLSnoise.add_subplot(nRows, nCols, iPlot + 1)

        ### 2018-05-07 log-log from semilogx
        dumLS = axLS.loglog(pers, lsBin, 'bo', ms=1, ls='-', color='b')
        dumLSnoise = axLSnoise.loglog(pers, lsNoise, \
                                            ms=1, ls='-', color='0.2', \
                                            alpha=0.5)

        coloSim = 'darkmagenta'
        dum1 = axLSnoise.plot(pers, lsNoiseUpper, alpha=0.7, \
                                  color=coloSim)
        #dum2 = axLSnoise.plot(pers, lsNoiseLower)

        dumAnno = axLSnoise.annotate('%.0f percent, %i trials' \
                                         % (100.-pctile, nNoise), \
                                         (0.05, 0.85), \
                                         xycoords='axes fraction', \
                                         ha='left', va='top', \
                                         color=coloSim, \
                                         alpha=0.7)

        # LS powers for standardization
        perMin = np.min([perMin, np.min(pers)])
        perMax = np.max([perMax, np.max(pers)])
        lsMin = np.min([lsMin, np.min(lsBin)])
        lsMax = np.max([lsMax, np.max(lsBin)])

        # do the axes as before
        if nPanels - iPlot > nCols:
            axLS.tick_params(labelbottom='off')
            axLSnoise.tick_params(labelbottom='off')
        else:
            axLS.set_xlabel('Period (hours)')
            axLSnoise.set_xlabel('Period (hours)')

        if iPlot % nCols > 0:
            axLS.tick_params(labelleft='off')
            axLSnoise.tick_params(labelleft='off')
        else:
            axLS.set_ylabel('LS Power')
            axLSnoise.set_ylabel('LS Power')

        # annotate the day number on both LS axes
        for axAnno in [axLS, axLSnoise]:
            dumdum = axAnno.annotate(sLabel, (0.05, 0.95), \
                                         xycoords='axes fraction', \
                                         ha='left', va='top', \
                                         fontsize=12, color='k')

        # append the LS axis onto the list
        lAxesLS.append(axLS)
        lAxesLSnoise.append(axLSnoise)

        ### 2018-05-07 hardcode the vertical axis
        ### ax.set_ylim(np.max(mags[bThis]), np.max(mags[bThis])-0.4)

    # now set the same x-range for all the axes
    for thisAx in lAxes:
        thisAx.set_xlim(hrMin, hrMax)

        # set the y limit
        ### 2018-05-07
        thisAx.set_ylim(np.max(mags + unctys), np.min(mags - unctys))

        # 2019-04-09: Set the y-range for all the axes to be the same as Z04 Figure 3

        thisAx.set_ylim([0.05, -0.3])

    # do the same for the lomb-scargle figures
    for iAx in range(len(lAxesLS)):
        thisLS = lAxesLS[iAx]
        try:
            thisLS.set_xlim(perMin, perMax)
            thisLS.set_ylim(lsMin, lsMax)
        except:
            print("WARN - LS axes badval??")
        #thisLS.set_ylim(lsMin, lsMax)
        thisLS.grid(which='both', visible=True)

        thisLSnoise = lAxesLSnoise[iAx]
        try:
            thisLSnoise.set_xlim(perMin, perMax)
            thisLSnoise.set_ylim(lsMin, lsMax)
        except:
            print("WARN - LS Noise axes badval??")
        thisLSnoise.grid(which='both', visible=True)

    # output the plot to a figure
    fig1.savefig('test_grid_lc.png', transparent=True)
    figLS.savefig('test_grid_LS.png', transparent=True)
    figLSnoise.savefig('test_grid_LSnoise.png', transparent=True)

    fig2 = plt.figure(2)
    fig2.clf()
    ax2 = fig2.add_subplot(111)
    dum = ax2.scatter(times, mags, c=dayNo)

    cbar = fig2.colorbar(dum, ax=ax2)

    if not lsOnAll:
        return

    print "lcPlot.go INFO - starting on the full dataset..."

    # do the lomb-scargle on the entire dataset
    dtAll = np.max(times) - np.min(times)
    dtAll = 100. / 24.  # (100 hours)
    dtAll = 12.0 / 24.0  # (12 hours max)
    dtMin = np.min(times[1::] - times[0:-1])
    perAll = np.logspace(np.log10(dtMin * 2.), np.log10(dtAll), 250)
    omeAll = 2.0 * np.pi / perAll

    # let's do the LS on the detrended data

    # lsAll = lomb_scargle(times, mags, unctys, omeAll, generalized=False)

    lsAll = lomb_scargle(detMJD, detMag, detUnc, omeAll, generalized=False)
    lsUp, lsNoise = whiteNoiseLS(times, unctys, omeAll, nNoise, pctile)

    fig5 = plt.figure(5, figsize=(8, 4))
    fig5.clf()

    # try replacing perAll * 24. with omeAll / (2.0*np.pi)
    fAll = omeAll / (2.0 * np.pi * 86400.)

    # take log10 of frequency and power

    logFreq = np.log10(fAll)
    logPower = np.log10(lsAll)

    # Save this to a table

    tbl = Table([fAll, lsAll])
    if writeLS:
        tbl.write(filName, format='ascii')
    # Try to select only the data that have a frequency between -3.9 and -2.8

    pwrFit = np.polyfit(logFreq, logPower, 1)

    ax51 = fig5.add_subplot(121)
    ax52 = fig5.add_subplot(122, sharex=ax51, sharey=ax51)

    #    LS = ax51.loglog(perAll * 24., lsAll, 'bo', ms=1, ls='-', color='b')
    #    LSc = ax52.loglog(perAll * 24., lsNoise, \
    #                            ms=1, ls='-', color='0.2', \
    #                                            alpha=0.5)
    #    LSn = ax52.loglog(perAll * 24., lsUp, alpha=0.7, color=coloSim)
    LS = ax51.loglog(fAll, lsAll, 'bo', ms=1, ls='-', color='b')
    LSc = ax52.loglog(fAll, lsNoise, \
                            ms=1, ls='-', color='0.2', \
                                            alpha=0.5)
    LSn = ax52.loglog(fAll, lsUp, alpha=0.7, color=coloSim)

    fig5.subplots_adjust(hspace=0.02, wspace=0.05, bottom=0.15)

    # standardize
    for thisAx in [ax51, ax52]:
        thisAx.grid(which='both', visible=True)
        #        thisAx.set_xlabel('Period (hours)')
        thisAx.set_xlabel(r'Frequency (s$^{-1}$)')

    ax51.set_ylabel('LS Power')
    ax52.tick_params(labelleft='off')

    # annotate the noise axis
    dumAnno = ax52.annotate('%.0f percent, %i trials' \
                                         % (100.-pctile, nNoise), \
                                         (0.05, 0.85), \
                                         xycoords='axes fraction', \
                                         ha='left', va='top', \
                                         color=coloSim, \
                                         alpha=0.7)

    # save this figure to disk
    fig5.savefig('test_alldata_LS.png', transparent=True)

    # Remove the first row from the table

    sigTable.remove_row(0)

    # See what the table looks like

    print sigTable

    # Write the table to disk

    if write:
        sigTable.write(filName, format='ascii')

    # Create a "Figure 7" to plot the logs of the LS in linear space (really logspace, since we're plotting logs)

    f7 = plt.figure(7)
    f7.clf()
    ax7 = f7.add_subplot(111)
    ax7.scatter(logFreq, logPower, color='b')
    ax7.plot(logFreq, logPower, color='b')
    ax7.plot(logFreq,
             np.polyval(pwrFit, logFreq),
             c='r',
             label=r"$\beta$" + ": %5.2f" % pwrFit[0])
    ax7.legend()
    ax7.set_xlabel("log(Frequency)")
    ax7.set_ylabel("log(LS Power)")

    if binLS:

        nBins = 20

        freqBin, pwrBin, errBin, nPerBin = v404_test.BinData(fAll, lsAll, np.ones(len(fAll)), \
            tStart=10**-3.9, tEnd=10**-2.8, BinTime=(0.00146 / nBins))

        print np.shape(pwrBin)

        logFreqBin = np.log10(freqBin)
        logPwrBin = np.log10(pwrBin)
        pwrFitBin, covarBin = np.polyfit(logFreqBin, logPwrBin, 1, cov=True)

        print "Line, covariance matrix:", pwrFitBin, covarBin
        stdResid = np.std(logPwrBin - np.polyval(pwrFitBin, logFreqBin))
        print "Stddev of residuals: %.2e" % (stdResid)

        f8 = plt.figure(8)
        f8.clf()
        ax8 = f8.add_subplot(111)
        ax8.scatter(logFreqBin, logPwrBin, color='b')
        ax8.plot(logFreqBin,
                 np.polyval(pwrFitBin, logFreqBin),
                 c='r',
                 label=r"$\beta$" + ": %5.2f" % pwrFitBin[0])
        ax8.legend()
        ax8.set_xlabel("log(Frequency)")
        ax8.set_ylabel("log(LS Power)")
Example #26
0
def LS_null_hypotesis(t, y, dy, omega, 
                           generalized=False, subtract_mean=False,
                           random_state=None, N_mock=1000,
                           hist=False, plot_hist=True,Nbins=200):
    """Use a monte carlo simulation to compute Lomb-Scargle null hypotesis periodogram
        shuffling the vector {t U y_obs}
    Parameters
    ----------
    The first set of parameters are passed to the lomb_scargle algorithm
    t : array_like
        sequence of times
    y : array_like
        sequence of observations
    dy : array_like
        sequence of observational errors
    omega : array_like
        frequencies at which to evaluate p(omega)
    generalized : bool
        if True (default) use generalized lomb-scargle method
        otherwise, use classic lomb-scargle.
    subtract_mean : bool
        if True (default) subtract the sample mean from the data before
        computing the periodogram.  Only referenced if generalized is False
    Remaining parameters control the bootstrap
    N_mock : int
        number of simulations
    random_state : None, int, or RandomState object
        random seed, or random number generator
    Returns
    -------
    D : ndarray
        distribution of the height of the highest peak
    if hist=True:
        omegaD : ndarray
            distribution of the angular frecuencies corresponding to D
    """
    #print(len(y))
    #print(len(dy))
    random_state = check_random_state(random_state)
    t = np.asarray(t)
    #dy = np.ones_like(y)
    y = np.asarray(y)
    dy = np.asarray(dy) + np.zeros_like(y)

    D = np.zeros(N_mock)
    omegaD= np.zeros(N_mock)

    mock_vector=np.append(y,t)
    mock_dy=dy.copy()
    
    for i in range(100):
        np.random.shuffle(mock_vector)
        print(mock_vector)
    for i in range(N_mock):
        #ind = random_state.randint(0, len(y), len(y))
        #y = np.random.normal(len(t))
        np.random.shuffle(mock_vector) 
        np.random.shuffle(mock_dy)   
        
        p = lomb_scargle(mock_vector[:len(t)], mock_vector[-len(t):], mock_dy, omega,\
                         generalized=generalized, subtract_mean=subtract_mean)
        D[i] = p.max()
        omegaD[i]=omega[p.argmax()]
        
        
    #max_PS_mock=np.max(PS_mock_all,axis=0)
    if hist:
        
        if plot_hist:
            from matplotlib import pyplot as plt
            frecD=omegaD.copy()/(2*np.pi)
            
            plt.figure('null hypothesis hist')
            plt.hist(frecD,normed=True, bins=Nbins)
            plt.hist(frecD,normed=True,histtype='step')

            plt.figure('null hypotesis cumhist')
            Xcum=np.sort(D)
            Ycum=np.array(range(N_mock))/float(N_mock)
            plt.plot(Xcum,Ycum)
            #plt.xlim(Xcum,Xcum)
            plt.grid()
            plt.minorticks_on()
            plt.xlabel('')

        return D,omegaD
    else:
        return D
Example #27
0
def PeriodogramRbandDRW(QSOId, k):
    import matplotlib.pyplot as plt
    #import h5py
    import numpy as np
    #    #########################################################################################################
    #    #import light curve
    #    from QSOLightCurveH5FinalCatalog import QSOLightCurvesFinalCatalog
    #    MJD, mag, magErr = QSOLightCurvesFinalCatalog(QSOId)
    #
    #
    #    #sort the observations with time
    #
    #    SortedInd = np.argsort(MJD)
    #    MJD = MJD[SortedInd]
    #    mag = mag[SortedInd]
    #    magErr = magErr[SortedInd]
    #
    #    ##########################################################################################################
    #    #weighted by the photometric average observations in one night bins
    #    from BinLightCurve import BinLightCurve
    #    MJD, mag, magErr = BinLightCurve(MJD, mag, magErr)
    #
    #    MJD = MJD-np.min(MJD)
    #
    #####################################################
    #Replace with PG1302 light curve
    ######################################################
    #    just insert a file containing the real data you want to run PLS ond DRW on
    data = np.loadtxt(
        r'C:\Users\noahk\pg1302-research\observation-data\pg1302_data_LINEAR+CRTS+ASASSN.txt'
    )
    data2 = np.loadtxt(
        r'C:\Users\noahk\pg1302-research\observation-data\specific_pg1302_data.txt'
    )
    #    print data
    MJD = data[:, 0]
    mag = data[:, 1]
    magErr = data[:, 2]

    SortedInd = np.argsort(MJD)
    MJD = MJD[SortedInd]
    mag = mag[SortedInd]
    magErr = magErr[SortedInd]

    MJD2 = data2[:, 0]
    mag2 = data2[:, 1]
    magErr2 = data2[:, 2]

    SortedInd = np.argsort(MJD2)
    MJD2 = MJD2[SortedInd]
    mag2 = mag2[SortedInd]
    magErr2 = magErr2[SortedInd]

    # print(np.where(MJD==57207.806))
    # print(mag[286])

    print(magErr[286])
    print(magErr)
    MJD3 = np.delete(MJD, 286)
    mag3 = np.delete(mag, 286)

    magErr3 = np.delete(magErr, 286)

    #    #find frequency grid
    from OptimalFrequencyGrid import OptimalFrequencyGrid
    omega, omegaSlope = OptimalFrequencyGrid(MJD)

    #################################################################################################
    #indices to downsample the uniform grid
    deltat = 1
    from MinimumTimeResolution import MinimumTimeResolution
    ind, NumberOfPoints = MinimumTimeResolution(MJD, deltat)
    #

    #    #################################################################################################
    #    #identify best fit parameters for DRW model
    #    import h5py
    #    filename='../QSO1000Iterations'+str(k)+'/QSO1'+str(QSOId)+'_1000Iterations.h5'
    #    f=h5py.File(filename,"r")
    #    BestFitTau=f['/'+str(QSOId)+'/BestFitTau']
    #    BestFitTau=BestFitTau.value
    #    BestFitSigma=f['/'+str(QSOId)+'/BestFitSigma']
    #    BestFitSigma=BestFitSigma.value
    #
    #    BestFitMean=f['/'+str(QSOId)+'/BestFitMean']
    #    BestFitMean=BestFitMean.value
    #    f.close()
    #

    #############################################
    #Fix sigma and tau from Charisi+2015
    #############################################
    BestFitTau = 100
    BestFitSigma = .11
    BestFitMean = 14

    #    from ChiSquareMinimization import ChiSquareMinimization
    #    BestFitSigma, BestFitTau, BestFitMean, ChiSq=ChiSquareMinimization(mag, magErr, MJD)
    #    print BestFitSigma
    #    print BestFitTau
    #    print BestFitMean
    #    print ChiSq

    ###############################################################################################
    # DRW Simulations
    N_bootstraps = 10
    from SimulateTimeSeries import SimulateTimeSeriesDRW
    x = SimulateTimeSeriesDRW(BestFitTau, BestFitSigma, NumberOfPoints, ind,
                              MJD, magErr, BestFitMean, N_bootstraps, deltat)
    #    print x
    x = mag
    plt.errorbar(MJD, x, yerr=magErr, fmt='o', ecolor='black')
    plt.show()

    #    MaxPsim=np.max(Psim,axis=0)
    #    AvgPsim=np.mean(Psim,axis=0)
    #
    #    ################################################################################################
    #    #periodogram
    from astroML.time_series import lomb_scargle
    P_LS = lomb_scargle(MJD, x, magErr, omegaSlope, generalized=True)
    P_LS2 = lomb_scargle(MJD2, mag2, magErr2, omegaSlope, generalized=True)
    P_LS3 = lomb_scargle(MJD3, mag3, magErr3, omegaSlope, generalized=True)
    P_LS = np.log(P_LS)
    P_LS2 = np.log(P_LS2)
    P_LS3 = np.log(P_LS3)
    ftemp = omegaSlope / (2 * np.pi * 86400)
    logf = np.log10(ftemp)
    #     max_peak = np.amax(P_LS)
    #     print(max_peak)
    #     a = np.argmax(P_LS)
    #     max_f = logf[a]
    # #    print(max_peak)
    # #    print max_peak
    #     max_result = np.where(P_LS == max_peak)
    #     fmax = ftemp[max_result]
    #     print(fmax)
    #     print(max_f)
    # #    print fmax
    #     half_max = max_peak/2
    #     nearest = (np.abs(P_LS[0:800] - half_max)).argmin()
    #     h1 = ftemp[nearest]
    #     h2 = ftemp[639]
    # #    print h1
    # #    print h2
    #     fwhm = h2-h1
    #    print fwhm
    plt.plot(logf,
             P_LS,
             '--',
             lw=1,
             zorder=1,
             color="black",
             label='L+C+A w/ outlier')
    plt.plot(logf, P_LS2, '--', lw=1, zorder=1, color='blue', label='L+C')
    plt.plot(logf,
             P_LS3,
             '--',
             lw=1,
             zorder=1,
             color='red',
             label='L+C+A w/o outlier')
    plt.xlabel('Log Frequency (Hz)')
    plt.ylabel('P_LS')
    #    plt.xlim(-8.8,-6.9)
    plt.xlim(-9, -7.2)
    plt.legend()
    # plt.xlim(0,.000000015)
    # plt.axvline(h1)
    # plt.axvline(h2)
    plt.title("LS Periodogram of PG1302 L+C+A Data")
    plt.show()
Example #28
0
import numpy as np
from astroML.time_series import lomb_scargle
from astropy.io import ascii
import matplotlib.pyplot as plt
import urllib2


data = ascii.read('data/Gaia14aab.csv',format='csv')
plotting the motion of one lens.

lensRa, lensDec, id,pmra,pmdec,ref_epoch = sqlutil.get('select ra, dec, source_id,pmra,pmdec,ref_epoch from gaia_dr1.tgas_source where POWER(pmra,2) + POWER(pmdec,2) > 1000000',
                       db='wsdb',host='cappc127.ast.cam.ac.uk', user='******', password='******')

nullmask = data['averagemag.'] != 'null'

data = data[nullmask]

omega = np.linspace(0.01,2,1000.0)


P_LS = lomb_scargle(data['JD'],data['averagemag.'],1,omega,generalized=True)

print(P_LS)

plt.scatter(data['JD'],data['averagemag.'])
plt.show()
mask_tot = time_temp.mask + filtered_data.mask
mask_tot[mask_tot == 2] = 1
time = np.ma.array(time, mask = mask_tot)
print len(time), len(PDCSAP_FLUX)
PDCSAP_FLUX = PDCSAP_FLUX[~time.mask]
PDCSAP_FLUX_err = PDCSAP_FLUX_err[~time.mask]
time = time[~time.mask]	


print len(time), len(PDCSAP_FLUX)

#We compute the periodograms
if LS_idx == 0:
	normval = len(time)
	pgram = diag.lombscargle(time, PDCSAP_FLUX - PDCSAP_FLUX.mean(), f)
	power, z = lomb_scargle(time, PDCSAP_FLUX, PDCSAP_FLUX_err, f, significance = [1.-0.682689492,1.-0.999999426697])
	print z
elif LS_idx == 1:
	pgram = LombScargle(time, PDCSAP_FLUX)
	power = pgram.score(2.*np.pi/f)
elif LS_idx == 2:
	#print time
	power, z = lomb_scargle(time, PDCSAP_FLUX, PDCSAP_FLUX_err, f, significance = [1.-0.682689492,1.-0.999999426697])
	print z
#plt.plot(time, PDCSAP_FLUX)
#plt.show()

#Phase folding for illustrative purposes
offset = ((first_transit%planet_period) - planet_period/2.)

time = np.ma.mod(time - offset,planet_period)
Example #30
0
#period = omega[np.argmax(power)]
#print period
#exit()

omega = np.linspace(period, period + 0.1, 1000)
ax = plt.subplot(211)
for n_terms in [1, 2, 3]:
    P1 = multiterm_periodogram(t, y, dy, omega, n_terms=n_terms)
    plt.plot(omega, P1, lw=1, label='m = %i' % n_terms)
plt.legend(loc=2)
plt.xlim(period, period + 0.1)
plt.ylim(0, 1.0)
plt.ylabel('$1 - \chi^2(\omega) / \chi^2_{ref}$')

plt.subplot(212, sharex=ax)
for generalized in [True, False]:
    if generalized:
        label = 'generalized LS'
    else:
        label = 'standard LS'
    P2 = lomb_scargle(t, y, dy, omega, generalized=generalized)
    plt.plot(omega, P2, lw=1, label=label)
plt.legend(loc=2)
plt.xlim(period, period + 0.1)
plt.ylim(0, 1.0)

plt.xlabel('frequency $\omega$')
plt.ylabel('$P_{LS}(\omega)$')

plt.show()
Example #31
0
#------------------------------------------------------------
# Generate Data
np.random.seed(0)
N = 30
P = 0.3

t = np.random.randint(100, size=N) + 0.3 + 0.4 * np.random.random(N)
y = 10 + np.sin(2 * np.pi * t / P)
dy = 0.5 + 0.5 * np.random.random(N)
y_obs = np.random.normal(y, dy)

#------------------------------------------------------------
# Compute periodogram
period = 10 ** np.linspace(-1, 0, 10000)
omega = 2 * np.pi / period
PS = lomb_scargle(t, y_obs, dy, omega, generalized=True)

#------------------------------------------------------------
# Get significance via bootstrap
D = lomb_scargle_bootstrap(t, y_obs, dy, omega, generalized=True,
                           N_bootstraps=1000, random_state=0)
sig1, sig5 = np.percentile(D, [99, 95])

#------------------------------------------------------------
# Plot the results
fig = plt.figure()
fig.subplots_adjust(left=0.1, right=0.9, hspace=0.25)

# First panel: the data
ax = fig.add_subplot(211)
ax.errorbar(t, y_obs, dy, fmt='.k', lw=1, ecolor='gray')
Example #32
0
vmag = reshape(vmag,shape(vmag)[0])
err = np.zeros(len(jd))+0.03

#Looping through different resolutions to give you an idea of how the sampling resolution can affect the resulting power spectrum.
#Too coarse of sampling results in potentially not identifying important signals within the data
#Too fine of sampling may drown out the true signal amongst false signals in the power spectrum.  
for i in range(181,182): #range(min resolution test, max resolution test):
    diffs = diff(sort(jd))
    Pmin = 2*min(diffs) #Minimum guess for period = twice the smallest sequential time difference between observations
    Pmax = 60 #Maximum guess for period
    Resolution = i  #Frequency sampling resolution (higher isn't always better)
    period = linspace(Pmin,Pmax,Resolution) # Choose a period grid   <<<444,485>>>
    ang_freqs = 2*pi/period

    #####################################################
    power = lomb_scargle(jd,vmag,err,ang_freqs)
    N = len(jd)
    #####################################################

    fig1 = figure(num=None,figsize=(12,6),facecolor='w')
    title('Lomb-Scargle (Res = %d)'%i,fontsize=24)
    ylabel('Power',fontsize=20)
    xlabel('Period [d]',fontsize=20)
    #xlim([1.5,25])
    #ylim([0,0.125])
    plot(period,power,'-',color='#0066cc',lw=1.5)
    #annotate(s='%0.4f' % Pdiffs,fontsize=18,xy=([22,0.8]),xytext=(22,0.8))
    #plot(perbin,powbin,'-',color='#00e600',lw=2)
    xticks(np.arange(0, max(period)+1, 5.0))
    show()
Example #33
0
dy1 = 0.1 + 0.1 * np.random.random(y_obs1.shape)
y_obs1 += np.random.normal(0, dy1)

y_obs2 = np.sin(np.pi * t_obs / 3)
dy2 = 10 * dy1
y_obs2 = y_obs2 + np.random.normal(dy2)

y_window = np.ones_like(y_obs1)

t = np.linspace(0, 100, 10000)
y = np.sin(np.pi * t / 3)

#------------------------------------------------------------
# Compute the periodogram
omega = np.linspace(0, 5, 1001)[1:]
P_obs1 = lomb_scargle(t_obs, y_obs1, dy1, omega)
P_obs2 = lomb_scargle(t_obs, y_obs2, dy2, omega)
P_window = lomb_scargle(t_obs, y_window, 1, omega,
                        generalized=False, subtract_mean=False)
P_true = lomb_scargle(t, y, 1, omega)

omega /= 2 * np.pi

#------------------------------------------------------------
# Prepare the figures
fig = plt.figure(figsize=(5, 2.5))
fig.subplots_adjust(bottom=0.15, hspace=0.35, wspace=0.25,
                    left=0.11, right=0.95)

ax = fig.add_subplot(221)
ax.plot(t, y, '-', c='gray')
Example #34
0
    def __call__(self, tabla, *args, **kwargs):
        self.tabla = tabla
        self.jda, self.maga, self.erra = cargar_datos(self.tabla)
        self.fig, (self.ax1, self.ax2 , self.ax3) = plt.subplots(nrows=3)
        #self.fig.subplots_adjust(hspace=0.09, bottom=0.06, top=0.94, left=0.12, right=0.94)
        self.multi = MultiCursor(self.fig.canvas, (self.ax1,self.ax2), color='r', \
                                 lw=.5, horizOn=None, vertOn=True)

        manager = plt.get_current_fig_manager()
        manager.window.showMaximized()

        #jd/mag
        if self.splineYes == True:
            self.spl, self.splineYes = spline(self.jda, self.maga, 5)
            print "Aplicando spline"
            self.maga = self.maga - self.spl(self.jda)
            #self.ax1.plot(self.jda, self.spl(self.jda), 'r--', lw=3)
            self.spl, self.splineYes = spline(self.jda, self.maga, 5)
            self.ax1.plot(self.jda, self.spl(self.jda), 'r--', lw=3)
            self.maga = self.maga - self.spl(self.jda)
        else:
            print "NO aplicando spline"
            self.spl,self.splineYes = spline(self.jda, self.maga,5)
            self.ax1.plot(self.jda, self.spl(self.jda), 'g--', lw=3)



        self.ax1.plot(self.jda, self.maga, 'o', c='black')
        self.ax1.set_ylim(max(self.maga+0.01), min(self.maga)-0.01)
        self.ax1.set_xlim(min(self.jda)-10, max(self.jda)+0.01)
        self.ax1.set_xlabel(r'Time', fontsize=20)
        self.ax1.set_ylabel(r"Magnitud", fontsize=20)
        if self.name_star!=True:
            self.ax1.text(0.03, 0.142, "%s"%self.name_star, ha='left', va='top', \
                          transform=self.ax1.transAxes, fontsize=25,color="red")






        #GLS
        self.periodos=np.linspace(self.min_per, self.max_per, self.step_per)
        self.omega = 2 * np.pi / self.periodos
        self.PS = lomb_scargle(self.jda, self.maga, self.erra, self.omega, generalized=True)
        self.ax2.plot(self.periodos, self.PS, '-', c='black', lw=1, zorder=1,label="GLS")

        #LS
        model = periodic.LombScargle().fit(self.jda, self.maga, self.erra)
        fmin = 1.0 / self.max_per
        fmax = 1.0 / self.min_per
        df = (fmax - fmin) / self.step_per
        self.power = model.score_frequency_grid(fmin, df, self.step_per)
        self.freqs = fmin + df * np.arange(self.step_per)
        self.ax2.plot(1.0/self.freqs, self.power, '-', c='red', lw=1, zorder=1,label="LS")
        self.ax2.legend(fontsize = 'x-large')

        #PDM




        self.ax2.set_xlabel(r'Periodo', fontsize=20)
        self.ax2.set_ylabel(r"Power", fontsize=20)

        #self.ax2.set_ylim(0,1.01)
        self.ax2.set_xlim(self.min_per, self.max_per)

        self.ax1_bb = self.ax2.get_position()

        self.fig.canvas.mpl_connect('motion_notify_event', self.on_mouse_over)
        plt.tight_layout()
        plt.show()
y_obs = y + np.random.normal(dy)

omega_0 = 2 * np.pi / P

#######################################################################
# Generate the plot with and without the original typo

for typo in [True, False]:
    #------------------------------------------------------------
    # Compute the Lomb-Scargle Periodogram
    sig = np.array([0.1, 0.01, 0.001])
    omega = np.linspace(17, 22, 1000)

    # Notice the typo: we used y rather than y_obs
    if typo is True:
        P_S = lomb_scargle(t, y, dy, omega, generalized=False)
        P_G = lomb_scargle(t, y, dy, omega, generalized=True)
    else:
        P_S = lomb_scargle(t, y_obs, dy, omega, generalized=False)
        P_G = lomb_scargle(t, y_obs, dy, omega, generalized=True)

    #------------------------------------------------------------
    # Get significance via bootstrap
    D = lomb_scargle_bootstrap(t,
                               y_obs,
                               dy,
                               omega,
                               generalized=True,
                               N_bootstraps=1000,
                               random_state=0)
    sig1, sig5 = np.percentile(D, [99, 95])
Example #36
0
            ]
            time = [item[0] for item in inputLC01]
            mag = [item[1] for item in inputLC01]
            error = [item[2] for item in inputLC01]

            for i in range(0, len(amplitude)):
                for j in range(0, len(periods)):
                    sinusoid = [
                        amplitude[i] * sin(2 * pi * (x - time[0]) / periods[j])
                        for x in time
                    ]
                    newmag = [a + b for a, b in zip(mag, sinusoid)]

                    pgram_g = lomb_scargle(time,
                                           newmag,
                                           error,
                                           f,
                                           generalized=True)
                    for k in range(0, len(pgram_g)):
                        if pgram_g[k] == max(pgram_g):
                            newperiod = pd[k]

                    if max(pgram_g) > 0.2 and max(pgram_g) < 0.3:
                        plt.plot(periods[j],
                                 newperiod,
                                 marker='D',
                                 c='lightcoral',
                                 markersize=0.5,
                                 fillstyle='none')

                    newpgram_g = [0] * len(pgram_g)
def PeriodogramRbandDRW(QSOId,k):
    import matplotlib.pyplot as plt
    #import h5py
    import numpy as np
#    #########################################################################################################
#    #import light curve
#    from QSOLightCurveH5FinalCatalog import QSOLightCurvesFinalCatalog
#    MJD, mag, magErr = QSOLightCurvesFinalCatalog(QSOId)
#
#
#    #sort the observations with time
#
#    SortedInd = np.argsort(MJD)
#    MJD = MJD[SortedInd]
#    mag = mag[SortedInd]
#    magErr = magErr[SortedInd]
#
#    ##########################################################################################################
#    #weighted by the photometric average observations in one night bins
#    from BinLightCurve import BinLightCurve
#    MJD, mag, magErr = BinLightCurve(MJD, mag, magErr)
#
#    MJD = MJD-np.min(MJD)
#
#####################################################
#Replace with PG1302 light curve
######################################################
    data=np.loadtxt('C:/Python27/Data/specific_pg1302_data.txt')
#    print data
    MJD=data[:,0]
#    mag=data[:,1]
    F = 250
    mag =np.sin(2 * np.pi * MJD / F)
    magErr=data[:,2]

    SortedInd = np.argsort(MJD)
    MJD = MJD[SortedInd]
    mag = mag[SortedInd]
#    magErr = magErr[SortedInd]
 
#    #find frequency grid
    from OptimalFrequencyGrid import OptimalFrequencyGrid
    omega, omegaSlope = OptimalFrequencyGrid(MJD)

    
    #################################################################################################
    #indices to downsample the uniform grid
    deltat=1
    from MinimumTimeResolution import MinimumTimeResolution
    ind, NumberOfPoints = MinimumTimeResolution(MJD,deltat)
    #
    
#    #################################################################################################
#    #identify best fit parameters for DRW model
#    import h5py
#    filename='../QSO1000Iterations'+str(k)+'/QSO1'+str(QSOId)+'_1000Iterations.h5'
#    f=h5py.File(filename,"r")
#    BestFitTau=f['/'+str(QSOId)+'/BestFitTau']
#    BestFitTau=BestFitTau.value
#    BestFitSigma=f['/'+str(QSOId)+'/BestFitSigma']
#    BestFitSigma=BestFitSigma.value
#
#    BestFitMean=f['/'+str(QSOId)+'/BestFitMean']
#    BestFitMean=BestFitMean.value
#    f.close()
#

#############################################
#Fix sigma and tau from Charisi+2015
#############################################
    BestFitTau=100
    BestFitSigma=.11
    BestFitMean=14
    
    
    #    from ChiSquareMinimization import ChiSquareMinimization
    #    BestFitSigma, BestFitTau, BestFitMean, ChiSq=ChiSquareMinimization(mag, magErr, MJD)
    #    print BestFitSigma
    #    print BestFitTau
    #    print BestFitMean
    #    print ChiSq
    
    ###############################################################################################
    # DRW Simulations
    N_bootstraps=10
    from SimulateTimeSeries import SimulateTimeSeriesDRW
    x=SimulateTimeSeriesDRW(BestFitTau,BestFitSigma,NumberOfPoints,ind,MJD,mag,magErr,BestFitMean,N_bootstraps,deltat)
#    print x
    x = x + mag
    plt.errorbar(MJD, x, yerr=magErr, fmt='o', ecolor='black')
    plt.show()

#    MaxPsim=np.max(Psim,axis=0)
#    AvgPsim=np.mean(Psim,axis=0)
#
#    ################################################################################################
#    #periodogram
    from astroML.time_series import lomb_scargle
    P_LS = lomb_scargle(MJD, x, magErr, omegaSlope, generalized=True)
    
    plt.plot(omegaSlope, P_LS, '-', c='black', lw=1, zorder=1)
    plt.show()
Example #38
0
np.random.seed(0)
N = 30
P = 0.3

t = P / 2 * np.random.random(N) + P * np.random.randint(100, size=N)
y = 10 + np.sin(2 * np.pi * t / P)
dy = 0.5 + 0.5 * np.random.random(N)
y_obs = y + np.random.normal(dy)

omega_0 = 2 * np.pi / P

#------------------------------------------------------------
# Compute the Lomb-Scargle Periodogram
sig = np.array([0.1, 0.01, 0.001])
omega = np.linspace(17, 22, 1000)
P_S = lomb_scargle(t, y, dy, omega, generalized=False)
P_G, z = lomb_scargle(t, y, dy, omega, generalized=True, significance=sig)

#------------------------------------------------------------
# Plot the results
fig = plt.figure()

# First panel: input data
ax = fig.add_subplot(211)
ax.errorbar(t, y_obs, dy, fmt='.k', lw=1, ecolor='gray')
ax.plot([-2, 32], [10, 10], ':k', lw=1)

ax.set_xlim(-2, 32)
ax.set_xlabel('$t$')
ax.set_ylabel('$y(t)$')
Example #39
0
            time, mag, error, ra, dec, flag = loadtxt(file00, dtype='float',delimiter=' ', usecols=(0,1,2,3,4,7), unpack=True)
            inputLC00 = zip(time[0:], mag[0:], error[0:], ra[0:], dec[0:], flag[0:])
            inputLC01 = [[time,mag,error,ra,dec,flag] for (time,mag,error,ra,dec,flag) in inputLC00 if \
			((error != 0.) and (ra != 0.) and (dec != 0.) and (flag == 0.))]
	    std01 = std([item[1] for item in inputLC01])
	    amplitude = [std01*0.3, std01*0.6, std01*0.9, std01*1.2, std01*1.5]
	    time = [item[0] for item in inputLC01]
	    mag = [item[1] for item in inputLC01]
	    error = [item[2] for item in inputLC01]
	    
	    for i in range(0, len(amplitude)):
	        for j in range(0, len(periods)):
	            sinusoid = [amplitude[i] * sin(2*pi*(x-time[0])/periods[j]) for x in time]
	            newmag = [a+b for a,b in zip(mag, sinusoid)]
                        
                    pgram_g = lomb_scargle(time, newmag, error, f, generalized = True)
                    for k in range(0, len(pgram_g)):
                        if pgram_g[k] == max(pgram_g):
                            newperiod = pd[k]
                    
                    if max(pgram_g) > 0.2 and max(pgram_g) < 0.3:
                        plt.plot(periods[j], newperiod, marker='D', c='lightcoral', markersize=0.5, fillstyle='none')
                    
                    newpgram_g = [0] * len(pgram_g)
                    for m in range(0, len(pgram_g)):
                        if pgram_g[m] < max(newpgram_g):
                            newpgram_g[m] = pgram_g[m]
                            
                    if max(newpgram_g) <= 0.6 * max(pgram_g):
        
                        if max(pgram_g) > 0.3 and max(pgram_g) < 0.6:
def LSperiodogram(data,time, errdata, frequencies):
    # A periodogram supposed to work on not uniformly sampled data but the tests showed lack of robustness
    power = amlt.lomb_scargle(time, data, errdata, frequencies)
    return power
Example #41
0
def lombscargle(x, y, yerr, Pmin=0.5, Pmax=70, res=10000):
    periods = linspace(Pmin, Pmax, res)
    ang_freqs = 2 * pi / periods
    powers = lomb_scargle(x, y, yerr, ang_freqs, generalized=True)
    return periods, powers
def monte_carlo_plot(files):

    N = 100000
    short_P = 0.1
    long_P = 62.0
    pd = linspace(short_P, long_P, float(N))
    f = (2.0*pi)/pd
    p0 = log10(2*pi/f)

    for filename in files:
        if filename.endswith("sysrem.txt"):
            periods = 31.5 * random.random_sample((500, 1)) + 0.1
            file00 = open(filename, 'r')
            time, mag, error, ra, dec, flag = loadtxt(file00, dtype='float',delimiter=' ', 
                                                      usecols=(0,1,2,3,4,7), unpack=True)
            inputLC00 = zip(time[0:], mag[0:], error[0:], ra[0:], dec[0:], flag[0:])
            inputLC01 = [[time,mag,error,ra,dec,flag] for (time,mag,error,ra,dec,flag) in inputLC00 if \
			((error != 0.) and (ra != 0.) and (dec != 0.) and (flag == 0.))]
	    std01 = std([item[1] for item in inputLC01])
	    amplitude = [std01*0.3, std01*0.6, std01*0.9, std01*1.2, std01*1.5]
	    time = [item[0] for item in inputLC01]
	    mag = [item[1] for item in inputLC01]
	    error = [item[2] for item in inputLC01]
	    
	    for i in range(0, len(amplitude)):
	        for j in range(0, len(periods)):
	            sinusoid = [amplitude[i] * sin(2*pi*(x-time[0])/periods[j]) for x in time]
	            newmag = [a+b for a,b in zip(mag, sinusoid)]
                        
                    pgram_g = lomb_scargle(time, newmag, error, f, generalized = True)
                    for k in range(0, len(pgram_g)):
                        if pgram_g[k] == max(pgram_g):
                            newperiod = pd[k]
                    
                    if max(pgram_g) > 0.2 and max(pgram_g) < 0.3:
                        plt.plot(periods[j], newperiod, marker='D', c='lightcoral', markersize=0.5, fillstyle='none')
                    
                    newpgram_g = [0] * len(pgram_g)
                    for m in range(0, len(pgram_g)):
                        if pgram_g[m] < max(newpgram_g):
                            newpgram_g[m] = pgram_g[m]
                            
                    if max(newpgram_g) <= 0.6 * max(pgram_g):
        
                        if max(pgram_g) > 0.3 and max(pgram_g) < 0.6:
                            plt.plot(periods[j], newperiod, marker='D', c='khaki', markersize=0.5, fillstyle='none')
                        
                        if max(pgram_g) > 0.6:
                            plt.plot(periods[j], newperiod, marker='D', c='black', markersize=0.5, fillstyle='none')

        break      

    ax = plt.gca()
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlim([0.1,32.0])
    ax.set_ylim([0.1,32.0])
    plt.xlabel('Injected P_rot (days)')
    plt.ylabel('Recovered P_rot (days)')
    red_patch = mpatches.Patch(color='lightcoral', label='0.2 < power < 0.3')
    yellow_patch = mpatches.Patch(color='khaki', label='unique = 1 & 0.3 < power < 0.6')
    black_patch = mpatches.Patch(color='black', label='unique = 1 & power > 0.6')
    plt.legend(handles=[black_patch, yellow_patch, red_patch])    
    plt.savefig("result2.eps",bbox_inches="tight")