Example #1
0
    def set_power_period(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.dflux.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.dflux.values).power(self.frequency)

        elif self.method == 'BLS_astropy':
            model = BoxLeastSquares(self.df.t.values, self.df.m.values, dy=self.df.dflux.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()
        # setting_period
        period = (1. / self.frequency[np.argmax(self.power)])
        print("p f p-f", period, np.fix(period), period-np.fix(period))
        if period - np.fix(period) < 0.009:
            self.period = (1. / self.frequency[(np.asarray(self.power).argsort()[-2])])
        else:
            self.period = period
Example #2
0
def process_lightcurve(lc, lc_duration):
    t = lc.times * u.day
    y_filt = lc.fluxes

    # 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=0.25 * u.day,
                              maximum_period=lc_duration / 2 * u.day,
                              minimum_n_transit=2,
                              frequency_factor=1.0)

    # Clean up results: Astropy Quantity objects are not serialisable
    results = dict(results)

    for keyword in results:
        if isinstance(results[keyword], u.Quantity):
            value_quantity = results[keyword]
            value_numeric = value_quantity.value
            value_unit = str(value_quantity.unit)

            if isinstance(value_numeric, np.ndarray):
                value_numeric = list(value_numeric)

            results[keyword] = [value_numeric, value_unit]

        elif isinstance(results[keyword], np.ndarray):
            value_numeric = list(results[keyword])
            results[keyword] = value_numeric

    # Return results
    return results
Example #3
0
def bls(time, nflux):
    """Applies astropy Box Least-Squares to light curve to fit period

    Parameters
    ----------
    time: np.array
        Time array
    nflux: np.array
        Flux array


    Returns
    -------
    per_guess: float
        Period fit from BLS
    """

    from astropy.timeseries import BoxLeastSquares
    import astropy.units as u

    mod = BoxLeastSquares(time * u.day, nflux, dy=0.01)
    periodogram = mod.autopower(0.2, objective="snr")
    per_guess = np.asarray(periodogram.period)[int(
        np.median(np.argmax(periodogram.power)))]

    return per_guess
Example #4
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
Example #5
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()
Example #6
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
Example #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
Example #8
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)
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
Example #10
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
        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
            params.rp = 0.1
            params.a = 17.
Example #12
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
Example #13
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='/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
Example #15
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
    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