Beispiel #1
0
    def multi_search(self, to_plot=False):
        """Search a lightcurve for a secondary signal."""
        # Start with the corrected lightcurve and its associated period
        # Phase on that period and remove it
        white_out = detrend.pre_whiten(self.time, self.corrected_flux, 
                                       self.corrected_unc, self.corr_prot,
                                       which="phased")
        detrended_flux = self.corrected_flux / white_out[2]

        self.corr_trend = white_out[2]
        self.sec_flux = detrended_flux
        self.sec_unc = self.corrected_unc

        # Run lomb-scargle again and re-measure the period
        fit_out = self._run_fit([self.time, self.sec_flux, self.sec_unc])
        self.sec_prot = fit_out[0]
        self.sec_power = fit_out[1]
        self.sec_periods = fit_out[2]
        self.sec_pgram = fit_out[3]
        self.sec_sigmas = fit_out[5]

        eval_out =  evaluate.test_pgram(self.sec_periods, self.sec_pgram,
                                        self.power_threshold)
        plot_aliases = [None, eval_out[2]]

        white_out2 = detrend.pre_whiten(self.time, self.sec_flux, 
                                        self.sec_unc, self.sec_prot,
                                        which="phased")
        self.sec_trend = white_out2[2]

        # Plot!
        if to_plot:
            # Plot them up
            lcs = [[self.time, self.corrected_flux, self.corrected_unc],
                   [self.time, self.sec_flux, self.sec_unc]]
            pgrams = [[self.corr_periods, self.corr_pgram], 
                      [self.sec_periods, self.sec_pgram]]
            best_periods = [self.corr_prot, self.sec_prot]
            data_labels = ["Corrected", "Fund. Prot="
                           "{0:.2f}d Removed".format(self.corr_prot)]
            sigmas = [self.corr_sigmas, self.sec_sigmas]
            rd_fig, rd_axes = plot.compare_multiple(lcs, pgrams, best_periods, 
                                                    sigmas, 
                                                    aliases=plot_aliases,
                                                    data_labels=data_labels,  
                                                    phase_by=self.sec_prot)

            rd_fig.suptitle(self.name, fontsize="large", y=0.99)

            rd_fig.delaxes(rd_axes[3])

            rd_axes[0].plot(self.time, white_out[2], 'b-', lw=2)

            plt.savefig("{0}plot_outputs/{1}_second_period.png".format(
                        base_path,self.name))
Beispiel #2
0
    def choose_initial(self, to_plot=False):
        """Search raw and detrended LCs for periods, and decide whether there's
        a period there.

        """
        # Run a fit on the raw lc
        r_out = self._run_fit("raw")
        raw_fp, raw_power, raw_prots, raw_pgram, raw_alias, raw_sigma = r_out
        logging.debug("Ran raw fit")

        # Run a fit on the detrended lc
        d_out = self._run_fit("detrended")
        det_fp, det_power, det_prots, det_pgram, det_alias, det_sigma = d_out
        logging.debug("Ran detrended fit")

        # Only consider peaks less than ~half the length of the lightcurve
