Ejemplo n.º 1
0
def simpleSnr(time, flux, results):
    """
    calculate a simple snr on the planet based on the depth and scatter
    after you remove the planet model from the data.
    """

    model = BoxLeastSquares(time, flux)
    fmodel = model.model(time, results[0], results[3], results[1])
    flatten = median_subtract(flux - fmodel, 12)

    noise = np.std(flatten)
    snr = results[2] / noise

    return snr
Ejemplo n.º 2
0
def process_lightcurve(lc: LightcurveArbitraryRaster, lc_duration: float, search_settings: dict):
    """
    Perform a transit search on a light curve, using the bls_reference code.

    :param lc:
        The lightcurve object containing the input lightcurve.
    :type lc:
        LightcurveArbitraryRaster
    :param lc_duration:
        The duration of the lightcurve, in units of days.
    :type lc_duration:
        float
    :param search_settings:
        Dictionary of settings which control how we search for transits.
    :type search_settings:
        dict
    :return:
        dict containing the results of the transit search.
    """

    t = lc.times * u.day
    y_filt = lc.fluxes

    # Work out what period range we are scanning
    minimum_period = float(search_settings.get('period_min', 0.5)) * u.day
    maximum_period = float(search_settings.get('period_max', lc_duration / 2)) * u.day

    # Run this lightcurve through the astropy implementation of BLS
    durations = np.linspace(0.05, 0.2, 10) * u.day
    model = BoxLeastSquares(t, y_filt)
    results = model.autopower(durations,
                              minimum_period=minimum_period,
                              maximum_period=maximum_period,
                              minimum_n_transit=2,
                              frequency_factor=2.0)

    # Find best period
    best_period = results.period[np.argmax(results.power)]
    results = {
        'period': float(best_period / u.day),
        'power': np.max(results.power)
    }

    # Extended results to save to disk
    results_extended = results

    # Return results
    return results, results_extended
Ejemplo n.º 3
0
    def period_finder(self,
                      nt=5,
                      min_p=1,
                      max_p=100,
                      n_f=10000,
                      auto=True,
                      method='LS_astropy'):

        self.pmin = min_p
        self.pmax = max_p
        self.method = method

        if self.method == 'LS_astropy':
            if auto:
                ls = LombScargle(self.df.t.values,
                                 self.df.m.values,
                                 self.df.e.values,
                                 nterms=nt)
                self.frequency, self.power = ls.autopower(
                    minimum_frequency=1. / self.pmax,
                    maximum_frequency=1. / self.pmin)
            else:
                self.frequency = np.linspace(1. / self.pmax, 1. / self.pmin,
                                             n_f)
                self.power = LombScargle(self.df.t.values, self.df.m.values,
                                         self.df.e.values).power(
                                             self.frequency)

        elif self.method == 'BLS_astropy':
            model = BoxLeastSquares(self.df.t.values * u.day,
                                    self.df.m.values,
                                    dy=self.df.e.values)
            if auto:
                periodogram = model.autopower(0.2)
                self.frequency = 1. / periodogram.period
                self.power = periodogram.power
            else:
                periods = np.linspace(self.pmin, self.pmax, 10)
                periodogram = model.power(periods, 0.2)
                self.frequency = 1. / periodogram.period
                self.power = periodogram.power
        else:
            print('Method should be chosen between these options:')
            print('LS_astropy, BLS_astropy')
            sys.exit()

        self.set_period()
        self.plot_ls()
Ejemplo n.º 4
0
def test_lightcurve_to_time_series():
    from gammapy.catalog import SourceCatalog4FGL

    catalog_4fgl = SourceCatalog4FGL(
        "$GAMMAPY_DATA/catalogs/fermi/gll_psc_v20.fit.gz")
    lightcurve = catalog_4fgl["FGES J1553.8-5325"].lightcurve()

    table = lightcurve.to_table(sed_type="flux", format="binned-time-series")

    timeseries = BinnedTimeSeries(data=table)

    assert_allclose(timeseries.time_bin_center.mjd[0], 54863.97885336907)
    assert_allclose(timeseries.time_bin_end.mjd[0], 55045.301668796295)

    time_axis = lightcurve.geom.axes["time"]
    assert_allclose(timeseries.time_bin_end.mjd[0], time_axis.time_max.mjd[0])

    # assert that it interfaces with periodograms

    p = BoxLeastSquares.from_timeseries(timeseries=timeseries,
                                        signal_column_name="flux",
                                        uncertainty="flux_errp")

    result = p.power(1 * u.year, 0.5 * u.year)
    assert_allclose(result.duration, 182.625 * u.d)
Ejemplo n.º 5
0
    def refine_ephem_BLS(self, filters=[1, 2], logtrange=-5, dur=None):
        import astropy.units as u
        from astropy.timeseries import BoxLeastSquares

        # pmin,pmax
        pmin = self.p * (1 - 10**logtrange),
        pmax = self.p * (1 + 10**logtrange),

        # preproc
        t_med = np.median(self.t)
        _t = (self.t - t_med) * u.day

        # model setup
        mask = np.isin(self.fid, filters)
        model = BoxLeastSquares(_t[mask], self.yn[mask], self.dyn[mask])

        # durations to search
        durmin = np.max([30. / 3600 / 24, self.p * 0.005])
        durmax = np.min([10., self.p * 0.15])
        dur = np.logspace(np.log10(durmin),
                          np.log10(durmax),
                          num=5,
                          endpoint=True)

        # run search
        out = model.autopower(np.array(dur),
                              minimum_period=pmin,
                              maximum_period=pmax)

        # select best period
        i = np.argmax(out.power)
        p = out.period[i].value
        t0 = out.transit_time[i].value + t_med

        print('period set to %12.12f, a %f fractional change' %
              (p, (self.p - p) / self.p))
        try:
            print('t0 set to %g, %g fraction of the period' %
                  (t0, (t0 - self.t0) / p))
        except:
            pass
        self.p = p
        self.t0 = t0
        self.dur = out.duration[i].value / p

        self.astropyBLS = out
Ejemplo n.º 6
0
    def __findBestSigma(self,
                        maxperiod,
                        window_length,
                        sigma_step,
                        sigma_max,
                        debug_mode=False):
        i = 3  #starting point
        self.sigArr = []
        self.lenArr = []
        self.maxdataArr = []

        while (sigma_max >= i):
            flat = self.rawlc.flatten(
                window_length=window_length).remove_outliers(sigma=i)
            model = BoxLeastSquares(flat.time, flat.flux, dy=0.01)
            testperiods = np.arange(1, maxperiod, 0.001)
            periodogram = model.power(testperiods, 0.16)
            maxID = np.argmax(periodogram.power)
            stat = model.compute_stats(periodogram.period[maxID],
                                       periodogram.duration[maxID],
                                       periodogram.transit_time[maxID])
            self.sigArr.append(sum(stat['per_transit_log_likelihood']))
            self.lenArr.append(len(stat['per_transit_log_likelihood']))
            if debug_mode:
                print([
                    i,
                    sum(stat['per_transit_log_likelihood']),
                    len(stat['per_transit_log_likelihood']),
                    periodogram.period[maxID]
                ])  #Debug
            i += sigma_step

        maxLLikeIndex = np.argwhere(self.lenArr == np.amax(self.lenArr))
        for i in maxLLikeIndex:
            self.maxdataArr.append(self.sigArr[i.item(0)])
        bestFit = np.argmax(self.maxdataArr) - 1
        if debug_mode:
            print("Index of LogLikelihoods")
            print(maxLLikeIndex)
            print("Best Sigma")
            print(bestFit + i)

        return bestFit + i
Ejemplo n.º 7
0
def _bootstrap_max(t, y, dy, pmin, pmax, ffac, random_seed, n_bootstrap=1000):
    """Generate a sequence of bootstrap estimates of the max"""

    rng = np.random.RandomState(random_seed)
    power_max = []
    for _ in range(n_bootstrap):
        s = rng.randint(0, len(y), len(y))  # sample with replacement
        bls_boot = BoxLeastSquares(t, y[s], dy[s])
        result = bls_boot.autopower(
            [0.05, 0.10, 0.15, 0.20, 0.25, 0.33],
            minimum_period=pmin,
            maximum_period=pmax,
            frequency_factor=ffac,
        )
        power_max.append(result.power.max())

    power_max = u.Quantity(power_max)
    power_max.sort()

    return power_max
Ejemplo n.º 8
0
def plot_bls_folds(time,flux,results,ticid, zoom=True):
    
    num=4  #max number of possible planet candidates
    plt.figure(figsize=(8,12))
    s=np.std(flux)
    
    for i,r in enumerate(results):
        plt.subplot(num,1,i+1)
        phase = (time - r[1] + 0.5*r[0]) % r[0] - 0.5*r[0]
        
        model = BoxLeastSquares(time,flux)
        fmodel = model.model(time,results[i,0],results[i,3],results[i,1])
        order=np.argsort(phase)
        plt.plot(phase[order]*24,fmodel[order],'g.-', ms=3)
        plt.plot(phase*24,flux,'k.',label="TIC %u P=%6.2f d" % (ticid, results[i,0]))
        #plt.title(str(ticid) + " Per: " + str(results[i,0]) )
        if zoom:
            plt.xlim(-5.7*results[i,3]*24,5.7*results[i,3]*24)
            plt.ylim(-2.9*r[2], 4*s)
        
        plt.legend(fontsize=8)
Ejemplo n.º 9
0
    def get_ref_vals(lightcurve, p_ref=None):
        t = lightcurve.time
        y = lightcurve.flux
        dy = lightcurve.flux_err

        bls = BoxLeastSquares(t, y, dy)
        durations = [0.05, 0.1, 0.2]
        if p_ref is None:
            periodogram = bls.autopower(durations)
        else:
            periods = np.linspace(p_ref * 0.9, p_ref * 1.1, 5000)
            periodogram = bls.power(periods, durations)

        max_power = np.argmax(periodogram.power)
        stats = bls.compute_stats(periodogram.period[max_power],
                                  periodogram.duration[max_power],
                                  periodogram.transit_time[max_power])
        num_transits = len(stats['transit_times'])
        t0 = periodogram.transit_time[max_power]
        p = periodogram.period[max_power]

        return (t0, p, num_transits)
Ejemplo n.º 10
0
 def __generatePeriodogram(self, maxperiod):
     model = BoxLeastSquares(self.flat.time, self.flat.flux, dy=0.01)
     testperiods = np.arange(1, maxperiod, 0.001)
     self.periodogram = model.power(testperiods, 0.16)
Ejemplo n.º 11
0
def main():
    root = tk.Tk()
    root.withdraw()
    filepath = filedialog.askopenfilename()
    hdulist = fits.open(filepath)
    telescope = hdulist[0].header['telescop'].lower()
    if telescope == 'tess':
        hdu = hdulist['LIGHTCURVE']
        print("TESS file recognized")
        tessID = str(hdulist[1].header['TICID'])
        print(tessID)
        ts = TimeSeries.read(filepath, format='tess.fits')
    elif telescope == 'kepler':
        hdu = hdulist[1]
        print("Kepler file recognized")
        keplerID = str(hdulist[0].header['KEPLERID'])
        print(keplerID)
        ts = TimeSeries.read(filepath, format='kepler.fits')
    else:
        raise NotImplementedError(
            "{} is not implemented, only KEPLER or TESS are "
            "supported through this reader".format(
                hdulist[0].header['telescop']))
    fig, axs = plt.subplots(2, 2)
    if telescope == 'tess':
        fig.suptitle('TESS Id:' + tessID, fontsize=15)
    if telescope == 'kepler':
        fig.suptitle('Kepler Id:' + keplerID, fontsize=15)
    fig.set_size_inches(18.5, 10.5)

    #full data plot
    axs[0, 0].plot(ts.time.jd,
                   ts['sap_flux'],
                   'k.',
                   markersize=1,
                   label='whole')
    axs[0, 0].set_xlabel('Julian Date')
    axs[0, 0].set_ylabel('SAP Flux (e-/s)')
    axs[0, 0].set_title('full data')

    #folded time series
    periodogram = BoxLeastSquares.from_timeseries(ts, 'sap_flux')
    results = periodogram.autopower(0.1 * u.day)
    best = np.argmax(results.power)
    period = results.period[best]
    transit_time = results.transit_time[best]
    ts_folded = ts.fold(period=period, midpoint_epoch=transit_time)
    axs[0, 1].plot(ts_folded.time.jd,
                   ts_folded['sap_flux'],
                   'k.',
                   markersize=1)
    axs[0, 1].set_xlabel('Time (days)')
    axs[0, 1].set_ylabel('SAP FLUX (e-/s)')
    axs[0, 1].set_title('folded time series')

    #binned time series
    mean, median, stddev = sigma_clipped_stats(ts_folded['sap_flux'])
    ts_folded['sap_flux_norm'] = ts_folded['sap_flux'] / median
    ts_binned = aggregate_downsample(ts_folded, time_bin_size=0.003 * u.day)
    axs[1, 0].plot(ts_folded.time.jd,
                   ts_folded['sap_flux_norm'],
                   'k.',
                   markersize=1)
    axs[1, 0].plot(ts_binned.time_bin_start.jd,
                   ts_binned['sap_flux_norm'],
                   'r-',
                   drawstyle='default')
    axs[1, 0].set_xlabel('Time (days)')
    axs[1, 0].set_ylabel('Normalized Flux')
    axs[1, 0].set_title('binned time series')

    #final transit model
    axs[1, 1].plot(ts_folded.time.jd,
                   ts_folded['sap_flux_norm'],
                   'k.',
                   markersize=1)
    axs[1, 1].plot(ts_binned.time_bin_start.jd,
                   ts_binned['sap_flux_norm'],
                   'r-',
                   drawstyle='default')
    axs[1, 1].set_xlabel('Time (days)')
    axs[1, 1].set_ylabel('Normalized Flux')
    axs[1, 1].set_title('transit model')

    plt.show()
Ejemplo n.º 12
0
def computeperiodbs(JDtime, targetflux):
    from astropy.timeseries import BoxLeastSquares
    model = BoxLeastSquares(JDtime, targetflux)
    results = model.autopower(0.16)
    period = results.period[np.argmax(results.power)]
    return period, 0, 0