#        max_peak_loc = 0.75 * (self.time[-1] - self.time[0])
        max_peak_loc = 40
        logging.info("Max Prot = %f", max_peak_loc)

        raw_loc2 = np.argmax(raw_pgram[raw_prots<max_peak_loc])
        raw_power2 = raw_pgram[raw_prots<max_peak_loc][raw_loc2]
        raw_prot2 = raw_prots[raw_prots<max_peak_loc][raw_loc2]
        logging.info("raw %d FP %f Power %f", raw_loc2, raw_prot2, raw_power2)

        det_loc2 = np.argmax(det_pgram[det_prots<max_peak_loc])
        det_power2 = det_pgram[det_prots<max_peak_loc][det_loc2]
        det_prot2 = det_prots[det_prots<max_peak_loc][det_loc2]
        logging.info("det %d FP %f Power %f", det_loc2, det_prot2, det_power2)

        # Compare them
        lc_to_use = self._pick_lc(raw_power2, det_power2)
        if lc_to_use<=1:
            logging.info("Using raw lightcurve")
            self.init_prot , self.init_power = raw_prot2, raw_power2
            self.init_periods_to_test, self.init_pgram = raw_prots, raw_pgram
            self.use_flux = self.flux / self.med
            self.use_unc = self.unc_flux / self.med
            self.init_sigmas = raw_sigma
            self.use = "raw"
            data_labels = ["Raw (Selected)", "Detrended"]
        elif lc_to_use==2:
            logging.info("Using detrended lightcurve")
            self.init_prot , self.init_power = det_prot2, det_power2
            self.init_periods_to_test, self.init_pgram = det_prots, det_pgram
            self.use_flux = self.det_flux 
            self.use_unc = self.unc_flux 
            self.init_sigmas = det_sigma
            self.use = "det"
            data_labels = ["Raw", "Detrended (Selected)"]

        logging.info("Initial Prot %f Power %f", self.init_prot, 
                     self.init_power)
        # get power at harmonics
        self.init_harmonics = self._harmonics(self.init_prot, 
                                              self.init_periods_to_test,
                                              self.init_pgram)

        # Get aliases for selected period
        eval_out = evaluate.test_pgram(self.init_periods_to_test, 
                                       self.init_pgram, self.power_threshold)

        # Get phase-folded, smoothed trend
        white_out2 = detrend.pre_whiten(self.time, self.use_flux, 
                                        self.use_unc, self.init_prot,
                                        which="phased")
        self.init_trend = white_out2[2]

 
        if eval_out[-1]==False:
            logging.warning("Selected lightcurve is not clean")
        else:
            logging.debug("Selected lightcurve is clean")
        plot_aliases = [None, eval_out[2]]

        if to_plot:
            # Plot them up
            lcs = [[self.time, self.flux/self.med, abs(self.unc_flux/self.med)],
                   [self.time, self.det_flux, self.det_unc]]
            pgrams = [[raw_prots, raw_pgram], [det_prots, det_pgram]]
            best_periods = [raw_prot2, det_prot2]
            sigmas = [raw_sigma, det_sigma]
            logging.debug(sigmas)
            rd_fig, rd_axes = plot.compare_multiple(lcs, pgrams, best_periods, 
                                                    sigmas, 
                                                    aliases=plot_aliases,
                                                    data_labels=data_labels,  
                                                    phase_by=self.init_prot)

            rd_fig.suptitle(self.name, fontsize="large", y=0.99)

            rd_fig.delaxes(rd_axes[3])

            plt.savefig("{0}plot_outputs/{1}_raw_detrend.png".format(base_path,
                                                                     self.name))
            plt.close("all")