Ejemplo n.º 13
0
def _package_results(
    tpf,
    target,
    contaminator,
    aper,
    contaminant_aper,
    transit_pixels,
    transit_pixels_err,
    period,
    t0,
    duration,
    plot=False,
):
    """Helper function for packaging up results"""

    # def get_coords(thumb, err, aper, count=400):
    #     Y, X = np.mgrid[: tpf.shape[1], : tpf.shape[2]]
    #     cxs, cys = [], []
    #     for count in range(count):
    #         err1 = np.random.normal(0, err[aper])
    #         cxs.append(np.average(X[aper], weights=thumb[aper] + err1))
    #         cys.append(np.average(Y[aper], weights=thumb[aper] + err1))
    #     cxs, cys = np.asarray(cxs), np.asarray(cys)
    #     cras, cdecs = tpf.wcs.wcs_pix2world(np.asarray([cxs, cys]).T, 1).T
    #     return cras, cdecs

    def get_coords(thumb, err, aper=None):
        if aper is None:
            aper = np.ones(tpf.flux.shape[1:], bool)
        with np.errstate(divide="ignore"):
            Y, X = np.mgrid[:tpf.shape[1], :tpf.shape[2]]
            aper = create_threshold_mask(thumb / err, 3) & aper
            cxs, cys = [], []
            for count in range(500):
                w = np.random.normal(loc=np.abs(thumb[aper]), scale=err[aper])
                cxs.append(np.average(X[aper], weights=w))
                cys.append(np.average(Y[aper], weights=w))
            cxs, cys = np.asarray(cxs), np.asarray(cys)
            k = (cxs > 0) & (cxs < tpf.shape[2]) & (cys > 0) & (cys <
                                                                tpf.shape[1])
            cxs, cys = cxs[k], cys[k]
            cras, cdecs = tpf.wcs.all_pix2world(np.asarray([cxs, cys]).T, 1).T
        return cras, cdecs

    thumb = np.nanmean(np.nan_to_num(tpf.flux.value), axis=0)
    err = (np.sum(np.nan_to_num(tpf.flux_err.value)**2, axis=0)**0.5) / len(
        tpf.time)
    ra_target, dec_target = get_coords(thumb, err, aper=aper)
    bls = BoxLeastSquares(target.time, target.flux, target.flux_err)
    depths = []
    for i in range(50):
        bls.y = target.flux + np.random.normal(0, target.flux_err)
        depths.append(bls.power(period, duration)["depth"][0])
    target_depth = (np.mean(depths), np.std(depths))

    res = {"target_depth": target_depth}
    res["target_ra"] = np.median(ra_target), np.std(ra_target)
    res["target_dec"] = np.median(dec_target), np.std(dec_target)
    res["target_lc"] = target
    res["target_aper"] = aper

    if contaminant_aper.any():

        ra_contaminant, dec_contaminant = get_coords(transit_pixels,
                                                     transit_pixels_err)
        bls = BoxLeastSquares(contaminator.time, contaminator.flux,
                              contaminator.flux_err)
        depths = []
        for i in range(50):
            bls.y = contaminator.flux + np.random.normal(
                0, contaminator.flux_err)
            depths.append(bls.power(period, duration)["depth"][0])
        contaminator_depth = (np.mean(depths), np.std(depths))
        res["contaminator_ra"] = np.median(ra_contaminant), np.std(
            ra_contaminant)
        res["contaminator_dec"] = np.median(dec_contaminant), np.std(
            dec_contaminant)
        res["contaminator_depth"] = contaminator_depth
        res["contaminator_lc"] = contaminator
        res["contaminator_aper"] = contaminant_aper

        d, de = (contaminator_depth[0] - target_depth[0]), np.hypot(
            contaminator_depth[1], target_depth[1])
        res["delta_transit_depth[sigma]"] = d / de

        dra = res["contaminator_ra"][0] - res["target_ra"][0]
        ddec = res["contaminator_dec"][0] - res["target_dec"][0]
        edra = (res["contaminator_ra"][1]**2 + res["target_ra"][1]**2)**0.5
        eddec = (res["contaminator_dec"][1]**2 + res["target_dec"][1]**2)**0.5
        centroid_shift = (((dra**2 + ddec**2)**0.5) * u.deg).to(u.arcsecond)
        ecentroid_shift = (centroid_shift * ((2 * edra / dra)**2 +
                                             (2 * eddec / ddec)**2)**0.5)
        res["centroid_shift"] = (centroid_shift, ecentroid_shift)

    res["period"] = period
    res["t0"] = t0
    res["duration"] = duration
    res["transit_depth"] = transit_pixels
    res["transit_depth_err"] = transit_pixels_err

    if plot:
        res["fig"] = _make_plot(tpf, res)
    return res
Ejemplo n.º 14
0
class BLSStep(OTSStep):
    name = "bls"

    def __init__(self, ts):
        super().__init__(ts)
        self._periods = None
        self._durations = array([0.25, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0
                                 ]) / 24
        self.bls = None
        self.result = None
        self.period = None  # Best-fit period
        self.zero_epoch = None  # Best-fit zero epoch
        self.duration = None  # Best-fit duration
        self.depth = None  # Best-fit depth
        self.snr = None  # Best-fit Signal to noise ratio

    def __call__(self, *args, **kwargs):
        self.logger = getLogger(
            f"{self.name}:{self.ts.name.lower().replace('_','-')}")
        self.logger.info("Running BLS periodogram")
        self._periods = linspace(self.ts.pmin, self.ts.pmax, self.ts.nper)
        self.bls = BoxLeastSquares(self.ts.time * u.day, self.ts.flux,
                                   self.ts.ferr)
        self.result = self.bls.power(self._periods,
                                     self._durations,
                                     objective='snr')
        for p in self.ts.masked_periods:
            self.result.depth_snr *= maskf(self._periods, p, .1)
            self.result.log_likelihood *= maskf(self._periods, p, .1)
        i = argmax(self.result.depth_snr)
        self.period = self.result.period[i].value
        self.snr = self.result.depth_snr[i]
        self.duration = self.result.duration[i].value
        self.depth = self.result.depth[i]
        t0 = self.result.transit_time[i].value
        ep = epoch(self.ts.time.min(), t0, self.period)
        self.zero_epoch = t0 + ep * self.period
        self.ts.update_ephemeris(self.zero_epoch, self.period, self.duration,
                                 self.depth)
        self.logger.info(
            f"BLS SNR {self.snr:.2f} period {self.period:.2f} d, duration {24*self.duration:.2f} h"
        )

    def add_to_fits(self, hdul: HDUList):
        if self.bls is not None:
            h = hdul[0].header
            h.append(Card('COMMENT', '======================'))
            h.append(Card('COMMENT', '     BLS results      '))
            h.append(Card('COMMENT', '======================'))
            h.append(Card('bls_snr', self.snr,
                          'BLS depth signal to noise ratio'),
                     bottom=True)
            h.append(Card('period', self.period, 'Orbital period [d]'),
                     bottom=True)
            h.append(Card('epoch', self.zero_epoch, 'Zero epoch [BJD]'),
                     bottom=True)
            h.append(Card('duration', self.duration, 'Transit duration [d]'),
                     bottom=True)
            h.append(Card('depth', self.depth, 'Transit depth'), bottom=True)

    @bplot
    def plot_snr(self, ax=None):
        if self.period < 1.:
            ax.semilogx(self._periods,
                        self.result.depth_snr,
                        drawstyle='steps-mid')
        else:
            ax.plot(self._periods,
                    self.result.depth_snr,
                    drawstyle='steps-mid')

        ax.axvline(self.period,
                   alpha=0.15,
                   c='orangered',
                   ls='-',
                   lw=10,
                   zorder=-100)
        setp(ax, xlabel='Period [d]', ylabel='Depth SNR')
        ax.autoscale(axis='x', tight=True)
        plt.plot(freq, power, c='k', linewidth=1)
        plt.xlabel('Frequency')
        plt.ylabel('Power')
        plt.title(
            '{} LombScargle Periodogram for original lc'.format(target_ID))
        #ls_plot.show(block=True)
        #        ls_fig.savefig(save_path + '{} - Lomb-Sacrgle Periodogram for original lc.png'.format(target_ID))
        #        plt.close(ls_fig)
        i = np.argmax(power)
        freq_rot = freq[i]
        p_rot = 1 / freq_rot
        print('Rotation Period = {:.3f}d'.format(p_rot))

        # From BLS
        durations = np.linspace(0.05, 1, 22) * u.day
        model = BoxLeastSquares(lc_30min.time * u.day, normalized_flux)
        #        model = BLS(lc_30min.time*u.day, BLS_flux)
        results = model.autopower(durations, frequency_factor=1.0)
        rot_index = np.argmax(results.power)
        rot_period = results.period[rot_index]
        rot_t0 = results.transit_time[rot_index]
        print("Rotation Period from BLS of original = {}d".format(rot_period))

        ########################### batman stuff ######################################
        if injected_planet != False:
            #        type_of_planet = 'Hot Jupiter'
            #        stellar_type = 'F or G'
            params = batman.TransitParams(
            )  #object to store transit parameters
            params.t0 = -4.5  #time of inferior conjunction
            params.per = 8.0
Ejemplo n.º 16
0
    def from_lightcurve(lc, **kwargs):
        """Creates a Periodogram from a LightCurve using the Box Least Squares (BLS) method."""
        # BoxLeastSquares was added to `astropy.stats` in AstroPy v3.1 and then
        # moved to `astropy.timeseries` in v3.2, which makes the import below
        # somewhat complicated.
        try:
            from astropy.timeseries import BoxLeastSquares
        except ImportError:
            try:
                from astropy.stats import BoxLeastSquares
            except ImportError:
                raise ImportError("BLS requires AstroPy v3.1 or later")

        # Validate user input for `lc`
        # (BoxLeastSquares will not work if flux or flux_err contain NaNs)
        lc = lc.remove_nans()
        if np.isfinite(lc.flux_err).all():
            dy = lc.flux_err
        else:
            dy = None

        # Validate user input for `duration`
        duration = kwargs.pop("duration", 0.25)
        if duration is not None and ~np.all(np.isfinite(duration)):
            raise ValueError("`duration` parameter contains illegal nan or inf value(s)")

        # Validate user input for `period`
        period = kwargs.pop("period", None)
        minimum_period = kwargs.pop("minimum_period", None)
        maximum_period = kwargs.pop("maximum_period", None)
        if period is not None and ~np.all(np.isfinite(period)):
            raise ValueError("`period` parameter contains illegal nan or inf value(s)")
        if minimum_period is None:
            if period is None:
                minimum_period = np.max([np.median(np.diff(lc.time)) * 4,
                                         np.max(duration) + np.median(np.diff(lc.time))])
            else:
                minimum_period = np.min(period)
        if maximum_period is None:
            if period is None:
                maximum_period = (np.max(lc.time) - np.min(lc.time)) / 3.
            else:
                maximum_period = np.max(period)

        # Validate user input for `time_unit`
        time_unit = (kwargs.pop("time_unit", "day"))
        if time_unit not in dir(u):
            raise ValueError('{} is not a valid value for `time_unit`'.format(time_unit))

        # Validate user input for `frequency_factor`
        frequency_factor = kwargs.pop("frequency_factor", 10)
        df = frequency_factor * np.min(duration) / (np.max(lc.time) - np.min(lc.time))**2
        npoints = int(((1/minimum_period) - (1/maximum_period))/df)
        if npoints > 1e7:
            raise ValueError('`period` contains {} points.'
                             'Periodogram is too large to evaluate. '
                             'Consider setting `frequency_factor` to a higher value.'
                             ''.format(np.round(npoints, 4)))
        elif npoints > 1e5:
            log.warning('`period` contains {} points.'
                        'Periodogram is likely to be large, and slow to evaluate. '
                        'Consider setting `frequency_factor` to a higher value.'
                        ''.format(np.round(npoints, 4)))

        # Create BLS object and run the BLS search
        bls = BoxLeastSquares(lc.time, lc.flux, dy)
        if period is None:
            period = bls.autoperiod(duration,
                                    minimum_period=minimum_period,
                                    maximum_period=maximum_period,
                                    frequency_factor=frequency_factor)
        result = bls.power(period, duration, **kwargs)
        if not isinstance(result.period, u.quantity.Quantity):
            result.period = u.Quantity(result.period, time_unit)
        if not isinstance(result.power, u.quantity.Quantity):
            result.power = result.power * u.dimensionless_unscaled
        if not isinstance(result.duration, u.quantity.Quantity):
            result.duration = u.Quantity(result.duration, time_unit)

        return BoxLeastSquaresPeriodogram(frequency=1. / result.period,
                                          power=result.power,
                                          default_view='period',
                                          label=lc.label,
                                          targetid=lc.targetid,
                                          transit_time=result.transit_time,
                                          duration=result.duration,
                                          depth=result.depth,
                                          bls_result=result,
                                          snr=result.depth_snr,
                                          bls_obj=bls,
                                          time=lc.time,
                                          flux=lc.flux,
                                          time_unit=time_unit)
Ejemplo n.º 17
0
    format='kepler.fits')  #creates 2 AstroPY timeseries that can be used
ts1 = TimeSeries.read("EverestFits-KepFiltered.fits", format='kepler.fits')

image = fits.open(star.fitsfile)
plt.imshow(image[5].data)  #shows the star

print("Pre KepFilter")
plt.plot(ts.time.jd, ts['sap_flux'], 'k.', markersize=1)
plt.xlabel('Julian Date')
plt.ylabel('Raw Flux (e-/s)')
plt.show()

print("Post KepFilter")
plt.plot(ts1.time.jd, ts1['sap_flux'], 'k.', markersize=1)
plt.xlabel('Julian Date')
plt.ylabel('Raw Flux (e-/s)')
plt.show()

model = BoxLeastSquares(
    ts1.time, ts1["sap_flux"]
)  #creates a box least squares periodogram on the filtered timeseries
john1 = model.autopower(.2)

plt.plot(john1.period, john1.power)  #plots the periods vs the power
plt.show

n = john1.period[np.argmax(
    john1.power)]  #finds the maximum power in the timeseries->n

print("The period is " + str(n) + " days")  #prints out the period
Ejemplo n.º 18
0
    def _create_interact_ui(doc,
                            minp=minimum_period,
                            maxp=maximum_period,
                            resolution=resolution):
        """Create BLS interact user interface."""
        if minp is None:
            minp = 0.3
        if maxp is None:
            maxp = (lc.time[-1] - lc.time[0]) / 2

        time_format = ''
        if lc.time_format == 'bkjd':
            time_format = ' - 2454833 days'
        if lc.time_format == 'btjd':
            time_format = ' - 2457000 days'

        # Some sliders
        duration_slider = Slider(start=0.01,
                                 end=0.5,
                                 value=0.05,
                                 step=0.01,
                                 title="Duration [Days]",
                                 width=400)

        npoints_slider = Slider(start=500,
                                end=10000,
                                value=resolution,
                                step=100,
                                title="BLS Resolution",
                                width=400)

        # Set up the period values, BLS model and best period
        period_values = np.logspace(np.log10(minp), np.log10(maxp),
                                    npoints_slider.value)
        period_values = period_values[(period_values > duration_slider.value)
                                      & (period_values < maxp)]
        model = BoxLeastSquares(lc.time, lc.flux)
        result = model.power(period_values, duration_slider.value)
        loc = np.argmax(result.power)
        best_period = result.period[loc]
        best_t0 = result.transit_time[loc]

        # Some Buttons
        double_button = Button(label="Double Period",
                               button_type="danger",
                               width=100)
        half_button = Button(label="Half Period",
                             button_type="danger",
                             width=100)
        text_output = Paragraph(text="Period: {} days, T0: {}{}".format(
            np.round(best_period, 7), np.round(best_t0, 7), time_format),
                                width=350,
                                height=40)

        # Set up BLS source
        bls_source = prepare_bls_datasource(result, loc)
        bls_help_source = prepare_bls_help_source(bls_source,
                                                  npoints_slider.value)

        # Set up the model LC
        mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
        mf /= np.median(mf)
        mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) >
                 0.9)
        model_lc = LightCurve(lc.time[mask], mf[mask])
        model_lc = model_lc.append(
            LightCurve([(lc.time[0] - best_t0) + best_period / 2], [1]))
        model_lc = model_lc.append(
            LightCurve([(lc.time[0] - best_t0) + 3 * best_period / 2], [1]))

        model_lc_source = ColumnDataSource(
            data=dict(time=np.sort(model_lc.time),
                      flux=model_lc.flux[np.argsort(model_lc.time)]))

        # Set up the LC
        nb = int(np.ceil(len(lc.flux) / 5000))
        lc_source = prepare_lightcurve_datasource(lc[::nb])
        lc_help_source = prepare_lc_help_source(lc)

        # Set up folded LC
        nb = int(np.ceil(len(lc.flux) / 10000))
        f = lc.fold(best_period, best_t0)
        f_source = prepare_folded_datasource(f[::nb])
        f_help_source = prepare_f_help_source(f)

        f_model_lc = model_lc.fold(best_period, best_t0)
        f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
        f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))

        f_model_lc_source = ColumnDataSource(
            data=dict(phase=f_model_lc.time, flux=f_model_lc.flux))

        def _update_light_curve_plot(event):
            """If we zoom in on LC plot, update the binning."""
            mint, maxt = fig_lc.x_range.start, fig_lc.x_range.end
            inwindow = (lc.time > mint) & (lc.time < maxt)
            nb = int(np.ceil(inwindow.sum() / 5000))
            temp_lc = lc[inwindow]
            lc_source.data = {
                'time': temp_lc.time[::nb],
                'flux': temp_lc.flux[::nb]
            }

        def _update_folded_plot(event):
            loc = np.argmax(bls_source.data['power'])
            best_period = bls_source.data['period'][loc]
            best_t0 = bls_source.data['transit_time'][loc]
            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time < maxphase)
            nb = int(np.ceil(inwindow.sum() / 10000))
            f_source.data = {
                'phase': f[inwindow].time[::nb],
                'flux': f[inwindow].flux[::nb]
            }

        # Function to update the widget
        def _update_params(all=False, best_period=None, best_t0=None):
            if all:
                # If we're updating everything, recalculate the BLS model
                minp, maxp = fig_bls.x_range.start, fig_bls.x_range.end
                period_values = np.logspace(np.log10(minp), np.log10(maxp),
                                            npoints_slider.value)
                ok = (period_values > duration_slider.value) & (period_values <
                                                                maxp)
                if ok.sum() == 0:
                    return
                period_values = period_values[ok]
                result = model.power(period_values, duration_slider.value)
                ok = np.isfinite(result['power']) & np.isfinite(result['duration']) &\
                         np.isfinite(result['transit_time']) & np.isfinite(result['period'])
                bls_source.data = dict(period=result['period'][ok],
                                       power=result['power'][ok],
                                       duration=result['duration'][ok],
                                       transit_time=result['transit_time'][ok])
                loc = np.nanargmax(bls_source.data['power'])
                best_period = bls_source.data['period'][loc]
                best_t0 = bls_source.data['transit_time'][loc]

                minpow, maxpow = bls_source.data['power'].min(
                ) * 0.95, bls_source.data['power'].max() * 1.05
                fig_bls.y_range.start = minpow
                fig_bls.y_range.end = maxpow

            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time < maxphase)
            nb = int(np.ceil(inwindow.sum() / 10000))
            f_source.data = {
                'phase': f[inwindow].time[::nb],
                'flux': f[inwindow].flux[::nb]
            }

            mf = model.model(lc.time, best_period, duration_slider.value,
                             best_t0)
            mf /= np.median(mf)
            mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2))
                     > 0.9)
            model_lc = LightCurve(lc.time[mask], mf[mask])

            model_lc_source.data = {
                'time': np.sort(model_lc.time),
                'flux': model_lc.flux[np.argsort(model_lc.time)]
            }

            f_model_lc = model_lc.fold(best_period, best_t0)
            f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
            f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))

            f_model_lc_source.data = {
                'phase': f_model_lc.time,
                'flux': f_model_lc.flux
            }

            vertical_line.update(location=best_period)
            fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(
                np.round(best_period, 7), np.round(best_t0, 7), time_format)
            text_output.text = "Period: {} days, \t T0: {}{}".format(
                np.round(best_period, 7), np.round(best_t0, 7), time_format)

        # Callbacks
        def _update_upon_period_selection(attr, old, new):
            """When we select a period we should just update a few things, but we should not recalculate model
            """
            if len(new) > 0:
                new = new[0]
                best_period = bls_source.data['period'][new]
                best_t0 = bls_source.data['transit_time'][new]
                _update_params(best_period=best_period, best_t0=best_t0)

        def _update_model_slider(attr, old, new):
            """If the duration slider is updated, then update the whole model set."""
            _update_params(all=True)

        def _update_model_slider_EVENT(event):
            """If we update the duration slider, we should update the whole model set.
            This is the same as the _update_model_slider but it has a different call signature...
            """
            _update_params(all=True)

        def _double_period_event():
            fig_bls.x_range.start *= 2
            fig_bls.x_range.end *= 2
            _update_params(all=True)

        def _half_period_event():
            fig_bls.x_range.start /= 2
            fig_bls.x_range.end /= 2
            _update_params(all=True)

        # Help Hover Call Backs
        def _update_folded_plot_help_reset(event):
            f_help_source.data['phase'] = [
                (np.max(f.time) - np.min(f.time)) * 0.98 + np.min(f.time)
            ]
            f_help_source.data['flux'] = [
                (np.max(f.flux) - np.min(f.flux)) * 0.98 + np.min(f.flux)
            ]

        def _update_folded_plot_help(event):
            f_help_source.data['phase'] = [
                (fig_folded.x_range.end - fig_folded.x_range.start) * 0.95 +
                fig_folded.x_range.start
            ]
            f_help_source.data['flux'] = [
                (fig_folded.y_range.end - fig_folded.y_range.start) * 0.95 +
                fig_folded.y_range.start
            ]

        def _update_lc_plot_help_reset(event):
            lc_help_source.data['time'] = [
                (np.max(lc.time) - np.min(lc.time)) * 0.98 + np.min(lc.time)
            ]
            lc_help_source.data['flux'] = [
                (np.max(lc.flux) - np.min(lc.flux)) * 0.9 + np.min(lc.flux)
            ]

        def _update_lc_plot_help(event):
            lc_help_source.data['time'] = [
                (fig_lc.x_range.end - fig_lc.x_range.start) * 0.95 +
                fig_lc.x_range.start
            ]
            lc_help_source.data['flux'] = [
                (fig_lc.y_range.end - fig_lc.y_range.start) * 0.9 +
                fig_lc.y_range.start
            ]

        def _update_bls_plot_help_event(event):
            bls_help_source.data['period'] = [
                bls_source.data['period'][int(npoints_slider.value * 0.95)]
            ]
            bls_help_source.data['power'] = [
                (np.max(bls_source.data['power']) -
                 np.min(bls_source.data['power'])) * 0.98 +
                np.min(bls_source.data['power'])
            ]

        def _update_bls_plot_help(attr, old, new):
            bls_help_source.data['period'] = [
                bls_source.data['period'][int(npoints_slider.value * 0.95)]
            ]
            bls_help_source.data['power'] = [
                (np.max(bls_source.data['power']) -
                 np.min(bls_source.data['power'])) * 0.98 +
                np.min(bls_source.data['power'])
            ]

        # Create all the figures.
        fig_folded = make_folded_figure_elements(f, f_model_lc, f_source,
                                                 f_model_lc_source,
                                                 f_help_source)
        fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(
            np.round(best_period, 7), np.round(best_t0, 5), time_format)
        fig_bls, vertical_line = make_bls_figure_elements(
            result, bls_source, bls_help_source)
        fig_lc = make_lightcurve_figure_elements(lc, model_lc, lc_source,
                                                 model_lc_source,
                                                 lc_help_source)

        # Map changes

        # If we click a new period, update
        bls_source.selected.on_change('indices', _update_upon_period_selection)

        # If we change the duration, update everything, including help button for BLS
        duration_slider.on_change('value', _update_model_slider)
        duration_slider.on_change('value', _update_bls_plot_help)

        # If we increase resolution, update everything
        npoints_slider.on_change('value', _update_model_slider)

        # Make sure the vertical line always goes to the best period.
        vertical_line.update(location=best_period)

        # If we pan in the BLS panel, update everything
        fig_bls.on_event(PanEnd, _update_model_slider_EVENT)
        fig_bls.on_event(Reset, _update_model_slider_EVENT)

        # If we pan in the LC panel, rebin the points
        fig_lc.on_event(PanEnd, _update_light_curve_plot)
        fig_lc.on_event(Reset, _update_light_curve_plot)

        # If we pan in the Folded panel, rebin the points
        fig_folded.on_event(PanEnd, _update_folded_plot)
        fig_folded.on_event(Reset, _update_folded_plot)

        # Deal with help button
        fig_bls.on_event(PanEnd, _update_bls_plot_help_event)
        fig_bls.on_event(Reset, _update_bls_plot_help_event)
        fig_folded.on_event(PanEnd, _update_folded_plot_help)
        fig_folded.on_event(Reset, _update_folded_plot_help_reset)
        fig_lc.on_event(PanEnd, _update_lc_plot_help)
        fig_lc.on_event(Reset, _update_lc_plot_help_reset)

        # Buttons
        double_button.on_click(_double_period_event)
        half_button.on_click(_half_period_event)

        # Layout the widget
        doc.add_root(
            layout([[fig_bls, fig_folded], fig_lc,
                    [
                        Spacer(width=70), duration_slider,
                        Spacer(width=50), npoints_slider
                    ],
                    [
                        Spacer(width=70), double_button,
                        Spacer(width=70), half_button,
                        Spacer(width=300), text_output
                    ]]))
def ffi_lowess_detrend(
        save_path='/Users/mbattley/Documents/PhD/New detrending methods/Smoothing/lowess/QLP lcs/',
        sector=1,
        target_ID_list=[],
        pipeline='2min',
        multi_sector=False,
        use_TESSflatten=False,
        use_peak_cut=False,
        binned=False,
        transit_mask=False,
        injected_planet='user_defined',
        injected_rp=0.1,
        injected_per=8.0,
        detrending='lowess_partial',
        single_target_ID=['HIP 1113'],
        n_bins=30,
        filename=''):
    try:
        lc_30min = lightkurve.lightcurve.TessLightCurve(time=[], flux=[])
        if multi_sector != False:
            sap_lc, pdcsap_lc = two_min_lc_download(target_ID,
                                                    sector=multi_sector[0],
                                                    from_file=False)
            lc_30min = pdcsap_lc
            nancut = np.isnan(lc_30min.flux) | np.isnan(lc_30min.time)
            lc_30min = lc_30min[~nancut]
            clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                lc_30min.time, lc_30min.flux, lc_30min.flux_err, target_ID,
                multi_sector[0], save_path)
            lc_30min.time = clean_time
            lc_30min.flux = clean_flux
            lc_30min.flux_err = clean_flux_err
            for sector_num in multi_sector[1:]:
                sap_lc_new, pdcsap_lc_new = two_min_lc_download(
                    target_ID, sector_num, from_file=False)
                lc_30min_new = pdcsap_lc_new
                nancut = np.isnan(lc_30min_new.flux) | np.isnan(
                    lc_30min_new.time)
                lc_30min_new = lc_30min_new[~nancut]
                clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                    lc_30min_new.time, lc_30min_new.flux,
                    lc_30min_new.flux_err, target_ID, sector_num, save_path)
                lc_30min_new.time = clean_time
                lc_30min_new.flux = clean_flux
                lc_30min_new.flux_err = clean_flux_err
                lc_30min = lc_30min.append(lc_30min_new)
#                    lc_30min.flux = lc_30min.flux.append(lc_30min_new.flux)
#                    lc_30min.time = lc_30min.time.append(lc_30min_new.time)
#                    lc_30min.flux_err = lc_30min.flux_err.append(lc_30min_new.flux_err)
#                nancut = np.isnan(lc_30min.flux) | np.isnan(lc_30min.time)
#                lc_30min = lc_30min[~nancut]
        else:
            try:
                #                if pipeline == 'DIA':
                #                    lc_30min, filename = diff_image_lc_download(target_ID, sector, plot_lc = True, save_path = save_path, from_file = True)
                #                elif pipeline == '2min':
                #                    sap_lc, pdcsap_lc = two_min_lc_download(target_ID, sector = sector, from_file = False)
                #                    lc_30min = pdcsap_lc
                #                    nancut = np.isnan(lc_30min.flux) | np.isnan(lc_30min.time)
                #                    lc_30min = lc_30min[~nancut]
                #                elif pipeline == 'eleanor':
                #                    raw_lc, corr_lc, pca_lc = eleanor_lc_download(target_ID, sector, from_file = False, save_path = save_path, plot_pca = False)
                #                    lc_30min = pca_lc
                #                elif pipeline == 'from_file':
                ##                    sap_lc, pdcsap_lc = two_min_lc_download(target_ID, sector = sector, from_file = False)
                ##                    lcf = lightkurve.open('tess2019140104343-s0012-0000000212461524-0144-s_lc.fits')
                ##                    lc_30min = lcf.PDCSAP_FLUX
                #                    #filename = 'tess2019247000000-0000000224225541-111-cr_llc.fits'
                #                    filename = 'tess2019247000000-0000000146520535-111-cr_llc.fits'
                #                    lc_30min, kspsap_flux = get_lc_from_fits(filename)
                #                elif pipeline == 'from_pickle':
                #                    with open('Original_time.pkl','rb') as f:
                #                        original_time = pickle.load(f)
                #                    with open('Original_flux.pkl','rb') as f:
                #                        original_flux = pickle.load(f)
                #                    lc_30min = lightkurve.lightcurve.TessLightCurve(time = original_time,flux=original_flux)
                #                elif pipeline == 'raw':
                #                    lc_30min = raw_FFI_lc_download(target_ID, sector, plot_tpf = False, plot_lc = True, save_path = save_path, from_file = False)
                if pipeline == 'CDIPS':
                    lc_30min, target_ID, sector = get_lc_from_fits(
                        filename, source=pipeline, save_path=save_path)
                    print(target_ID)
#                elif pipeline == 'QLP':
#                    lc_30min, kspsap_flux = get_lc_from_fits(filename, source = pipeline)
                else:
                    print('Invalid pipeline')

            except:
                print('Lightcurve for {} not available'.format(target_ID))
#            try:
#                raw_lc, corr_lc, pca_lc = eleanor_lc_download(target_ID, sector, from_file = False, save_path = save_path, plot_pca = False)
#                lc_30min = pca_lc
#                pipeline = 'eleanor'
#            except RuntimeError:
#                print('Lightcurve for {} not available'.format(target_ID))
#        sap_lc, pdcsap_lc = two_min_lc_download(target_ID, sector)
#        lc_30min = pdcsap_lc
#        pipeline = '2min'

################### Clean TESS lc pointing systematics ########################
        if multi_sector == False:
            clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                lc_30min.time, lc_30min.flux, lc_30min.flux_err, target_ID,
                sector, save_path)
            lc_30min.time = clean_time
            lc_30min.flux = clean_flux
            lc_30min.flux_err = clean_flux_err

        ######################### Find rotation period ################################