Beispiel #3
0
def run_ls(time,
           flux,
           unc_flux,
           threshold,
           prot_lims=None,
           run_bootstrap=False):
    """Run a periodogram and return it.

    Inputs
    ------
    time, flux, unc_flux: array_like

    prot_lims: list-like, length=2
        minimum and maximum rotation periods to search

    num_prot: integer
        How many rotation periods to search

    Outputs
    -------
    fund_period, fund_power, periods_to_test, periodogram, aliases

    sigmas
        only if run_bootstrap=True
    """

    logging.debug("run ls t %d f %d u %d", len(time), len(flux), len(unc_flux))
    # Define range of period space to search
    # Using real frequencies not angular frequencies
    freq_term = 1.0  # 2.0 * np.pi

    set_f0 = freq_term / prot_lims[1]
    set_fmax = freq_term / prot_lims[0]
    n_freqs = 3e4
    set_df = (set_fmax - set_f0) / n_freqs
    freqs_to_test = set_f0 + set_df * np.arange(n_freqs)

    # Search for a period
    model = lomb_scargle_fast.LombScargleFast().fit(time, flux, unc_flux)
    periodogram = model.score_frequency_grid(f0=set_f0, df=set_df, N=n_freqs)
    logging.debug("pgram count %d", len(periodogram))
    periods_to_test = freq_term / freqs_to_test

    ls_out = evaluate.test_pgram(periods_to_test, periodogram, threshold)
    fund_period, fund_power, aliases, is_clean = ls_out

    # Now bootstrap to find the typical height of the highest peak
    # (Use the same time points, but redraw the corresponding flux points
    # at random, allowing replacement)
    if run_bootstrap:
        N_bootstraps = 500
        n_points = len(flux)
        ind = np.random.randint(0, n_points, (N_bootstraps, n_points))
        bs_periods, bs_powers = np.zeros(N_bootstraps), np.zeros(N_bootstraps)
        for i, f_index in enumerate(ind):
            bs_model = lomb_scargle_fast.LombScargleFast().fit(
                time, flux[f_index], unc_flux[f_index])
            bs_pgram = bs_model.score_frequency_grid(f0=set_f0,
                                                     df=set_df,
                                                     N=n_freqs)
            max_loc = np.argmax(bs_pgram)
            bs_periods[i] = periods_to_test[max_loc]
            bs_powers[i] = bs_pgram[max_loc]


#        logging.debug("Periods and Powers")
#        logging.debug(bs_periods)
#        logging.debug(bs_powers)

        sigmas = np.percentile(bs_powers, [99.9, 99, 95])
        logging.debug("Fund power: %f 99p %f 95p %f", fund_power, sigmas[1],
                      sigmas[2])
    else:
        sigmas = None

    return (fund_period, fund_power, periods_to_test, periodogram, aliases,
            sigmas)
Beispiel #4
0
    def correct_and_fit(self, to_plot=False, n_closest=21):
        """Position-correct and perform a fit."""
        logging.debug("Fitting corrected lightcurve")

        cl_flux, cl_unc = self._clean_it(self.use)

        self._xy_correct(correct_with=cl_flux, n_closest=n_closest)

        fit_out = self._run_fit([self.time, self.corrected_flux,
                                 self.corrected_unc])
        fund_prot, fund_power, periods_to_test, periodogram = fit_out[:4]
        aliases, sigmas = fit_out[4:]

        eval_out =  evaluate.test_pgram(periods_to_test, periodogram, 
                                        self.power_threshold)

        self.corr_prot = fund_prot
        self.corr_power = fund_power
        self.corr_sigmas = sigmas
        self.corr_periods = periods_to_test
        self.corr_pgram = periodogram

        self.corr_harmonics = self._harmonics(self.corr_prot,
                                              self.corr_periods,
                                              self.corr_pgram)

        if eval_out[-1]==False:
            logging.warning("Corrected lightcurve is not clean")
        else:
            logging.debug("Corrected lightcurve is clean")
        plot_aliases = [None, eval_out[2]]

        if to_plot:
            # Plot them up
            lcs = [[self.time, self.use_flux, self.use_unc],
                   [self.time, self.corrected_flux, self.corrected_unc]]
            pgrams = [[self.init_periods_to_test, self.init_pgram], 
                      [periods_to_test, periodogram]]
            best_periods = [self.init_prot, fund_prot]
            data_labels = ["Initial", "Corrected"]
            sigmas = [self.init_sigmas, sigmas]
            rd_fig, rd_axes = plot.compare_multiple(lcs, pgrams, best_periods, 
                                                    sigmas, 
                                                    aliases=plot_aliases,
                                                    data_labels=data_labels,  
                                                    phase_by=fund_prot)

            rd_fig.suptitle(self.name, fontsize="large", y=0.99)

            ptime, fsine = evaluate.fit_sine(self.time, self.corrected_flux,
                                             self.corrected_unc, 
                                             self.corr_prot)

            plotx = np.argsort(ptime)
            rd_axes[2].plot(ptime[plotx], fsine[plotx], color="lightgrey", lw=2)