#            normalized_flux = np.array(lc_30min.flux)/np.median(lc_30min.flux)
        normalized_flux = lc_30min.flux
        #
        # From Lomb-Scargle
        freq = np.arange(0.04, 4.1, 0.00001)
        power = LombScargle(lc_30min.time, normalized_flux).power(freq)
        ls_fig = plt.figure()
        plt.plot(freq, power, c='k', linewidth=1)
        plt.xlabel('Frequency')
        plt.ylabel('Power')
        plt.title(
            '{} LombScargle Periodogram for original lc'.format(target_ID))
        #ls_plot.show(block=True)
        #        ls_fig.savefig(save_path + '{} - Lomb-Sacrgle Periodogram for original lc.png'.format(target_ID))
        plt.close(ls_fig)
        i = np.argmax(power)
        freq_rot = freq[i]
        p_rot = 1 / freq_rot
        print('Rotation Period = {:.3f}d'.format(p_rot))
        #
        #        # From BLS
        #        durations = np.linspace(0.05, 1, 22) * u.day
        #        model = BoxLeastSquares(lc_30min.time*u.day, normalized_flux)
        ##        model = BLS(lc_30min.time*u.day, BLS_flux)
        #        results = model.autopower(durations, frequency_factor=1.0)
        #        rot_index = np.argmax(results.power)
        #        rot_period = results.period[rot_index]
        #        rot_t0 = results.transit_time[rot_index]
        #        print("Rotation Period from BLS of original = {}d".format(rot_period))

        ########################### batman stuff ######################################
        #        if injected_planet != False:
        #    #        type_of_planet = 'Hot Jupiter'
        #    #        stellar_type = 'F or G'
        #            params = batman.TransitParams()       #object to store transit parameters
        #            params.t0 = -10.0                      #time of inferior conjunction
        #            params.per = 8.0
        #            params.rp = 0.1
        #            table_data = Table.read("BANYAN_XI-III_members_with_TIC.csv" , format='ascii.csv')
        #            i = list(table_data['main_id']).index(target_ID)
        #            m_star = table_data['Stellar Mass'][i]*m_Sun
        #            r_star = table_data['Stellar Radius'][i]*r_Sun*1000
        #            params.a = (((G*m_star*(params.per*86400.)**2)/(4.*(np.pi**2)))**(1./3))/r_star
        #            if np.isnan(params.a) == True:
        #                #For a: 25 for 10d; 17 for 8d; 10 for 4d; 4-8 (6) for 2 day; 2-5  for 1d; 1-3 (or 8?) for 0.5d
        #                params.a = 17. #semi-major axis (in units of stellar radii)
        #            params.inc = 90.
        #            params.ecc = 0.
        #            params.w = 90.                        #longitude of periastron (in degrees)
        #            params.limb_dark = "nonlinear"        #limb darkening model
        #            params.u = [0.5, 0.1, 0.1, -0.1]      #limb darkening coefficients [u1, u2, u3, u4]
        #
        #            if injected_planet == 'user_defined':
        #                # Build planet from user specified parameters
        #                params.per = injected_per                      #orbital period (days) - try 0.5, 1, 2, 4, 8 & 10d periods
        #                params.rp = injected_rp                       #planet radius (in units of stellar radii) - Try between 0.01 and 0.1 (F/G) or 0.025 to 0.18 (K/M)
        #                params.a = (((G*m_star*(params.per*86400.)**2)/(4.*(np.pi**2)))**(1./3))/r_star
        #                if np.isnan(params.a) == True:
        #                    params.a =  17                            # Recalculates a if period has changed
        #                params.inc = 90.                      #orbital inclination (in degrees)
        #                params.ecc = 0.                       #eccentricity
        #
        #            elif injected_planet == 'exo_archive':
        #                # Randomly inject planet from exoplanet archive
        #                exoplanet_data = Table.read("Exoplanet Archive Planets for injection.csv" , format='ascii.csv')
        #                pl_index = 760#random.randrange(1,1972,1)
        #                params.per = exoplanet_data['pl_orbper'][pl_index]
        #                params.rp = exoplanet_data['pl_radj'][pl_index]*r_Jup/(exoplanet_data['st_rad'][pl_index]*r_Sun)
        #                params.a = exoplanet_data['pl_orbsmax'][pl_index]*au/(exoplanet_data['st_rad'][pl_index]*r_Sun)
        #                if not np.isnan(exoplanet_data['pl_orbincl'][pl_index]):
        #                    params.inc = exoplanet_data['pl_orbincl'][pl_index]
        #                if not np.isnan(exoplanet_data['pl_orbeccen'][pl_index]):
        #                    params.ecc = exoplanet_data['pl_orbeccen'][pl_index]
        #
        #            elif injected_planet == 'set_period':
        #                params.per = 8.0
        #                params.rp = random.uniform(0,0.2)
        #                params.a = 17.
        #                params.inc = 90.
        #                params.ecc = 0.
        #
        #            elif injected_planet == 'set_depth':
        #                params.per = random.uniform(0.15,13.5)
        #                params.rp = 0.05
        #                params.a = 17.
        #                params.inc = 90.
        #                params.ecc = 0.
        #            else:
        #                raise NameError('Invalid inputfor injected planet')
        #
        #            # Defines times at which to calculate lc and models batman lc
        #            t = np.linspace(-13.9165035, 13.9165035, len(lc_30min.time))
        #            index = int(len(lc_30min.time)//2)
        #            mid_point = lc_30min.time[index]
        #            t = lc_30min.time - lc_30min.time[index]
        #            m = batman.TransitModel(params, t)
        #            t += lc_30min.time[index]
        #    #        print("About to compute flux")
        #            batman_flux = m.light_curve(params)
        #    #        print("Computed flux")
        #            batman_model_fig = plt.figure()
        #            plt.scatter(lc_30min.time, batman_flux, s = 2, c = 'k')
        #            plt.xlabel("Time - 2457000 (BTJD days)")
        #            plt.ylabel("Relative flux")
        #            plt.title("batman model transit for {}R ratio".format(params.rp))
        #            #batman_model_fig.savefig(save_path + "batman model transit for {}d {}R planet.png".format(params.per,params.rp))
        #            #plt.close(batman_model_fig)
        #            plt.show()

        ################################# Combining ###################################

        #            combined_flux = np.array(lc_30min.flux)/np.median(lc_30min.flux) + batman_flux -1

        #            injected_transit_fig = plt.figure()
        #            plt.scatter(lc_30min.time, combined_flux, s = 2, c = 'k')
        #            plt.xlabel("Time - 2457000 (BTJD days)")
        #            plt.ylabel("Relative flux")
        #    #        plt.title("{} with injected transits for a {} around a {} Star.".format(target_ID, type_of_planet, stellar_type))
        #            plt.title("{} with injected transits for a {}R {}d planet to star ratio.".format(target_ID, params.rp, params.per))
        #            ax = plt.gca()
        #            for n in range(int(-1*8/params.per),int(2*8/params.per+2)):
        #                ax.axvline(params.t0+n*params.per+mid_point, ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
        #            ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
        #            ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
        #            ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
        #            #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
        ##            injected_transit_fig.savefig(save_path + "{} - Injected transits fig - Period {} - {}R transit.png".format(target_ID, params.per, params.rp))
        ##            plt.close(injected_transit_fig)
        #            plt.show()

        ############################## Removing peaks #################################

        combined_flux = np.array(lc_30min.flux) / np.median(lc_30min.flux)
        #            combined_flux = lc_30min.flux
        if use_peak_cut == True:
            peaks, peak_info = find_peaks(combined_flux,
                                          prominence=0.001,
                                          width=15)
            #peaks = np.array([64, 381, 649, 964, 1273])
            troughs, trough_info = find_peaks(-combined_flux,
                                              prominence=-0.001,
                                              width=15)
            #troughs = np.array([211, 530, 795, 1113])
            #troughs = np.append(troughs, [370,1031])
            #print(troughs)
            flux_peaks = combined_flux[peaks]
            flux_troughs = combined_flux[troughs]
            amplitude_peaks = ((flux_peaks[0] - 1) + (1 - flux_troughs[0])) / 2
            print("Absolute amplitude of main variability = {}".format(
                amplitude_peaks))
            peak_location_fig = plt.figure()
            plt.scatter(lc_30min.time, combined_flux, s=2, c='k')
            plt.plot(lc_30min.time[peaks], combined_flux[peaks], "x")
            plt.plot(lc_30min.time[troughs],
                     combined_flux[troughs],
                     "x",
                     c='r')
            #peak_location_fig.savefig(save_path + "{} - Peak location fig.png".format(target_ID))
            peak_location_fig.show()
            #                plt.close(peak_location_fig)

            near_peak_or_trough = [False] * len(combined_flux)

            for i in peaks:
                for j in range(len(lc_30min.time)):
                    if abs(lc_30min.time[j] - lc_30min.time[i]) < 0.1:
                        near_peak_or_trough[j] = True

            for i in troughs:
                for j in range(len(lc_30min.time)):
                    if abs(lc_30min.time[j] - lc_30min.time[i]) < 0.1:
                        near_peak_or_trough[j] = True

            near_peak_or_trough = np.array(near_peak_or_trough)

            t_cut = lc_30min.time[~near_peak_or_trough]
            flux_cut = combined_flux[~near_peak_or_trough]
            flux_err_cut = lc_30min.flux_err[~near_peak_or_trough]
            #
            #    phase = np.mod(t-t0_rot,p_rot)/p_rot
            #    plt.figure()
            #    plt.scatter(phase,flux, c = 'k', s = 2)
            #    near_trough = (phase<0.1/p_rot) | (phase>1-0.1/p_rot)
            #    t_cut_bottom = t[~near_trough]
            #    flux_cut_bottom = combined_flux[~near_trough]
            #    flux_err_cut_bottom = lc_30min.flux_err[~near_trough]
            #
            #    phase = np.mod(t_cut_bottom-t0_rot,p_rot)/p_rot
            #    near_peak = (phase<0.5+0.1/p_rot) & (phase>0.5-0.1/p_rot)
            #    t_cut = t_cut_bottom[~near_peak]
            #    flux_cut = flux_cut_bottom[~near_peak]
            #    flux_err_cut = flux_err_cut_bottom[~near_peak]
            #
            #    cut_phase = np.mod(t_cut-t0_rot,p_rot)/p_rot
            #    plt.figure()
            #    plt.scatter(cut_phase, flux_cut, c='k', s=2)
            #
            # Plot new cut version
            peak_cut_fig = plt.figure()
            plt.scatter(t_cut, flux_cut, c='k', s=2)
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel("Relative flux")
            plt.title('{} lc after removing peaks/troughs'.format(target_ID))
            ax = plt.gca()
            #ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #peak_cut_fig.savefig(save_path + "{} - Peak cut fig.png".format(target_ID))
            peak_cut_fig.show()
#                plt.close(peak_cut_fig)
        else:
            t_cut = lc_30min.time
            flux_cut = combined_flux
            flux_err_cut = lc_30min.flux_err
            print('Flux cut skipped')

    ############################## Apply transit mask #########################

        if transit_mask == True:
            period = 8.138
            epoch = 1332.31
            duration = 0.15
            phase = np.mod(t_cut - epoch - period / 2, period) / period

            near_transit = [False] * len(flux_cut)

            for i in range(len(t_cut)):
                if abs(phase[i] - 0.5) < duration / period:
                    near_transit[i] = True

            near_transit = np.array(near_transit)

            t_masked = t_cut[~near_transit]
            flux_masked = flux_cut[~near_transit]
            flux_err_masked = flux_err_cut[~near_transit]
            t_new = t_cut[near_transit]

            f = interpolate.interp1d(t_masked, flux_masked, kind='quadratic')
            #                f = interpolate.BarycentricInterpolator(t_masked,flux_masked)

            flux_new = f(t_new)
            interpolated_fig = plt.figure()
            #                plt.scatter(t_masked, flux_masked, s = 2, c = 'k')
            plt.scatter(t_cut, flux_cut, s=2, c='k')
            plt.scatter(t_new, flux_new, s=2, c='r')
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel('Relative flux')
            #                interpolated_fig.savefig(save_path + "{} - Interpolated over transit mask fig.png".format(target_ID))

            t_transit_mask = np.concatenate((t_masked, t_new), axis=None)
            flux_transit_mask = np.concatenate((flux_masked, flux_new),
                                               axis=None)

            sorted_order = np.argsort(t_transit_mask)
            t_transit_mask = t_transit_mask[sorted_order]
            flux_transit_mask = flux_transit_mask[sorted_order]

    ############################## LOWESS detrending ##############################

    # Full lc
        if detrending == 'lowess_full':
            #t_cut = lc_30min.time
            #flux_cut = combined_flux
            full_lowess_flux = np.array([])
            if transit_mask == True:
                lowess = sm.nonparametric.lowess(flux_transit_mask,
                                                 t_transit_mask,
                                                 frac=0.03)
            else:
                lowess = sm.nonparametric.lowess(flux_cut, t_cut, frac=0.03)

        #     number of points = 20 at lowest, or otherwise frac = 20/len(t_section)

            overplotted_lowess_full_fig = plt.figure()
            plt.scatter(t_cut, flux_cut, c='k', s=2)
            plt.plot(lowess[:, 0], lowess[:, 1])
            plt.title(
                '{} lc with overplotted lowess full lc detrending'.format(
                    target_ID))
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel('Relative flux')
            #overplotted_lowess_full_fig.savefig(save_path + "{} lc with overplotted LOWESS full lc detrending.png".format(target_ID))
            plt.show()
            #                plt.close(overplotted_lowess_full_fig)

            residual_flux_lowess = flux_cut / lowess[:, 1]
            full_lowess_flux = np.concatenate((full_lowess_flux, lowess[:, 1]))

            lowess_full_residuals_fig = plt.figure()
            plt.scatter(t_cut, residual_flux_lowess, c='k', s=2)
            plt.title(
                '{} lc after lowess full lc detrending'.format(target_ID))
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel('Relative flux')
            ax = plt.gca()
            #ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #            lowess_full_residuals_fig.savefig(save_path + "{} lc after LOWESS full lc detrending.png".format(target_ID))
            plt.show()
#                plt.close(lowess_full_residuals_fig)

# Partial lc
        if detrending == 'lowess_partial':
            time_diff = np.diff(t_cut)
            residual_flux_lowess = np.array([])
            time_from_lowess_detrend = np.array([])
            full_lowess_flux = np.array([])

            overplotted_detrending_fig = plt.figure()
            plt.scatter(t_cut, flux_cut, c='k', s=2)
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel("Normalized flux")
            #plt.title('{} lc with overplotted detrending'.format(target_ID))

            low_bound = 0
            if pipeline == '2min':
                n_bins = 450
            else:
                n_bins = n_bins
            for i in range(len(t_cut) - 1):
                if time_diff[i] > 0.1:
                    high_bound = i + 1

                    t_section = t_cut[low_bound:high_bound]
                    flux_section = flux_cut[low_bound:high_bound]
                    #                    print(t_section)
                    if len(t_section) >= n_bins:
                        if transit_mask == True:
                            lowess = sm.nonparametric.lowess(
                                flux_transit_mask[low_bound:high_bound],
                                t_transit_mask[low_bound:high_bound],
                                frac=n_bins / len(t_section))
                        else:
                            lowess = sm.nonparametric.lowess(flux_section,
                                                             t_section,
                                                             frac=n_bins /
                                                             len(t_section))
    #                    lowess = sm.nonparametric.lowess(flux_section, t_section, frac=20/len(t_section))
                        lowess_flux_section = lowess[:, 1]
                        plt.plot(t_section, lowess_flux_section, '-')

                        residuals_section = flux_section / lowess_flux_section
                        residual_flux_lowess = np.concatenate(
                            (residual_flux_lowess, residuals_section))
                        time_from_lowess_detrend = np.concatenate(
                            (time_from_lowess_detrend, t_section))
                        full_lowess_flux = np.concatenate(
                            (full_lowess_flux, lowess_flux_section))
                        low_bound = high_bound
                    else:
                        print('Skipped one gap')

            # Carries out same process for final line (up to end of data)
            high_bound = len(t_cut)

            t_section = t_cut[low_bound:high_bound]
            flux_section = flux_cut[low_bound:high_bound]
            if transit_mask == True:
                lowess = sm.nonparametric.lowess(
                    flux_transit_mask[low_bound:high_bound],
                    t_transit_mask[low_bound:high_bound],
                    frac=n_bins / len(t_section))
            else:
                lowess = sm.nonparametric.lowess(flux_section,
                                                 t_section,
                                                 frac=n_bins / len(t_section))
#            lowess = sm.nonparametric.lowess(flux_section, t_section, frac=20/len(t_section))
            lowess_flux_section = lowess[:, 1]
            plt.plot(t_section, lowess_flux_section, '-')
            if injected_planet != False:
                overplotted_detrending_fig.savefig(
                    save_path +
                    "{} - Overplotted lowess detrending - partial lc - {}R {}d injected planet.png"
                    .format(target_ID, params.rp, params.per))
            else:
                overplotted_detrending_fig.savefig(
                    save_path +
                    "{} - Overplotted lowess detrending - partial lc.pdf".
                    format(target_ID))
#            overplotted_detrending_fig.show()
            plt.close(overplotted_detrending_fig)

            residuals_section = flux_section / lowess_flux_section
            residual_flux_lowess = np.concatenate(
                (residual_flux_lowess, residuals_section))
            time_from_lowess_detrend = np.concatenate(
                (time_from_lowess_detrend, t_section))
            full_lowess_flux = np.concatenate(
                (full_lowess_flux, lowess_flux_section))

            #    t_section = t_cut[83:133]
            residuals_after_lowess_fig = plt.figure()
            plt.scatter(time_from_lowess_detrend,
                        residual_flux_lowess,
                        c='k',
                        s=2)
            plt.title(
                '{} lc after LOWESS partial lc detrending'.format(target_ID))
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel('Relative flux')
            #ax = plt.gca()
            #ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            if injected_planet != False:
                residuals_after_lowess_fig.savefig(
                    save_path +
                    "{} lc after LOWESS partial lc detrending - {}R {}d injected planet.png"
                    .format(target_ID, params.rp, params.per))
            else:
                residuals_after_lowess_fig.savefig(
                    save_path +
                    "{} lc after LOWESS partial lc detrending.pdf".format(
                        target_ID))
#            residuals_after_lowess_fig.show()
            plt.close(residuals_after_lowess_fig)

    #    ########################## Periodogram Stuff ##################################

    # Create periodogram
        durations = np.linspace(0.05, 1, 22) * u.day
        if detrending == 'lowess_full' or detrending == 'lowess_partial':
            BLS_flux = residual_flux_lowess
        else:
            BLS_flux = combined_flux
#        with open('Detrended_time.pkl', 'wb') as f:
#            pickle.dump(t_cut, f, pickle.HIGHEST_PROTOCOL)
#        with open('Detrended_flux.pkl', 'wb') as f:
#            pickle.dump(BLS_flux, f, pickle.HIGHEST_PROTOCOL)
        model = BoxLeastSquares(t_cut * u.day, BLS_flux)
        #model = BLS(lc_30min.time*u.day,BLS_flux)
        results = model.autopower(durations,
                                  minimum_n_transit=3,
                                  frequency_factor=1.0)
        #results = model.autopower(durations, minimum_n_transit=2,frequency_factor=1.0)

        # Find the period and epoch of the peak
        index = np.argmax(results.power)
        period = results.period[index]
        #print(results.period)
        t0 = results.transit_time[index]
        duration = results.duration[index]
        transit_info = model.compute_stats(period, duration, t0)
        print(transit_info)

        epoch = transit_info['transit_times'][0]

        #    periodogram_fig, ax = plt.subplots(1, 1, figsize=(8, 4))
        periodogram_fig, ax = plt.subplots(1, 1)

        # Highlight the harmonics of the peak period
        ax.axvline(period.value, alpha=0.4, lw=3)
        for n in range(2, 10):
            ax.axvline(n * period.value, alpha=0.4, lw=1, linestyle="dashed")
            ax.axvline(period.value / n, alpha=0.4, lw=1, linestyle="dashed")

        # Plot and save the periodogram
        ax.plot(results.period, results.power, "k", lw=0.5)
        ax.set_xlim(results.period.min().value, results.period.max().value)
        ax.set_xlabel("period [days]")
        ax.set_ylabel("log likelihood")
        #        ax.set_title('{} - BLS Periodogram after {} detrending - {}R {}d injected planet'.format(target_ID, detrending, params.rp, params.per))
        ax.set_title('{} - BLS Periodogram after {} detrending'.format(
            target_ID, detrending))
        #        periodogram_fig.savefig(save_path + '{} - BLS Periodogram after lowess partial detrending - {}R {}d injected planet.png'.format(target_ID, params.rp, params.per))
        periodogram_fig.savefig(save_path +
                                '{} - BLS Periodogram after {} detrending.pdf'.
                                format(target_ID, detrending))
        plt.close(periodogram_fig)
        #        periodogram_fig.show()

        ##    ################################## Phase folding ##########################
        # Find indices of 2nd and 3rd peaks of periodogram
        all_peaks = scipy.signal.find_peaks(results.power,
                                            width=5,
                                            distance=10)[0]
        all_peak_powers = results.power[all_peaks]
        sorted_power_indices = np.argsort(all_peak_powers)
        sorted_peak_powers = all_peak_powers[sorted_power_indices]
        #        sorted_peak_periods = results.period[sorted_power_indices]

        # Find info for 2nd largest peak in periodogram
        index_peak_2 = np.where(results.power == sorted_peak_powers[-2])[0]
        period_2 = results.period[index_peak_2[0]]
        t0_2 = results.transit_time[index_peak_2[0]]

        # Find info for 3rd largest peak in periodogram
        index_peak_3 = np.where(results.power == sorted_peak_powers[-3])[0]
        period_3 = results.period[index_peak_3[0]]
        t0_3 = results.transit_time[index_peak_3[0]]

        #phase_fold_plot(t_cut, BLS_flux, 8, mid_point+params.t0, target_ID, save_path, '{} with injected 8 day transit folded by transit period - {}R ratio'.format(target_ID, params.rp))
        #phase_fold_plot(lc_30min.time, BLS_flux, rot_period.value, rot_t0.value, target_ID, save_path, '{} folded by rotation period'.format(target_ID))
        #print('Max BLS Period = {} days, t0 = {}'.format(period.value, t0.value))
        phase_fold_plot(
            t_cut, BLS_flux, period.value, t0.value, target_ID, save_path,
            '{} {} residuals folded by Periodogram Max ({:.3f} days)'.format(
                target_ID, detrending, period.value))
        #        period_to_test = p_rot
        #        t0_to_test = 1332
        period_to_test2 = period_2.value
        t0_to_test2 = t0_2.value
        period_to_test3 = period_3.value
        t0_to_test3 = t0_3.value
        #            period_to_test4 = 10.26
        #            t0_to_test4 = 1447.06
        #        phase_fold_plot(t_cut, BLS_flux, p_rot, t0_to_test, target_ID, save_path, '{} folded by rotation period ({} days)'.format(target_ID,period_to_test))
        phase_fold_plot(
            t_cut, BLS_flux, period_to_test2, t0_to_test2, target_ID,
            save_path,
            '{} detrended lc folded by 2nd largest peak ({:0.4} days)'.format(
                target_ID, period_to_test2))
        phase_fold_plot(
            t_cut, BLS_flux, period_to_test3, t0_to_test3, target_ID,
            save_path,
            '{} detrended lc folded by 3rd largest peak ({:0.4} days)'.format(
                target_ID, period_to_test3))
        #            phase_fold_plot(t_cut, BLS_flux, period_to_test4, t0_to_test4, target_ID, save_path, '{} detrended lc folded by {:0.4} days'.format(target_ID,period_to_test4))
        #print("Absolute amplitude of main variability = {}".format(amplitude_peaks))
        #print('Main Variability Period from Lomb-Scargle = {:.3f}d'.format(p_rot))
        #print("Main Variability Period from BLS of original = {}".format(rot_period))
        #variability_table.add_row([target_ID,p_rot,rot_period,amplitude_peaks])

        ############################# Eyeballing ##############################
        """
        Generate 2 x 2 eyeballing plot
        """
        eye_balling_fig, axs = plt.subplots(2, 2, figsize=(16, 10), dpi=120)

        # Original DIA with injected transits setup
        axs[0, 0].scatter(lc_30min.time, combined_flux, s=1, c='k')
        axs[0, 0].set_ylabel('Normalized Flux')
        axs[0, 0].set_xlabel('Time')
        axs[0, 0].set_title('{} - {} light curve'.format(target_ID, 'DIA'))
        #for n in range(int(-1*8/params.per),int(2*8/params.per+2)):
        #    axs[0,0].axvline(params.t0+n*params.per+mid_point, ymin = 0.1, ymax = 0.2, lw=1, c = 'r')

        # Detrended figure setup
        axs[0, 1].scatter(t_cut,
                          BLS_flux,
                          c='k',
                          s=1,
                          label='{} residuals after {} detrending'.format(
                              target_ID, detrending))
        #            axs[0,1].set_title('{} residuals after {} detrending - Sector {}'.format(target_ID, detrending, sector))
        axs[0, 1].set_title(
            '{} residuals after {} detrending - Sectors 14-18'.format(
                target_ID, detrending))
        axs[0, 1].set_ylabel('Normalized Flux')
        axs[0, 1].set_xlabel('Time - 2457000 [BTJD days]')
        #            binned_time, binned_flux = bin(t_cut, BLS_flux, binsize=15, method='mean')
        #            axs[0,1].scatter(binned_time, binned_flux, c='r', s=4)
        #for n in range(int(-1*8/params.per),int(2*8/params.per+2)):
        #    axs[0,1].axvline(params.t0+n*params.per+mid_point, ymin = 0.1, ymax = 0.2, lw=1, c = 'r')

        # Periodogram setup
        axs[1, 0].plot(results.period, results.power, "k", lw=0.5)
        axs[1, 0].set_xlim(results.period.min().value,
                           results.period.max().value)
        axs[1, 0].set_xlabel("period [days]")
        axs[1, 0].set_ylabel("log likelihood")
        axs[1,
            0].set_title('{} - BLS Periodogram of residuals'.format(target_ID))
        axs[1, 0].axvline(period.value, alpha=0.4, lw=3)
        for n in range(2, 10):
            axs[1, 0].axvline(n * period.value,
                              alpha=0.4,
                              lw=1,
                              linestyle="dashed")
            axs[1, 0].axvline(period.value / n,
                              alpha=0.4,
                              lw=1,
                              linestyle="dashed")

        # Folded or zoomed plot setup
        epoch = t0.value
        #            epoch = 1686.67
        period = period.value
        #epoch = t0_3.value
        #period = period_3.value
        #            print('Main epoch is {}'.format(t0.value+lc_30min.time[0]))
        phase = np.mod(t_cut - epoch - period / 2, period) / period
        axs[1, 1].scatter(phase, BLS_flux, c='k', s=1)
        axs[1, 1].set_title('{} Lightcurve folded by {:0.4} days'.format(
            target_ID, period))
        axs[1, 1].set_xlabel('Phase')
        axs[1, 1].set_ylabel('Normalized Flux')
        #axs[1,1].set_xlim(0.4,0.6)
        #            binned_phase, binned_lc = bin(phase, BLS_flux, binsize=15, method='mean')
        #            plt.scatter(binned_phase, binned_lc, c='r', s=4)

        eye_balling_fig.tight_layout()
        eye_balling_fig.savefig(
            save_path + '{} - Full eyeballing fig.pdf'.format(target_ID))
        plt.close(eye_balling_fig)
        #        plt.show()

        ########################### ADDING INFO ROWS ######################
        #            sensitivity_table.add_row([target_ID,sector,pipeline,params.per,params.a,params.rp,period,np.max(results.power),period_2.value,period_3.value])
        with open(save_path + 'Period_info_table.csv', 'a') as f:
            data_row = [
                target_ID, sector,
                np.max(results.power), period, epoch, period_2.value,
                period_3.value, p_rot
            ]
            writer = csv.writer(f, delimiter=',')
            # writer.writerow(["your", "header", "foo"])  # write header
            writer.writerow(data_row)

        ###################### BONUS MULTI-PLOTTING STUFF #################


#        orientation = 'vert'
#
#        if orientation == 'vert':
#            fig, (ax1, ax2, ax3) = plt.subplots(3, 1)
#        elif orientation == 'horiz':
#            fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
#        else:
#            print('Enter legitimate orientation')
#
##            fig, (ax1, ax2, ax3) = plt.subplots(3, 1)
##            fig.subplots_adjust(hspace=0.3)
#
#        ax1.scatter(t_cut,flux_cut, c = 'k', s = 1)
#        ax1.set_xlabel('Time - 2457000 [BTJD days]')
#        ax1.set_ylabel('Normalized Flux')
#        ax1.plot(t_cut, full_lowess_flux, '-')
#        ax1.set_xlim(t_cut[0],t_cut[-1])
#
#        ax2.plot(results.period, results.power, "k", lw=0.5)
#        ax2.set_xlim(results.period.min().value, results.period.max().value)
#        ax2.set_xlabel("period [days]")
#        ax2.set_ylabel("log likelihood")
#        ax2.axvline(period, alpha=0.4, lw=3)
#        for n in range(2, 10):
#            ax2.axvline(n*period, alpha=0.4, lw=1, linestyle="dashed")
#            ax2.axvline(period / n, alpha=0.4, lw=1, linestyle="dashed")
#
#        ax3.scatter(phase, BLS_flux, c='k', s=1)
#        ax3.set_xlabel('Phase')
#        ax3.set_ylabel('Normalized Flux')
#        ax3.set_xlim(0,1)
#        plt.text(0.5,0.5,'Folded by {}d'.format(period), fontsize=12)
#
#        plt.show()

################## Saving detrended lc to file  ###################

        detrended_lc = lightkurve.lightcurve.TessLightCurve(
            time=t_cut, flux=BLS_flux, flux_err=lc_30min.flux_err)
        detrended_lc.to_csv(
            save_path + 'Detrended_lcs/{}_detrended_lc.csv'.format(target_ID))

        ###################################################################

    except RuntimeError:
        print('No DiffImage lc exists for {}'.format(target_ID))
    except:
        print('Some other error for {}'.format(target_ID))
    return t_cut, BLS_flux, phase, epoch, period
Ejemplo n.º 20
0
        model = TLS(lc.time.value, lc.flux, lc.flux_err)
        result = model.power(n_transits_min=1,
                             period_min=args.min_period,
                             period_max=args.max_period,
                             use_threads=args.ncpu,
                             show_progress_bar=True)

        period = result.period
        t0 = result.T0
        dur = result.duration
        depth = result.depth

        periods, power = result.periods, result.power

    elif args.method == 'BLS':
        model = BoxLeastSquares(lc.time.value, lc.flux, dy=lc.flux_err)
        result = model.autopower(0.15)

        periods, power = result.period, result.power

        idx = np.argmax(power)
        period = periods[idx]
        t0 = result.transit_time[idx]
        dur = result.duration[idx]
        depth = result.depth[idx]

    #if i==1:
    #    period *= 2 2458339.018159

    phase = (lc.time.value - t0 + 0.5 * period) % period - 0.5 * period
    fph = (lc.time.value - t0 + 0.5 * period) % period - 0.5 * period
Ejemplo n.º 21
0
def bls_estimator(
    x,
    y,
    yerr=None,
    duration=0.2,
    min_period=None,
    max_period=None,
    objective=None,
    method=None,
    oversample=10,
    **kwargs,
):
    """Estimate the period of a time series using box least squares

    All extra keyword arguments are passed directly to
    :func:`astropy.timeseries.BoxLeastSquares.autopower`.

    Args:
        x (ndarray[N]): The times of the observations
        y (ndarray[N]): The observations at times ``x``
        yerr (Optional[ndarray[N]]): The uncertainties on ``y``
        min_period (Optional[float]): The minimum period to consider
        max_period (Optional[float]): The maximum period to consider

    Returns:
        A dictionary with the computed autocorrelation function and the
        estimated period. For compatibility with the
        :func:`lomb_scargle_estimator`, the period is returned as a list with
        the key ``peaks``.

    """
    kwargs["minimum_period"] = kwargs.get("minimim_period", min_period)
    kwargs["maximum_period"] = kwargs.get("maximum_period", max_period)

    x_ref = 0.5 * (np.min(x) + np.max(x))
    bls = BoxLeastSquares(x - x_ref, y, yerr)

    # Estimate the frequency factor to not be insanely slow
    if "frequency_factor" not in kwargs:
        kwargs["frequency_factor"] = 1.0
        periods = bls.autoperiod(duration, **kwargs)
        while len(periods) > len(x):
            kwargs["frequency_factor"] *= 2
            periods = bls.autoperiod(duration, **kwargs)

    # Compute the periodogram
    pg = bls.autopower(
        duration,
        objective=objective,
        method=method,
        oversample=oversample,
        **kwargs,
    )

    # Correct for the reference time offset
    pg.transit_time += x_ref

    # Find the peak
    peaks = find_peaks(1 / pg.period, pg.power, max_peaks=1)
    results = dict(bls=pg, peaks=peaks, peak_info=None)
    if not len(peaks):
        return results

    # Extract the relevant information at the peak
    ind = peaks[0]["index"]
    results["peak_info"] = dict(
        (k, v[ind]) for k, v in pg.items() if k != "objective")
    return results
def generate_plots_s3(ticid,sector,cam,ccd, \
                   bls_bucket="tesssearchresults", \
                   detrend_bucket="tesssearchresults", \
                   ffilc_bucket="straw-lightcurves", \
                   outpath="/Users/smullally/TESS/lambdaSearch/strawTests/blsResults/s0001-kdwarf/plots/"):
    """
    Given a TICID, sector, camera, ccd and the bucket locations.
    generate a one page plot for each signal found by the bls using 
    the information in those files.
    bls_bucket contains the search results csv file.
    detrend_bucket contains the detrend fits file.
    ffi_bucket contains the raw light curve fits files.
    returns hdus and a dictionary of the csv.
    """

    rootname = "tic%012u_s%04u-%1u-%1u" % (ticid, sector, cam, ccd)
    path = "tic%012u/" % ticid
    bls_name = "%s_plsearch.csv" % rootname
    det_name = "%s_detrend.fits" % rootname
    lc_name = "%s_stlc.fits" % rootname

    if detrend_bucket[0] == "/":
        det_hdu = fits.open(detrend_bucket + path + det_name)
        bls = np.loadtxt(bls_bucket + path + bls_name, delimiter=',')
    else:
        det_hdu = loadFitsFromUri(detrend_bucket, path, det_name)
        bls = loadCsvFromUri(bls_bucket, path, bls_name)
    if ffilc_bucket[0] == "/":
        raw_hdu = fits.open(ffilc_bucket + path + lc_name)
    else:
        raw_hdu = loadFitsFromUri(ffilc_bucket, path, lc_name)

    #Get the number of signals found by the bls.
    if len(bls.shape) == 1:
        N = 1
        bls = bls.reshape((1, 7))
        #print(bls.shape)
    else:
        N = bls.shape[0]

    time_raw = raw_hdu[1].data['TIME']
    raw = raw_hdu[1].data['SAP_FLUX']
    time_det = det_hdu[1].data['TIME']
    detrend = det_hdu[1].data['DETREND_FLUX']

    #plt.plot(time_det,detrend,'.')

    head = raw_hdu[1].header
    try:
        ave_im = raw_hdu[2].data
    except:
        ave_im = np.zeros((10, 10))
    meta = {}
    meta['sector'] = sector
    meta['cam'] = cam
    meta['ccd'] = ccd
    try:
        meta['imloc'] = (head['CUBECOL'], head['CUBEROW'])
    except:
        meta['imloc'] = (head['APCEN_Y'], head['APCEN_X'])

    meta['radius'] = head['AP_RAD']

    for i in range(N):
        #print(i)

        meta['period'] = bls[i, 0]
        meta['dur'] = bls[i, 3]
        meta['epoch'] = bls[i, 1]
        meta['snr'] = bls[i, 4]
        meta['depth'] = bls[i, 2]
        meta['ntrans'] = bls[i, 5]
        meta['id'] = ticid
        meta['pn'] = i + 1

        #print(meta)

        bls_object = BoxLeastSquares(time_det, detrend)
        model = bls_object.model(time_det, meta['period'], \
                                      meta['dur'], meta['epoch'])
        out_name = "%s-%02i_plot.png" % (rootname, meta['pn'])
        output = outpath + out_name
        plt.figure(figsize=(10, 12))
        report.summaryPlot1(time_raw, raw, time_det, detrend, model, ave_im,
                            meta)

        plt.savefig(output)
        print(output)