#            rd_axes[2].set_ylim(min(fsine)*0.9, max(fsine)*1.1)
        
            use_residuals = self.use_flux - fsine
            cor_residuals = self.corrected_flux - fsine

            logging.debug("RESIDUALS")
            logging.debug(use_residuals[:10])
            logging.debug(cor_residuals[:10])

            rd_axes[3].errorbar(self.time % fund_prot, use_residuals, 
                                np.zeros_like(self.time), #self.use_unc,
                                fmt=plot.shape1, ms=2, capsize=0, 
                                ecolor=plot.color1, color=plot.color1,
                                mec=plot.color1)
            rd_axes[3].errorbar(self.time % fund_prot, cor_residuals, 
                                np.zeros_like(self.time), #self.corrected_unc,
                                fmt=plot.shape2, ms=2, capsize=0, 
                                ecolor=plot.color2, color=plot.color2,  
                                mec=plot.color2)
            rd_axes[3].set_xlim(0, fund_prot)

            plt.savefig("{0}plot_outputs/{1}_corrected.png".format(base_path, 
                                                                   self.name))
#            plt.show()
            plt.close("all")
Beispiel #5
0
def run_ls(time, flux, unc_flux, threshold, prot_lims=None, 
           run_bootstrap=False):
    """Run a periodogram and return it.

    Inputs
    ------
    time, flux, unc_flux: array_like

    prot_lims: list-like, length=2
        minimum and maximum rotation periods to search

    num_prot: integer
        How many rotation periods to search

    Outputs
    -------
    fund_period, fund_power, periods_to_test, periodogram, aliases

    sigmas
        only if run_bootstrap=True
    """

    logging.debug("run ls t %d f %d u %d", len(time), len(flux),
                  len(unc_flux))
    # Define range of period space to search
    # Using real frequencies not angular frequencies
    freq_term = 1.0 # 2.0 * np.pi

    set_f0 = freq_term / prot_lims[1]
    set_fmax = freq_term / prot_lims[0]
    n_freqs = 3e4
    set_df = (set_fmax - set_f0) / n_freqs
    freqs_to_test = set_f0 + set_df * np.arange(n_freqs)

    # Search for a period
    model = lomb_scargle_fast.LombScargleFast().fit(time, flux, unc_flux)
    periodogram = model.score_frequency_grid(f0=set_f0, df=set_df, N=n_freqs)
    logging.debug("pgram count %d", len(periodogram))
    periods_to_test = freq_term / freqs_to_test

    ls_out = evaluate.test_pgram(periods_to_test, periodogram, threshold)
    fund_period, fund_power, aliases, is_clean  = ls_out

    # Now bootstrap to find the typical height of the highest peak
    # (Use the same time points, but redraw the corresponding flux points
    # at random, allowing replacement)
    if run_bootstrap:
        N_bootstraps = 500
        n_points = len(flux)
        ind = np.random.randint(0, n_points, (N_bootstraps, n_points))
        bs_periods, bs_powers = np.zeros(N_bootstraps), np.zeros(N_bootstraps)
        for i, f_index in enumerate(ind):
            bs_model = lomb_scargle_fast.LombScargleFast().fit(time, 
                                               flux[f_index], unc_flux[f_index])
            bs_pgram = bs_model.score_frequency_grid(f0=set_f0,  
                                                     df=set_df, N=n_freqs)
            max_loc = np.argmax(bs_pgram)
            bs_periods[i] = periods_to_test[max_loc]
            bs_powers[i] = bs_pgram[max_loc]

#        logging.debug("Periods and Powers")
#        logging.debug(bs_periods)
#        logging.debug(bs_powers)

        sigmas = np.percentile(bs_powers, [99.9, 99, 95])
        logging.debug("Fund power: %f 99p %f 95p %f", 
                      fund_power, sigmas[1], sigmas[2])
    else:
        sigmas=None

    return (fund_period, fund_power, periods_to_test, periodogram, 
            aliases, sigmas)