Ejemplo n.º 23
0
def process_cell(matrix, cell, progress_indicator):
    alphabet_size = cell[0]
    paa_division_integer = cell[1]

    progression = 0 if progress_indicator == -1 else progress_indicator

    # Download or use downloaded lightcurve files
    time_flux_tuple_arr = pm.get_lightcurve_data()

    # get ground truth values for all lc's with autocorrelation
    ground_truth_arr = pm.get_ground_truth_values(time_flux_tuple_arr)

    # transform durations from exoplanet archieve from hours to days
    actual_duration_arr = [
        3.88216 / 24, 2.36386 / 24, 3.98235 / 24, 4.56904 / 24, 3.60111 / 24,
        5.16165 / 24, 3.19843 / 24
    ]  ##kepler-2,3,4,5,6,7,8 https://exoplanetarchive.ipac.caltech.edu/cgi-bin/TblView/nph-tblView?app=ExoTbls&config=cumulative

    #mean array of periods
    mean_period_arr = []

    # Calculate matrix values for all lighcurves
    # get flux, time, duration and ground thruth for i'th tuple
    ground_truth_period = ground_truth_arr[progression]
    actual_duration = actual_duration_arr[progression]

    time_flux_tuple = time_flux_tuple_arr[progression]
    time = time_flux_tuple[0]
    norm_fluxes = time_flux_tuple[1]

    dat_size = norm_fluxes.size

    # Find Period for eaxh parameter combination alphabets_size/PAA_division_interger of SAX

    # PAA transformation procedure
    # Determine number of PAA points from the datasize devided by the paa_division_integer(number of points per segment)
    paa_points = int(dat_size / paa_division_integer)

    # PAA transformation of data
    PAA_array = paa(norm_fluxes, paa_points)
    PAA_array = np.asarray(PAA_array, dtype=np.float32)

    # SAX conversion
    # Get breakpoints to convert segments into SAX string
    breakPointsArray = pm.getBreakPointsArray(PAA_array, alphabet_size)
    sax_output = ts_to_string(PAA_array, breakPointsArray)

    # Convert to numeric SAX representation
    numericSaxConversionArray = pm.getNumericSaxArray(breakPointsArray)
    numeric_SAX_flux = []

    for symbol_index in range(len(sax_output)):
        letter_represented_as_int = pm.getAlfabetToNumericConverter(
            sax_output[symbol_index], numericSaxConversionArray)
        numeric_SAX_flux.append(letter_represented_as_int)

    numeric_SAX_flux = np.asarray(numeric_SAX_flux, dtype=np.float32)
    numeric_SAX_time = time

    # Repeat each element in array x times, where x is the number of PAA points
    repeated_x_array = np.repeat(numeric_SAX_time, paa_points)

    # How many elements each list should have
    n = int(len(repeated_x_array) / paa_points)
    final_x_array = []
    lists = list(pm.divide_array_in_chunks(repeated_x_array, n))

    # take mean of all chunks
    for l in lists:
        final_x_array.append(np.mean(l))
    numeric_SAX_time = final_x_array

    # BoxLeastSquares applied to numeric SAX representation
    BLS = BoxLeastSquares(numeric_SAX_time, numeric_SAX_flux)
    periodogram = BLS.autopower(actual_duration)

    # Find period with highest power in periodogram
    best_period = np.argmax(periodogram.power)
    period = periodogram.period[best_period]

    # Add error in percentage between best peiord and ground truth to array with periods
    ground_truth_error = (abs(period - ground_truth_period) /
                          ground_truth_period) * 100

    # Update matrix
    if progression == 0:
        matrix[alphabet_size - MIN_SAX][paa_division_integer -
                                        MIN_PAA] = ground_truth_error
    else:
        #Update mean of particualr parameter combination
        current_value = matrix[alphabet_size - MIN_SAX][paa_division_integer -
                                                        MIN_PAA]
        matrix[alphabet_size -
               MIN_SAX][paa_division_integer -
                        MIN_PAA] = (current_value * progression +
                                    ground_truth_error) / (progression + 1)
def ffi_lowess_detrend(save_path='',
                       sector=1,
                       target_ID_list=[],
                       pipeline='2min',
                       multi_sector=False,
                       use_peak_cut=False,
                       binned=False,
                       transit_mask=False,
                       injected_planet='user_defined',
                       injected_rp=0.1,
                       injected_per=8.0,
                       detrending='lowess_partial',
                       single_target_ID=['HIP 1113'],
                       n_bins=30):
    for target_ID in target_ID_list:
        try:
            lc_30min = lightkurve.lightcurve.TessLightCurve(time=[], flux=[])
            if multi_sector != False:
                sap_lc, pdcsap_lc = two_min_lc_download(target_ID,
                                                        sector=multi_sector[0],
                                                        from_file=False)
                lc_30min = pdcsap_lc
                nancut = np.isnan(lc_30min.flux) | np.isnan(lc_30min.time)
                lc_30min = lc_30min[~nancut]
                clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                    lc_30min.time, lc_30min.flux, lc_30min.flux_err, target_ID,
                    multi_sector[0], save_path)
                lc_30min.time = clean_time
                lc_30min.flux = clean_flux
                lc_30min.flux_err = clean_flux_err
                for sector_num in multi_sector[1:]:
                    sap_lc_new, pdcsap_lc_new = two_min_lc_download(
                        target_ID, sector_num, from_file=False)
                    lc_30min_new = pdcsap_lc_new
                    nancut = np.isnan(lc_30min_new.flux) | np.isnan(
                        lc_30min_new.time)
                    lc_30min_new = lc_30min_new[~nancut]
                    clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                        lc_30min_new.time, lc_30min_new.flux,
                        lc_30min_new.flux_err, target_ID, sector_num,
                        save_path)
                    lc_30min_new.time = clean_time
                    lc_30min_new.flux = clean_flux
                    lc_30min_new.flux_err = clean_flux_err
                    lc_30min = lc_30min.append(lc_30min_new)
#                    lc_30min.flux = lc_30min.flux.append(lc_30min_new.flux)
#                    lc_30min.time = lc_30min.time.append(lc_30min_new.time)
#                    lc_30min.flux_err = lc_30min.flux_err.append(lc_30min_new.flux_err)
            else:
                try:
                    if pipeline == 'DIA':
                        lc_30min, filename = diff_image_lc_download(
                            target_ID,
                            sector,
                            plot_lc=True,
                            save_path=save_path,
                            from_file=True)
                    elif pipeline == '2min':
                        sap_lc, pdcsap_lc = two_min_lc_download(
                            target_ID, sector=sector, from_file=False)
                        lc_30min = pdcsap_lc
                        nancut = np.isnan(lc_30min.flux) | np.isnan(
                            lc_30min.time)
                        lc_30min = lc_30min[~nancut]
                    elif pipeline == 'eleanor':
                        raw_lc, corr_lc, pca_lc = eleanor_lc_download(
                            target_ID,
                            sector,
                            from_file=False,
                            save_path=save_path,
                            plot_pca=False)
                        lc_30min = pca_lc
                    elif pipeline == 'from_file':
                        lcf = lightkurve.open(
                            'tess2019140104343-s0012-0000000212461524-0144-s_lc.fits'
                        )
                        lc_30min = lcf.PDCSAP_FLUX
                    elif pipeline == 'from_pickle':
                        with open('Original_time.pkl', 'rb') as f:
                            original_time = pickle.load(f)
                        with open('Original_flux.pkl', 'rb') as f:
                            original_flux = pickle.load(f)
                        lc_30min = lightkurve.lightcurve.TessLightCurve(
                            time=original_time, flux=original_flux)
                    elif pipeline == 'raw':
                        lc_30min = raw_FFI_lc_download(target_ID,
                                                       sector,
                                                       plot_tpf=False,
                                                       plot_lc=True,
                                                       save_path=save_path,
                                                       from_file=False)
                        pipeline = "raw"
                    else:
                        print('Invalid pipeline')

                except:
                    print('Lightcurve for {} not available'.format(target_ID))

            ################### Clean TESS lc pointing systematics ########################
            if multi_sector == False:
                clean_time, clean_flux, clean_flux_err = clean_tess_lc(
                    lc_30min.time, lc_30min.flux, lc_30min.flux_err, target_ID,
                    sector, save_path)
                lc_30min.time = clean_time
                lc_30min.flux = clean_flux
                lc_30min.flux_err = clean_flux_err

            ######################### Find rotation period ################################
            normalized_flux = np.array(lc_30min.flux) / np.median(
                lc_30min.flux)

            # From Lomb-Scargle
            freq = np.arange(0.04, 4.1, 0.00001)
            power = LombScargle(lc_30min.time, normalized_flux).power(freq)
            ls_fig = plt.figure()
            plt.plot(freq, power, c='k', linewidth=1)
            plt.xlabel('Frequency')
            plt.ylabel('Power')
            plt.title(
                '{} LombScargle Periodogram for original lc'.format(target_ID))
            #ls_plot.show(block=True)
            #        ls_fig.savefig(save_path + '{} - Lomb-Scargle Periodogram for original lc.png'.format(target_ID))
            plt.close(ls_fig)
            i = np.argmax(power)
            freq_rot = freq[i]
            p_rot = 1 / freq_rot
            print('Rotation Period = {:.3f}d'.format(p_rot))

            # From BLS
            durations = np.linspace(0.05, 1, 22) * u.day
            model = BoxLeastSquares(lc_30min.time * u.day, normalized_flux)
            results = model.autopower(durations, frequency_factor=1.0)
            rot_index = np.argmax(results.power)
            rot_period = results.period[rot_index]
            print("Rotation Period from BLS of original = {}d".format(
                rot_period))

            ########################### batman stuff ######################################
            if injected_planet != False:
                params = batman.TransitParams(
                )  #object to store transit parameters
                params.t0 = -10.0  #time of inferior conjunction
                params.per = 8.0
                params.rp = 0.1
                table_data = Table.read("BANYAN_XI-III_members_with_TIC.csv",
                                        format='ascii.csv')
                i = list(table_data['main_id']).index(target_ID)
                m_star = table_data['Stellar Mass'][i] * m_Sun
                r_star = table_data['Stellar Radius'][i] * r_Sun * 1000
                params.a = (((G * m_star * (params.per * 86400.)**2) /
                             (4. * (np.pi**2)))**(1. / 3)) / r_star
                if np.isnan(params.a) == True:
                    params.a = 17.  #semi-major axis (in units of stellar radii)
                params.inc = 90.
                params.ecc = 0.
                params.w = 90.  #longitude of periastron (in degrees)
                params.limb_dark = "nonlinear"  #limb darkening model
                params.u = [0.5, 0.1, 0.1, -0.1
                            ]  #limb darkening coefficients [u1, u2, u3, u4]

                if injected_planet == 'user_defined':
                    # Build planet from user specified parameters
                    params.per = injected_per  #orbital period (days)
                    params.rp = injected_rp  #planet radius (in units of stellar radii)
                    params.a = (((G * m_star * (params.per * 86400.)**2) /
                                 (4. * (np.pi**2)))**(1. / 3)) / r_star
                    if np.isnan(params.a) == True:
                        params.a = 17  # Recalculates a if period has changed
                    params.inc = 90.  #orbital inclination (in degrees)
                    params.ecc = 0.  #eccentricity
                else:
                    raise NameError('Invalid inputfor injected planet')

                # Defines times at which to calculate lc and models batman lc
                t = np.linspace(-13.9165035, 13.9165035, len(lc_30min.time))
                index = int(len(lc_30min.time) // 2)
                mid_point = lc_30min.time[index]
                t = lc_30min.time - lc_30min.time[index]
                m = batman.TransitModel(params, t)
                t += lc_30min.time[index]
                batman_flux = m.light_curve(params)
                batman_model_fig = plt.figure()
                plt.scatter(lc_30min.time, batman_flux, s=2, c='k')
                plt.xlabel("Time - 2457000 (BTJD days)")
                plt.ylabel("Relative flux")
                plt.title("batman model transit for {}R ratio".format(
                    params.rp))
                #batman_model_fig.savefig(save_path + "batman model transit for {}d {}R planet.png".format(params.per,params.rp))
                #plt.close(batman_model_fig)
                plt.show()

            ################################# Combining ###################################
            if injected_planet != False:
                combined_flux = np.array(lc_30min.flux) / np.median(
                    lc_30min.flux) + batman_flux - 1

                injected_transit_fig = plt.figure()
                plt.scatter(lc_30min.time, combined_flux, s=2, c='k')
                plt.xlabel("Time - 2457000 (BTJD days)")
                plt.ylabel("Relative flux")
                plt.title(
                    "{} with injected transits for a {}R {}d planet to star ratio."
                    .format(target_ID, params.rp, params.per))
                ax = plt.gca()
                for n in range(int(-1 * 8 / params.per),
                               int(2 * 8 / params.per + 2)):
                    ax.axvline(params.t0 + n * params.per + mid_point,
                               ymin=0.1,
                               ymax=0.2,
                               lw=1,
                               c='r')
                ax.axvline(params.t0 + lc_30min.time[index],
                           ymin=0.1,
                           ymax=0.2,
                           lw=1,
                           c='r')
                ax.axvline(params.t0 + params.per + lc_30min.time[index],
                           ymin=0.1,
                           ymax=0.2,
                           lw=1,
                           c='r')
                ax.axvline(params.t0 + 2 * params.per + lc_30min.time[index],
                           ymin=0.1,
                           ymax=0.2,
                           lw=1,
                           c='r')
                #            injected_transit_fig.savefig(save_path + "{} - Injected transits fig - Period {} - {}R transit.png".format(target_ID, params.per, params.rp))
                #            plt.close(injected_transit_fig)
                plt.show()

        ############################## Removing peaks #################################
            if injected_planet == False:
                combined_flux = np.array(lc_30min.flux) / np.median(
                    lc_30min.flux)
#            combined_flux = lc_30min.flux
            if use_peak_cut == True:
                peaks, peak_info = find_peaks(combined_flux,
                                              prominence=0.001,
                                              width=15)
                troughs, trough_info = find_peaks(-combined_flux,
                                                  prominence=-0.001,
                                                  width=15)
                flux_peaks = combined_flux[peaks]
                flux_troughs = combined_flux[troughs]
                amplitude_peaks = ((flux_peaks[0] - 1) +
                                   (1 - flux_troughs[0])) / 2
                print("Absolute amplitude of main variability = {}".format(
                    amplitude_peaks))
                peak_location_fig = plt.figure()
                plt.scatter(lc_30min.time, combined_flux, s=2, c='k')
                plt.plot(lc_30min.time[peaks], combined_flux[peaks], "x")
                plt.plot(lc_30min.time[troughs],
                         combined_flux[troughs],
                         "x",
                         c='r')
                #peak_location_fig.savefig(save_path + "{} - Peak location fig.png".format(target_ID))
                peak_location_fig.show()
                #                plt.close(peak_location_fig)

                near_peak_or_trough = [False] * len(combined_flux)

                for i in peaks:
                    for j in range(len(lc_30min.time)):
                        if abs(lc_30min.time[j] - lc_30min.time[i]) < 0.1:
                            near_peak_or_trough[j] = True

                for i in troughs:
                    for j in range(len(lc_30min.time)):
                        if abs(lc_30min.time[j] - lc_30min.time[i]) < 0.1:
                            near_peak_or_trough[j] = True

                near_peak_or_trough = np.array(near_peak_or_trough)

                t_cut = lc_30min.time[~near_peak_or_trough]
                flux_cut = combined_flux[~near_peak_or_trough]
                flux_err_cut = lc_30min.flux_err[~near_peak_or_trough]

                # Plot new cut version
                peak_cut_fig = plt.figure()
                plt.scatter(t_cut, flux_cut, c='k', s=2)
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel("Relative flux")
                plt.title(
                    '{} lc after removing peaks/troughs'.format(target_ID))
                ax = plt.gca()
                #peak_cut_fig.savefig(save_path + "{} - Peak cut fig.png".format(target_ID))
                peak_cut_fig.show()
#                plt.close(peak_cut_fig)
            else:
                t_cut = lc_30min.time
                flux_cut = combined_flux
                flux_err_cut = lc_30min.flux_err
                print('Flux cut skipped')

        ############################## Apply transit mask #########################

            if transit_mask == True:
                period = 8.138
                epoch = 1332.31
                duration = 0.15
                phase = np.mod(t_cut - epoch - period / 2, period) / period

                near_transit = [False] * len(flux_cut)

                for i in range(len(t_cut)):
                    if abs(phase[i] - 0.5) < duration / period:
                        near_transit[i] = True

                near_transit = np.array(near_transit)

                t_masked = t_cut[~near_transit]
                flux_masked = flux_cut[~near_transit]
                flux_err_masked = flux_err_cut[~near_transit]
                t_new = t_cut[near_transit]

                f = interpolate.interp1d(t_masked,
                                         flux_masked,
                                         kind='quadratic')

                flux_new = f(t_new)
                interpolated_fig = plt.figure()
                #                plt.scatter(t_masked, flux_masked, s = 2, c = 'k')
                plt.scatter(t_cut, flux_cut, s=2, c='k')
                plt.scatter(t_new, flux_new, s=2, c='r')
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel('Relative flux')
                #                interpolated_fig.savefig(save_path + "{} - Interpolated over transit mask fig.png".format(target_ID))

                t_transit_mask = np.concatenate((t_masked, t_new), axis=None)
                flux_transit_mask = np.concatenate((flux_masked, flux_new),
                                                   axis=None)

                sorted_order = np.argsort(t_transit_mask)
                t_transit_mask = t_transit_mask[sorted_order]
                flux_transit_mask = flux_transit_mask[sorted_order]

        ############################## LOWESS detrending ##############################

        # Full lc
            if detrending == 'lowess_full':
                full_lowess_flux = np.array([])
                if transit_mask == True:
                    lowess = sm.nonparametric.lowess(flux_transit_mask,
                                                     t_transit_mask,
                                                     frac=0.03)
                else:
                    lowess = sm.nonparametric.lowess(flux_cut,
                                                     t_cut,
                                                     frac=0.03)

                overplotted_lowess_full_fig = plt.figure()
                plt.scatter(t_cut, flux_cut, c='k', s=2)
                plt.plot(lowess[:, 0], lowess[:, 1])
                plt.title(
                    '{} lc with overplotted lowess full lc detrending'.format(
                        target_ID))
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel('Relative flux')
                #overplotted_lowess_full_fig.savefig(save_path + "{} lc with overplotted LOWESS full lc detrending.png".format(target_ID))
                plt.show()
                #                plt.close(overplotted_lowess_full_fig)

                residual_flux_lowess = flux_cut / lowess[:, 1]
                full_lowess_flux = np.concatenate(
                    (full_lowess_flux, lowess[:, 1]))

                lowess_full_residuals_fig = plt.figure()
                plt.scatter(t_cut, residual_flux_lowess, c='k', s=2)
                plt.title(
                    '{} lc after lowess full lc detrending'.format(target_ID))
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel('Relative flux')
                ax = plt.gca()
                #ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #lowess_full_residuals_fig.savefig(save_path + "{} lc after LOWESS full lc detrending.png".format(target_ID))
                plt.show()
                #plt.close(lowess_full_residuals_fig)

            # Partial lc
            if detrending == 'lowess_partial':
                time_diff = np.diff(t_cut)
                residual_flux_lowess = np.array([])
                time_from_lowess_detrend = np.array([])
                full_lowess_flux = np.array([])

                overplotted_detrending_fig = plt.figure()
                plt.scatter(t_cut, flux_cut, c='k', s=2)
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel("Normalized flux")
                plt.title(
                    '{} lc with overplotted detrending'.format(target_ID))

                low_bound = 0
                if pipeline == '2min':
                    n_bins = 450
                else:
                    n_bins = n_bins
                for i in range(len(t_cut) - 1):
                    if time_diff[i] > 0.1:
                        high_bound = i + 1

                        t_section = t_cut[low_bound:high_bound]
                        flux_section = flux_cut[low_bound:high_bound]
                        if len(t_section) >= n_bins:
                            if transit_mask == True:
                                lowess = sm.nonparametric.lowess(
                                    flux_transit_mask[low_bound:high_bound],
                                    t_transit_mask[low_bound:high_bound],
                                    frac=n_bins / len(t_section))
                            else:
                                lowess = sm.nonparametric.lowess(
                                    flux_section,
                                    t_section,
                                    frac=n_bins / len(t_section))
                            lowess_flux_section = lowess[:, 1]
                            plt.plot(t_section, lowess_flux_section, '-')

                            residuals_section = flux_section / lowess_flux_section
                            residual_flux_lowess = np.concatenate(
                                (residual_flux_lowess, residuals_section))
                            time_from_lowess_detrend = np.concatenate(
                                (time_from_lowess_detrend, t_section))
                            full_lowess_flux = np.concatenate(
                                (full_lowess_flux, lowess_flux_section))
                            low_bound = high_bound
                        else:
                            print('LOWESS skipped one gap at {}'.format(
                                t_section[-1]))

                # Carries out same process for final line (up to end of data)
                high_bound = len(t_cut)
                t_section = t_cut[low_bound:high_bound]
                flux_section = flux_cut[low_bound:high_bound]
                if transit_mask == True:
                    lowess = sm.nonparametric.lowess(
                        flux_transit_mask[low_bound:high_bound],
                        t_transit_mask[low_bound:high_bound],
                        frac=n_bins / len(t_section))
                else:
                    lowess = sm.nonparametric.lowess(flux_section,
                                                     t_section,
                                                     frac=n_bins /
                                                     len(t_section))
                lowess_flux_section = lowess[:, 1]
                plt.plot(t_section, lowess_flux_section, '-')
                #                if injected_planet != False:
                #                    overplotted_detrending_fig.savefig(save_path + "{} - Overplotted lowess detrending - partial lc - {}R {}d injected planet.png".format(target_ID, params.rp, params.per))
                #                else:
                #                    overplotted_detrending_fig.savefig(save_path + "{} - Overplotted lowess detrending - partial lc".format(target_ID))
                overplotted_detrending_fig.show()
                #                plt.close(overplotted_detrending_fig)

                residuals_section = flux_section / lowess_flux_section
                residual_flux_lowess = np.concatenate(
                    (residual_flux_lowess, residuals_section))
                time_from_lowess_detrend = np.concatenate(
                    (time_from_lowess_detrend, t_section))
                full_lowess_flux = np.concatenate(
                    (full_lowess_flux, lowess_flux_section))

                residuals_after_lowess_fig = plt.figure()
                plt.scatter(time_from_lowess_detrend,
                            residual_flux_lowess,
                            c='k',
                            s=2)
                plt.title('{} lc after LOWESS partial lc detrending'.format(
                    target_ID))
                plt.xlabel('Time - 2457000 [BTJD days]')
                plt.ylabel('Relative flux')
                #ax = plt.gca()
                #ax.axvline(params.t0+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0+params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
                #                if injected_planet != False:
                #                    residuals_after_lowess_fig.savefig(save_path + "{} lc after LOWESS partial lc detrending - {}R {}d injected planet.png".format(target_ID, params.rp, params.per))
                #                else:
                #                    residuals_after_lowess_fig.savefig(save_path + "{} lc after LOWESS partial lc detrending".format(target_ID))
                residuals_after_lowess_fig.show()
#                plt.close(residuals_after_lowess_fig)

#    ###################### Periodogram Construction ##################

# Create periodogram
            durations = np.linspace(0.05, 1, 22) * u.day
            if detrending == 'lowess_full' or detrending == 'lowess_partial':
                BLS_flux = residual_flux_lowess
            else:
                BLS_flux = combined_flux
            model = BoxLeastSquares(t_cut * u.day, BLS_flux)
            results = model.autopower(durations,
                                      minimum_n_transit=3,
                                      frequency_factor=1.0)

            # Find the period and epoch of the peak
            index = np.argmax(results.power)
            period = results.period[index]
            #print(results.period)
            t0 = results.transit_time[index]
            duration = results.duration[index]
            transit_info = model.compute_stats(period, duration, t0)
            print(transit_info)

            epoch = transit_info['transit_times'][0]

            periodogram_fig, ax = plt.subplots(1, 1)

            # Highlight the harmonics of the peak period
            ax.axvline(period.value, alpha=0.4, lw=3)
            for n in range(2, 10):
                ax.axvline(n * period.value,
                           alpha=0.4,
                           lw=1,
                           linestyle="dashed")
                ax.axvline(period.value / n,
                           alpha=0.4,
                           lw=1,
                           linestyle="dashed")

            # Plot and save the periodogram
            ax.plot(results.period, results.power, "k", lw=0.5)
            ax.set_xlim(results.period.min().value, results.period.max().value)
            ax.set_xlabel("period [days]")
            ax.set_ylabel("log likelihood")
            #            ax.set_title('{} - BLS Periodogram after {} detrending - {}R {}d injected planet'.format(target_ID, detrending, params.rp, params.per))
            ax.set_title('{} - BLS Periodogram after {} detrending'.format(
                target_ID, detrending))
            #            periodogram_fig.savefig(save_path + '{} - BLS Periodogram after lowess partial detrending - {}R {}d injected planet.png'.format(target_ID, params.rp, params.per))
            #            periodogram_fig.savefig(save_path + '{} - BLS Periodogram after lowess partial detrending.png'.format(target_ID))
            #            plt.close(periodogram_fig)
            periodogram_fig.show()

            ################################## Phase folding ##########################
            # Find indices of 2nd and 3rd peaks of periodogram
            all_peaks = scipy.signal.find_peaks(results.power,
                                                width=5,
                                                distance=10)[0]
            all_peak_powers = results.power[all_peaks]
            sorted_power_indices = np.argsort(all_peak_powers)
            sorted_peak_powers = all_peak_powers[sorted_power_indices]
            #        sorted_peak_periods = results.period[sorted_power_indices]

            # Find info for 2nd largest peak in periodogram
            index_peak_2 = np.where(results.power == sorted_peak_powers[-2])[0]
            period_2 = results.period[index_peak_2[0]]
            t0_2 = results.transit_time[index_peak_2[0]]

            # Find info for 3rd largest peak in periodogram
            index_peak_3 = np.where(results.power == sorted_peak_powers[-3])[0]
            period_3 = results.period[index_peak_3[0]]
            t0_3 = results.transit_time[index_peak_3[0]]

            phase_fold_plot(
                t_cut, BLS_flux, period.value, t0.value, target_ID, save_path,
                '{} {} residuals folded by Periodogram Max ({:.3f} days)'.
                format(target_ID, detrending, period.value))
            period_to_test = p_rot
            t0_to_test = 1332
            period_to_test2 = period_2.value
            t0_to_test2 = t0_2.value
            period_to_test3 = period_3.value
            t0_to_test3 = t0_3.value
            phase_fold_plot(
                t_cut, BLS_flux, p_rot, t0_to_test, target_ID, save_path,
                '{} folded by rotation period ({} days)'.format(
                    target_ID, period_to_test))
            phase_fold_plot(
                t_cut, BLS_flux, period_to_test2, t0_to_test2, target_ID,
                save_path,
                '{} detrended lc folded by 2nd largest peak ({:0.4} days)'.
                format(target_ID, period_to_test2))
            phase_fold_plot(
                t_cut, BLS_flux, period_to_test3, t0_to_test3, target_ID,
                save_path,
                '{} detrended lc folded by 3rd largest peak ({:0.4} days)'.
                format(target_ID, period_to_test3))
            #variability_table.add_row([target_ID,p_rot,rot_period,amplitude_peaks])

            ############################# Eyeballing ##############################
            """
            Generate 2 x 2 eyeballing plot
            """
            eye_balling_fig, axs = plt.subplots(2,
                                                2,
                                                figsize=(16, 10),
                                                dpi=120)

            # Original DIA with injected transits setup
            axs[0, 0].scatter(lc_30min.time, combined_flux, s=1, c='k')
            axs[0, 0].set_ylabel('Normalized Flux')
            axs[0, 0].set_xlabel('Time')
            axs[0, 0].set_title('{} - {} light curve'.format(target_ID, 'DIA'))
            #for n in range(int(-1*8/params.per),int(2*8/params.per+2)):
            #    axs[0,0].axvline(params.t0+n*params.per+mid_point, ymin = 0.1, ymax = 0.2, lw=1, c = 'r')

            # Detrended figure setup
            axs[0, 1].scatter(t_cut,
                              BLS_flux,
                              c='k',
                              s=1,
                              label='{} residuals after {} detrending'.format(
                                  target_ID, detrending))
            #            axs[0,1].set_title('{} residuals after {} detrending - Sector {}'.format(target_ID, detrending, sector))
            axs[0, 1].set_title(
                '{} residuals after {} detrending - Sectors 14-18'.format(
                    target_ID, detrending))
            axs[0, 1].set_ylabel('Normalized Flux')
            axs[0, 1].set_xlabel('Time - 2457000 [BTJD days]')
            #            binned_time, binned_flux = bin(t_cut, BLS_flux, binsize=15, method='mean')
            #            axs[0,1].scatter(binned_time, binned_flux, c='r', s=4)
            #for n in range(int(-1*8/params.per),int(2*8/params.per+2)):
            #    axs[0,1].axvline(params.t0+n*params.per+mid_point, ymin = 0.1, ymax = 0.2, lw=1, c = 'r')

            # Periodogram setup
            axs[1, 0].plot(results.period, results.power, "k", lw=0.5)
            axs[1, 0].set_xlim(results.period.min().value,
                               results.period.max().value)
            axs[1, 0].set_xlabel("period [days]")
            axs[1, 0].set_ylabel("log likelihood")
            axs[1, 0].set_title(
                '{} - BLS Periodogram of residuals'.format(target_ID))
            axs[1, 0].axvline(period.value, alpha=0.4, lw=3)
            for n in range(2, 10):
                axs[1, 0].axvline(n * period.value,
                                  alpha=0.4,
                                  lw=1,
                                  linestyle="dashed")
                axs[1, 0].axvline(period.value / n,
                                  alpha=0.4,
                                  lw=1,
                                  linestyle="dashed")

            # Folded or zoomed plot setup
            epoch = t0.value
            period = period.value
            phase = np.mod(t_cut - epoch - period / 2, period) / period
            axs[1, 1].scatter(phase, BLS_flux, c='k', s=1)
            axs[1, 1].set_title('{} Lightcurve folded by {:0.4} days'.format(
                target_ID, period))
            axs[1, 1].set_xlabel('Phase')
            axs[1, 1].set_ylabel('Normalized Flux')
            #            binned_phase, binned_lc = bin(phase, BLS_flux, binsize=15, method='mean')
            #            plt.scatter(binned_phase, binned_lc, c='r', s=4)

            eye_balling_fig.tight_layout()
            #            eye_balling_fig.savefig(save_path + '{} - Full eyeballing fig.pdf'.format(target_ID))
            #            plt.close(eye_balling_fig)
            plt.show()

            ########################### ADDING INFO ROWS ######################


#            sensitivity_table.add_row([target_ID,sector,pipeline,params.per,params.a,params.rp,period,np.max(results.power),period_2.value,period_3.value])

        except RuntimeError:
            print('No DiffImage lc exists for {}'.format(target_ID))
        except:
            print('Some other error for {}'.format(target_ID))
    return t_cut, BLS_flux, phase, epoch, period
Ejemplo n.º 25
0
    def _create_interact_ui(doc,
                            minp=minimum_period,
                            maxp=maximum_period,
                            resolution=resolution):
        """Create BLS interact user interface."""
        if minp is None:
            minp = 0.3
        if maxp is None:
            maxp = (lc.time[-1].value - lc.time[0].value) / 2
        # TODO: consider to accept Time as minp / maxp, and convert it to unitless days

        time_format = ""
        if lc.time.format == "bkjd":
            time_format = " - 2454833 days"
        if lc.time.format == "btjd":
            time_format = " - 2457000 days"

        # Some sliders
        duration_slider = Slider(
            start=0.01,
            end=0.5,
            value=0.05,
            step=0.01,
            title="Duration [Days]",
            width=400,
        )

        npoints_slider = Slider(
            start=500,
            end=10000,
            value=resolution,
            step=100,
            title="BLS Resolution",
            width=400,
        )

        # Set up the period values, BLS model and best period
        period_values = np.logspace(np.log10(minp), np.log10(maxp),
                                    npoints_slider.value)
        period_values = period_values[(period_values > duration_slider.value)
                                      & (period_values < maxp)]
        model = BoxLeastSquares(lc.time, lc.flux)
        result = model.power(period_values, duration_slider.value)
        loc = np.argmax(result.power)
        best_period = result.period[loc]
        best_t0 = result.transit_time[loc]

        # Some Buttons
        double_button = Button(label="Double Period",
                               button_type="danger",
                               width=100)
        half_button = Button(label="Half Period",
                             button_type="danger",
                             width=100)
        text_output = Paragraph(
            text="Period: {} days, T0: {}{}".format(
                _round_strip_unit(best_period, 7),
                _round_strip_unit(best_t0, 7),
                time_format,
            ),
            width=350,
            height=40,
        )

        # Set up BLS source
        bls_source = prepare_bls_datasource(result, loc)
        bls_source_units = dict(
            transit_time_format=result["transit_time"].format,
            transit_time_scale=result["transit_time"].scale,
            period=result["period"].unit,
        )
        bls_help_source = prepare_bls_help_source(bls_source,
                                                  npoints_slider.value)

        # Set up the model LC
        mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
        mf /= np.median(mf)
        mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) >
                 0.9)
        model_lc = _to_lc(lc.time[mask], mf[mask])

        model_lc_source = _to_ColumnDataSource(
            data=dict(time=model_lc.time, flux=model_lc.flux))

        # Set up the LC
        nb = int(np.ceil(len(lc.flux) / 5000))
        lc_source = prepare_lightcurve_datasource(lc[::nb])
        lc_help_source = prepare_lc_help_source(lc)

        # Set up folded LC
        nb = int(np.ceil(len(lc.flux) / 10000))
        f = lc.fold(best_period, best_t0)
        f_source = prepare_folded_datasource(f[::nb])
        f_help_source = prepare_f_help_source(f)

        f_model_lc = model_lc.fold(best_period, best_t0)
        f_model_lc = _to_lc(_as_1d(f.time.min()), [1]).append(f_model_lc)
        f_model_lc = f_model_lc.append(_to_lc(_as_1d(f.time.max()), [1]))

        f_model_lc_source = _to_ColumnDataSource(
            data=dict(phase=f_model_lc.time, flux=f_model_lc.flux))

        def _update_light_curve_plot(event):
            """If we zoom in on LC plot, update the binning."""
            mint, maxt = fig_lc.x_range.start, fig_lc.x_range.end
            inwindow = (lc.time.value > mint) & (lc.time.value < maxt)
            nb = int(np.ceil(inwindow.sum() / 5000))
            temp_lc = lc[inwindow]
            _update_source(lc_source, {
                "time": temp_lc.time[::nb],
                "flux": temp_lc.flux[::nb]
            })

        def _update_folded_plot(event):
            loc = np.argmax(bls_source.data["power"])
            best_period = bls_source.data["period"][loc]
            best_t0 = bls_source.data["transit_time"][loc]
            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time < maxphase)
            nb = int(np.ceil(inwindow.sum() / 10000))
            _update_source(
                f_source,
                {
                    "phase": f[inwindow].time[::nb],
                    "flux": f[inwindow].flux[::nb]
                },
            )

        # Function to update the widget
        def _update_params(all=False, best_period=None, best_t0=None):
            if all:
                # If we're updating everything, recalculate the BLS model
                minp, maxp = fig_bls.x_range.start, fig_bls.x_range.end
                period_values = np.logspace(np.log10(minp), np.log10(maxp),
                                            npoints_slider.value)
                ok = (period_values > duration_slider.value) & (period_values <
                                                                maxp)
                if ok.sum() == 0:
                    return
                period_values = period_values[ok]
                result = model.power(period_values, duration_slider.value)
                ok = (_isfinite(result["power"])
                      & _isfinite(result["duration"])
                      & _isfinite(result["transit_time"])
                      & _isfinite(result["period"]))
                ok_result = dict(
                    period=result["period"]
                    [ok],  # useful for accessing values with units needed later
                    power=result["power"][ok],
                    duration=result["duration"][ok],
                    transit_time=result["transit_time"][ok],
                )
                _update_source(bls_source, ok_result)
                loc = np.nanargmax(ok_result["power"])
                best_period = ok_result["period"][loc]
                best_t0 = ok_result["transit_time"][loc]

                minpow, maxpow = (
                    bls_source.data["power"].min() * 0.95,
                    bls_source.data["power"].max() * 1.05,
                )
                fig_bls.y_range.start = minpow
                fig_bls.y_range.end = maxpow

            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time < maxphase)
            nb = int(np.ceil(inwindow.sum() / 10000))
            _update_source(
                f_source,
                {
                    "phase": f[inwindow].time[::nb],
                    "flux": f[inwindow].flux[::nb]
                },
            )

            mf = model.model(lc.time, best_period, duration_slider.value,
                             best_t0)
            mf /= np.median(mf)
            mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2))
                     > 0.9)
            model_lc = _to_lc(lc.time[mask], mf[mask])

            _update_source(model_lc_source, {
                "time": model_lc.time,
                "flux": model_lc.flux
            })

            f_model_lc = model_lc.fold(best_period, best_t0)
            f_model_lc = _to_lc(_as_1d(f.time.min()), [1]).append(f_model_lc)
            f_model_lc = f_model_lc.append(_to_lc(_as_1d(f.time.max()), [1]))

            _update_source(f_model_lc_source, {
                "phase": f_model_lc.time,
                "flux": f_model_lc.flux
            })

            vertical_line.update(location=best_period.value)
            fig_folded.title.text = "Period: {} days \t T0: {}{}".format(
                _round_strip_unit(best_period, 7),
                _round_strip_unit(best_t0, 7),
                time_format,
            )
            text_output.text = "Period: {} days, \t T0: {}{}".format(
                _round_strip_unit(best_period, 7),
                _round_strip_unit(best_t0, 7),
                time_format,
            )

        # Callbacks
        def _update_upon_period_selection(attr, old, new):
            """When we select a period we should just update a few things, but we should not recalculate model"""
            if len(new) > 0:
                new = new[0]
                best_period = (bls_source.data["period"][new] *
                               bls_source_units["period"])
                best_t0 = Time(
                    bls_source.data["transit_time"][new],
                    format=bls_source_units["transit_time_format"],
                    scale=bls_source_units["transit_time_scale"],
                )
                _update_params(best_period=best_period, best_t0=best_t0)

        def _update_model_slider(attr, old, new):
            """If the duration slider is updated, then update the whole model set."""
            _update_params(all=True)

        def _update_model_slider_EVENT(event):
            """If we update the duration slider, we should update the whole model set.
            This is the same as the _update_model_slider but it has a different call signature...
            """
            _update_params(all=True)

        def _double_period_event():
            fig_bls.x_range.start *= 2
            fig_bls.x_range.end *= 2
            _update_params(all=True)

        def _half_period_event():
            fig_bls.x_range.start /= 2
            fig_bls.x_range.end /= 2
            _update_params(all=True)

        # Help Hover Call Backs
        def _update_folded_plot_help_reset(event):
            f_help_source.data["phase"] = [_at_ratio(f.time, 0.95)]
            f_help_source.data["flux"] = [_at_ratio(f.flux, 0.95)]

        def _update_folded_plot_help(event):
            f_help_source.data["phase"] = [_at_ratio(fig_folded.x_range, 0.95)]
            f_help_source.data["flux"] = [_at_ratio(fig_folded.y_range, 0.95)]

        def _update_lc_plot_help_reset(event):
            lc_help_source.data["time"] = [_at_ratio(lc.time, 0.98)]
            lc_help_source.data["flux"] = [_at_ratio(lc.flux, 0.95)]

        def _update_lc_plot_help(event):
            lc_help_source.data["time"] = [_at_ratio(fig_lc.x_range, 0.98)]
            lc_help_source.data["flux"] = [_at_ratio(fig_lc.y_range, 0.95)]

        def _update_bls_plot_help_event(event):
            # cannot use _at_ratio helper for period, because period is log scaled.
            bls_help_source.data["period"] = [
                bls_source.data["period"][int(npoints_slider.value * 0.95)]
            ]
            bls_help_source.data["power"] = [
                _at_ratio(bls_source.data["power"], 0.98)
            ]

        def _update_bls_plot_help(attr, old, new):
            bls_help_source.data["period"] = [
                bls_source.data["period"][int(npoints_slider.value * 0.95)]
            ]
            bls_help_source.data["power"] = [
                _at_ratio(bls_source.data["power"], 0.98)
            ]

        # Create all the figures.
        fig_folded = make_folded_figure_elements(f, f_model_lc, f_source,
                                                 f_model_lc_source,
                                                 f_help_source)
        fig_folded.title.text = "Period: {} days \t T0: {}{}".format(
            _round_strip_unit(best_period, 7),
            _round_strip_unit(best_t0, 5),
            time_format,
        )
        fig_bls, vertical_line = make_bls_figure_elements(
            result, bls_source, bls_help_source)
        fig_lc = make_lightcurve_figure_elements(lc, model_lc, lc_source,
                                                 model_lc_source,
                                                 lc_help_source)

        # Map changes

        # If we click a new period, update
        bls_source.selected.on_change("indices", _update_upon_period_selection)

        # If we change the duration, update everything, including help button for BLS
        duration_slider.on_change("value", _update_model_slider)
        duration_slider.on_change("value", _update_bls_plot_help)

        # If we increase resolution, update everything
        npoints_slider.on_change("value", _update_model_slider)

        # Make sure the vertical line always goes to the best period.
        vertical_line.update(location=best_period.value)

        # If we pan in the BLS panel, update everything
        fig_bls.on_event(PanEnd, _update_model_slider_EVENT)
        fig_bls.on_event(Reset, _update_model_slider_EVENT)

        # If we pan in the LC panel, rebin the points
        fig_lc.on_event(PanEnd, _update_light_curve_plot)
        fig_lc.on_event(Reset, _update_light_curve_plot)

        # If we pan in the Folded panel, rebin the points
        fig_folded.on_event(PanEnd, _update_folded_plot)
        fig_folded.on_event(Reset, _update_folded_plot)

        # Deal with help button
        fig_bls.on_event(PanEnd, _update_bls_plot_help_event)
        fig_bls.on_event(Reset, _update_bls_plot_help_event)
        fig_folded.on_event(PanEnd, _update_folded_plot_help)
        fig_folded.on_event(Reset, _update_folded_plot_help_reset)
        fig_lc.on_event(PanEnd, _update_lc_plot_help)
        fig_lc.on_event(Reset, _update_lc_plot_help_reset)

        # Buttons
        double_button.on_click(_double_period_event)
        half_button.on_click(_half_period_event)

        # Layout the widget
        doc.add_root(
            layout([
                [fig_bls, fig_folded],
                fig_lc,
                [
                    Spacer(width=70),
                    duration_slider,
                    Spacer(width=50),
                    npoints_slider,
                ],
                [
                    Spacer(width=70),
                    double_button,
                    Spacer(width=70),
                    half_button,
                    Spacer(width=300),
                    text_output,
                ],
            ]))
Ejemplo n.º 26
0
def find_and_mask_transits(time,
                           flux,
                           flux_err,
                           periods,
                           durations,
                           nplanets=1,
                           plot=False):
    """
    Iteratively find and mask transits in the flattened light curve.

    Args:
        time (array): The time array.
        flux (array): The flux array. You'll get the best results
            if this is flattened.
        flux_err (array): The array of flux uncertainties.
        periods (array): The array of periods to search over for BLS.
            For example, periods = np.linspace(0.5, 20, 10)
        durations (array): The array of durations to search over for BLS.
            For example, durations = np.linspace(0.05, 0.2, 10)
        nplanets (Optional[int]): The number of planets you'd like to search for.
            This function will interatively find and remove nplanets. Default is 1.

    Returns:
        transit_masks (list): a list of masks that correspond to the in
            transit points of each light curve. To mask out transits do
            time[~transit_masks[index]], etc.
    """

    cum_transit = np.ones(len(time), dtype=bool)
    _time, _flux, _flux_err = time * 1, flux * 1, flux_err * 1

    t0s, durs, porbs = [np.zeros(nplanets) for i in range(3)]
    transit_masks = []
    for i in range(nplanets):
        bls = BoxLeastSquares(t=_time, y=_flux, dy=_flux_err)
        bls.power(periods, durations)

        periods = bls.autoperiod(durations,
                                 minimum_n_transit=3,
                                 frequency_factor=5.0)
        results = bls.autopower(durations, frequency_factor=5.0)

        # Find the period of the peak
        period = results.period[np.argmax(results.power)]

        # Extract the parameters of the best-fit model
        index = np.argmax(results.power)
        porbs[i] = results.period[index]
        t0s[i] = results.transit_time[index]
        durs[i] = results.duration[index]

        if plot:
            # Plot the periodogram
            fig, ax = plt.subplots(1, 1, figsize=(10, 5))
            ax.plot(results.period, results.power, "k", lw=0.5)
            ax.set_xlim(results.period.min(), results.period.max())
            ax.set_xlabel("period [days]")
            ax.set_ylabel("log likelihood")

            # Highlight the harmonics of the peak period
            ax.axvline(period, alpha=0.4, lw=4)
            for n in range(2, 10):
                ax.axvline(n * period, alpha=0.4, lw=1, linestyle="dashed")
                ax.axvline(period / n, alpha=0.4, lw=1, linestyle="dashed")
            # plt.show()

            # plt.plot(_time, _flux, ".")
            # plt.xlim(1355, 1360)

        in_transit = bls.transit_mask(_time, porbs[i], durs[i], t0s[i])
        transit_masks.append(in_transit)
        _time, _flux, _flux_err = _time[~in_transit], _flux[~in_transit], \
            _flux_err[~in_transit]

    return transit_masks, t0s, durs, porbs
Ejemplo n.º 27
0
def run_BLS(fl):
    t, f, e = np.genfromtxt(fl, usecols=(0,1,2), unpack=True)
    mask    = cleaner(t,f)
    
    t = t[~mask]
    f = f[~mask]
    e = e[~mask]

    lc   = TessLightCurve(time=t, flux=f, flux_err=e).flatten(window_length=51, polyorder=2, niters=5)

    #Test Fill
    '''
    diffs = np.diff(lc.time)
    stdd  = np.nanstd(diffs)
    medd  = np.nanmedian(diffs)

    maskgaps = diffs > 0.2#np.abs(diffs-medd) > stdd
    maskgaps = np.concatenate((maskgaps,[False]))
    '''

    '''
    for mg in np.where(maskgaps)[0]:
        addtime = np.arange(lc.time[mg]+0.05, lc.time[mg+1], 0.05)
        addflux = np.random.normal(1, 8e-4, len(addtime))

        lc.time = np.concatenate((lc.time, addtime))
        lc.flux = np.concatenate((lc.flux, addflux))

    addorder = np.argsort(lc.time)
    lc.time = lc.time[addorder]
    lc.flux = lc.flux[addorder]
    '''

    #fmed = np.nanmedian(lc.flux)
    #fstd = np.nanstd(lc.flux)
    #stdm = lc.flux < 0.97#np.abs(lc.flux-fmed) > 3*fstd

    periods   = np.exp(np.linspace(np.log(args.min_period), np.log(args.max_period), 5000))
    durations = np.linspace(0.05, 0.15, 20)# * u.day
    model     = BLS(lc.time,lc.flux) if not args.TLS else transitleastsquares(lc.time.value, lc.flux, lc.flux_err)

    #result    = model.power(periods, durations, oversample=20)#, objective='snr')
    result    = model.power(period_min=args.min_period, oversampling_factor=2, n_transits_min=1, use_threads=1, show_progress_bar=False)
    #try:
    #result    = model.autopower(durations, frequency_factor=2.0, maximum_period=args.max_period)
    #except:
    #    print(fl)
    idx       = np.argmax(result.power)


    period = result.period[idx]
    t0     = result.transit_time[idx]
    dur    = result.duration[idx]
    depth  = result.depth[idx]
    snr    = result.depth_snr[idx]
    '''
    period = result.period
    t0     = result.T0
    dur    = result.duration
    depth  = 1 - result.depth
    snr    = result.snr
    '''


    try:
        stats  = model.compute_stats(period, dur, t0)
        depth_even = stats['depth_even'][0]
        depth_odd  = stats['depth_odd'][0]
        depth_half = stats['depth_half'][0]
        t0, t1     = stats['transit_times'][:2]
        ntra       = len(stats['transit_times'])
    except:
        depth_even = 0
        depth_odd  = 0
        depth_half = 0
        t1         = 0
        ntra       = 0

    if args.target is not None:
        return fl, period, t0, dur, depth, snr, depth_even, depth_odd, depth_half, t1, ntra, result.period, result.power, lc.time, lc.flux, diffs
    else:
        return fl, period, t0, dur, depth, snr, depth_even, depth_odd, depth_half, t1, ntra