예제 #1
0
def build_ktransit_model(ticid, lc, rprs=0.02, vary_transit=True):
    from ktransit import FitTransit
    fitT = FitTransit()

    model = BoxLeastSquares(lc.time, lc.flux)
    results = model.autopower(0.16, minimum_period=2., maximum_period=21.)
    period = results.period[np.argmax(results.power)]
    t0 = results.transit_time[np.argmax(results.power)]
    if rprs is None:
        depth = results.depth[np.argmax(results.power)]
        rprs = depth ** 2

    fitT.add_guess_star(rho=0.022, zpt=0, ld1=0.6505,ld2=0.1041) #come up with better way to estimate this using AS
    fitT.add_guess_planet(T0=t0, period=period, impact=0.5, rprs=rprs)

    ferr = np.ones_like(lc.time) * 0.00001
    fitT.add_data(time=lc.time,flux=lc.flux,ferr=ferr)#*1e-3)

    vary_star = ['zpt']      # free stellar parameters
    if vary_transit:
        vary_planet = (['period', 'impact',       # free planetary parameters
            'T0', #'esinw', 'ecosw',
            'rprs']) #'impact',               # free planet parameters are the same for every planet you model
    else:
        vary_planet = (['rprs'])

    fitT.free_parameters(vary_star, vary_planet)
    fitT.do_fit()                   # run the fitting

    return fitT
예제 #2
0
    def pdf_summary(self, ticid, out_fname):
        """

        """
        self.ticid = ticid
        with PdfPages(out_fname) as pdf:

            ql_fig = self.plot(self.ticid, save_postcard=True)
            pdf.savefig(ql_fig)
            plt.close()
            lc = self.lc

            time, flux, flux_err = lc.time, lc.flux, lc.flux_err

            model = BoxLeastSquares(time, flux)
            results = model.autopower(0.16,
                                      minimum_period=2.,
                                      maximum_period=21.)
            period = results.period[np.argmax(results.power)]
            t0 = results.transit_time[np.argmax(results.power)]

            vt_fig = plot_transit_vetting(self.ticid, period, t0, lc=self.lc)
            pdf.savefig(vt_fig)
            plt.close()

            ica_fig = make_ica_plot(self.ticid)
            pdf.savefig(ica_fig)
            plt.close()

            star_fig = self.plot_starry_model(lc)
            pdf.savefig(star_fig)
            plt.close()
예제 #3
0
def make_transit_periodogram(t, y, dy=0.01):
    """
    Plots a periodogram to determine likely period of planet transit candidtaes 
    in a dataset, based on a box least squared method.
    """
    model = BoxLeastSquares(t * u.day, y, dy=0.01)
    periodogram = model.autopower(0.2, objective="snr")
    plt.figure()
    plt.plot(periodogram.period, periodogram.power, 'k')
    plt.xlabel('Period [days]')
    plt.ylabel('Power')
    max_power_i = np.argmax(periodogram.power)
    best_fit = periodogram.period[max_power_i]
    print('Best Fit Period: {} days'.format(best_fit))
    stats = model.compute_stats(periodogram.period[max_power_i],
                                periodogram.duration[max_power_i],
                                periodogram.transit_time[max_power_i])
    return stats, best_fit
def get_bls_features(x, t):
    features = []
    # print(x[0])
    for i in range(x.shape[0]):
        # adapted from http://docs.astropy.org/en/stable/stats/bls.html#peak-statistics
        bls = BoxLeastSquares(t, x[i])
        periodogram = bls.autopower(
            40, minimum_n_transit=5
        )  # arg is the granularity of considered durations
        max_power = np.argmax(periodogram.power)
        stats = bls.compute_stats(periodogram.period[max_power],
                                  periodogram.duration[max_power],
                                  periodogram.transit_time[max_power])
        # TODO: use dataframe?
        features.append([stats[s][0] / stats[s][1] for s in stat_names])
        # based on https://arxiv.org/pdf/astro-ph/0206099.pdf
        #         ratios.append(stats["depth"][0] / stats["depth"][1])  # depth over uncertainty
        if (i + 1) % 10 == 0:
            print(".", end="")
        if (i + 1) % 500 == 0:
            print()
    print()
    return np.array(features)
예제 #5
0
    def validate_transit(self, ticid=None, lc=None, rprs=0.02):
        """Take a closer look at potential transit signals."""
        from .plotting import create_starry_model

        if ticid is not None:
            lc = self.from_eleanor(ticid)[1]
            lc = self._clean_data(lc)
        elif lc is None:
            lc = self.lc

        model = BoxLeastSquares(lc.time, lc.flux)
        results = model.autopower(0.16)
        period = results.period[np.argmax(results.power)]
        t0 = results.transit_time[np.argmax(results.power)]
        if rprs is None:
            depth = results.depth[np.argmax(results.power)]
            rprs = depth**2

        # create the model
        model_flux = create_starry_model(
            lc.time, period=period, t0=t0, rprs=rprs) - 1
        model_lc = lk.LightCurve(time=lc.time, flux=model_flux)

        fig, ax = plt.subplots(3, 1, figsize=(12, 14))
        fig.patch.set_facecolor('white')
        '''
        Plot unfolded transit
        ---------------------
        '''
        lc.scatter(ax=ax[0], c='k', label='Corrected Flux')
        model_lc.plot(ax=ax[0], c='r', lw=2, label='Transit Model')
        ax[0].set_ylim([-.002, .002])
        ax[0].set_xlim([lc.time[0], lc.time[-1]])
        '''
        Plot folded transit
        -------------------
        '''
        lc.fold(period, t0).scatter(ax=ax[1],
                                    c='k',
                                    label=f'P={period:.3f}, t0={t0}')
        lc.fold(period, t0).bin(binsize=7).plot(ax=ax[1],
                                                c='b',
                                                label='binned',
                                                lw=2)
        model_lc.fold(period, t0).plot(ax=ax[1],
                                       c='r',
                                       lw=2,
                                       label="transit Model")
        ax[1].set_xlim([-0.5, .5])
        ax[1].set_ylim([-.002, .002])
        '''
        Zoom folded transit
        -------------------
        '''
        lc.fold(period, t0).scatter(ax=ax[2],
                                    c='k',
                                    label=f'folded at {period:.3f} days')
        lc.fold(period, t0).bin(binsize=7).plot(ax=ax[2],
                                                c='b',
                                                label='binned',
                                                lw=2)
        model_lc.fold(period, t0).plot(ax=ax[2],
                                       c='r',
                                       lw=2,
                                       label="transit Model")
        ax[2].set_xlim([-0.1, .1])
        ax[2].set_ylim([-.002, .002])

        ax[0].set_title(f'{ticid}', fontsize=14)

        plt.show()
예제 #6
0
f = []

for fn in files:
    ti, fi = np.genfromtxt(fn, usecols=(0,1), unpack=True)
    t.append(ti)
    f.append(fi / np.nanmedian(fi))

t = np.concatenate(t)
f = np.concatenate(f)

fig, ax = plt.subplots(figsize=[15,3])
ax.plot(t, f, '-k', lw=1, zorder=-2)
ax.scatter(t, f, c='gold', edgecolor='black', s=15, lw=.5, zorder=-1)

durations = np.linspace(0.05, 0.2, 50)# * u.day
model     = BLS(t,f)
result    = model.autopower(durations, frequency_factor=5.0, maximum_period=30.0)
idx       = np.argmax(result.power)

period = result.period[idx]
t0     = result.transit_time[idx]
dur    = result.duration[idx]
depth  = result.depth[idx]

ph = (t - t0 + 0.5*period) % period - 0.5*period

fig2, ax2 = plt.subplots(figsize=[8,2])
ax2.scatter(ph, f, c='gold', edgecolor='black', s=15, lw=.5)

plt.show()
예제 #7
0
    def build_model(x, y, yerr, period_prior, t0_prior, depth, minimum_period=2, maximum_period=30, r_star_prior=5.0, t_star_prior=5000, m_star_prior=None, start=None):
        """Build an exoplanet model for a dataset and set of planets

        Paramters
        ---------
        x : array-like
            The time series (in days); this should probably be centered
        y : array-like
            The relative fluxes (in parts per thousand)
        yerr : array-like
            The uncertainties on ``y``
        period_prior : list
            The literature values for periods of the planets (in days)
        t0_prior : list
            The literature values for phases of the planets in the same
            coordinates as `x`
        rprs_prior : list
            The literature values for the ratio of planet radius to star
            radius
        start : dict
            A dictionary of model parameters where the optimization
            should be initialized

        Returns:
            A PyMC3 model specifying the probabilistic model for the light curve

        """

        model = BoxLeastSquares(x, y)
        results = model.autopower(0.16, minimum_period=minimum_period, maximum_period=maximum_period)
        if period_prior is None:
            period_prior = results.period[np.argmax(results.power)]
        if t0_prior is None:
            t0_prior = results.transit_time[np.argmax(results.power)]
        if depth is None:
            depth = results.depth[np.argmax(results.power)]

        period_prior = np.atleast_1d(period_prior)
        t0_prior = np.atleast_1d(t0_prior)
        # rprs_prior = np.atleast_1d(rprs_prior)

        with pm.Model() as model:

            # Set model variables
            model.x = np.asarray(x, dtype=np.float64)
            model.y = np.asarray(y, dtype=np.float64)
            model.yerr = np.asarray(yerr + np.zeros_like(x), dtype=np.float64)

            '''Stellar Parameters'''
            # The baseline (out-of-transit) flux for the star in ppt
            mean = pm.Normal("mean", mu=0.0, sd=10.0)

            try:
                r_star_mu = target_list[target_list['ID'] == ticid]['rad'].values[0]
            except:
                r_star_mu = r_star_prior
            if m_star_prior is None:
                try:
                    m_star_mu = target_list[target_list['ID'] == ticid]['mass'].values[0]
                except:
                    m_star_mu = 1.2
                if np.isnan(m_star_mu):
                    m_star_mu = 1.2
            else:
                m_star_mu = m_star_prior
            r_star = pm.Normal("r_star", mu=r_star_mu, sd=1.)
            m_star = pm.Normal("m_star", mu=m_star_mu, sd=1.)
            t_star = pm.Normal("t_star", mu=t_star_prior, sd=200)
            rho_star_mu = ((m_star_mu*u.solMass).to(u.g) / ((4/3) * np.pi * ((r_star_mu*u.solRad).to(u.cm))**3)).value
            rho_star = pm.Normal("rho_star", mu=rho_star_mu, sd=.25)

            '''Orbital Parameters'''
            # The time of a reference transit for each planet
            t0 = pm.Normal("t0", mu=t0_prior, sd=2., shape=1)
            period = pm.Uniform("period", testval=period_prior,
                                lower=minimum_period,
                                upper=maximum_period,
                                shape=1)

            b = pm.Uniform("b", testval=0.5, shape=1)

            # Set up a Keplerian orbit for the planets
            model.orbit = xo.orbits.KeplerianOrbit(
                period=period, t0=t0, b=b, r_star=r_star, m_star=m_star)#rho_star=rho_star)

            # track additional orbital parameters
            a = pm.Deterministic("a", model.orbit.a)
            incl = pm.Deterministic("incl", model.orbit.incl)

            '''Planet Parameters'''
            # quadratic limb darkening paramters
            u_ld = xo.distributions.QuadLimbDark("u_ld")

            estimated_rpl = r_star*(depth)**(1/2)

            # logr = pm.Normal("logr", testval=np.log(estimated_rpl), sd=1.)
            r_pl = pm.Uniform("r_pl",
                              testval=estimated_rpl,
                              lower=0.,
                              upper=1.)

            # r_pl = pm.Deterministic("r_pl", tt.exp(logr))
            rprs = pm.Deterministic("rprs", r_pl / r_star)
            teff = pm.Deterministic('teff', t_star * tt.sqrt(0.5*(1/a)))

            # Compute the model light curve using starry
            model.light_curves = xo.StarryLightCurve(u_ld).get_light_curve(
                                    orbit=model.orbit, r=r_pl, t=model.x)

            model.light_curve = pm.math.sum(model.light_curves, axis=-1) + mean


            pm.Normal("obs",
                      mu=model.light_curve,
                      sd=model.yerr,
                      observed=model.y)

            # Fit for the maximum a posteriori parameters, I've found that I can get
            # a better solution by trying different combinations of parameters in turn
            if start is None:
                start = model.test_point
            map_soln = xo.optimize(start=start, vars=[period, t0])
            map_soln = xo.optimize(start=map_soln, vars=[r_pl, mean])
            map_soln = xo.optimize(start=map_soln, vars=[period, t0, mean])
            map_soln = xo.optimize(start=map_soln, vars=[r_pl, mean])
            map_soln = xo.optimize(start=map_soln)
            model.map_soln = map_soln

        return model
예제 #8
0
def find_and_mask_transits(time,
                           flux,
                           flux_err,
                           periods,
                           durations,
                           nplanets=1):
    """
    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)

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

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

        print("extract")
        # 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]

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

        print("mask")
        in_transit = bls.transit_mask(_time, porbs[i], 2 * 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
예제 #9
0
def superplot(lc, ticid, breakpoints, target_list, save_data=False, outdir=None):
    """

    """

    time, flux, flux_err = lc.time, lc.flux, lc.flux_err

    model = BoxLeastSquares(time, flux)
    results = model.autopower(0.16, minimum_period=2., maximum_period=21.)
    period = results.period[np.argmax(results.power)]
    t0 = results.transit_time[np.argmax(results.power)]
    depth = results.depth[np.argmax(results.power)]
    depth_snr = results.depth_snr[np.argmax(results.power)]

    '''
    Plot Filtered Light Curve
    -------------------------
    '''
    plt.subplot2grid((8,16),(1,0),colspan=4, rowspan=1)

    plt.plot(time, flux, 'k', label="filtered")
    for val in breakpoints:
        plt.axvline(val, c='b', linestyle='dashed')
    plt.legend()
    plt.ylabel('Normalized Flux')
    plt.xlabel('Time')

    osample=5.
    nyq=283.

    # calculate FFT
    freq, amp, nout, jmax, prob = lomb.fasper(time, flux, osample, 3.)
    freq = 1000. * freq / 86.4
    bin = freq[1] - freq[0]
    fts = 2. * amp * np.var(flux * 1e6) / (np.sum(amp) * bin)

    use = np.where(freq < nyq + 150)
    freq = freq[use]
    fts = fts[use]

    # calculate ACF
    acf = np.correlate(fts, fts, 'same')
    freq_acf = np.linspace(-freq[-1], freq[-1], len(freq))

    fitT = build_ktransit_model(ticid=ticid, lc=lc, vary_transit=False)
    dur = _individual_ktransit_dur(fitT.time, fitT.transitmodel)

    freq = freq
    fts1 = fts/np.max(fts)
    fts2 = scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 5)
    fts3 = scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 50)

    '''
    Plot Periodogram
    ----------------
    '''
    plt.subplot2grid((8,16),(0,4),colspan=4,rowspan=4)
    plt.loglog(freq, fts/np.max(fts))
    plt.loglog(freq, scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 5), color='C1', lw=2.5)
    plt.loglog(freq, scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 50), color='r', lw=2.5)
    plt.axvline(283,-1,1, ls='--', color='k')
    plt.xlabel("Frequency [uHz]")
    plt.ylabel("Power")
    plt.xlim(10, 400)
    plt.ylim(1e-4, 1e0)

    # annotate with transit info
    font = {'family':'monospace', 'size':10}
    plt.text(10**1.04, 10**-3.50, f'depth = {depth:.4f}        ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.62, f'depth_snr = {depth_snr:.4f}    ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.74, f'period = {period:.3f} days    ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.86, f't0 = {t0:.3f}            ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    try:
        # annotate with stellar params
        # won't work for TIC ID's not in the list
        if isinstance(ticid, str):
            ticid = int(re.search(r'\d+', str(ticid)).group())
        Gmag = target_list[target_list['ID'] == ticid]['GAIAmag'].values[0]
        Teff = target_list[target_list['ID'] == ticid]['Teff'].values[0]
        R = target_list[target_list['ID'] == ticid]['rad'].values[0]
        M = target_list[target_list['ID'] == ticid]['mass'].values[0]
        plt.text(10**1.7, 10**-3.50, rf"G mag = {Gmag:.3f} ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.62, rf"Teff = {int(Teff)} K  ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.74, rf"R = {R:.3f} $R_\odot$  ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.86, rf"M = {M:.3f} $M_\odot$    ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    except:
        pass

    '''# plot ACF inset
    ax = plt.gca()
    axins = inset_axes(ax, width=2.0, height=1.4)
    axins.plot(freq_acf, acf)
    axins.set_xlim(1,25)
    axins.set_xlabel("ACF [uHz]")'''

    '''
    Plot BLS
    --------
    '''
    plt.subplot2grid((8,16),(2,0),colspan=4, rowspan=1)

    plt.plot(results.period, results.power, "k", lw=0.5)
    plt.xlim(results.period.min(), results.period.max())
    plt.xlabel("period [days]")
    plt.ylabel("log likelihood")

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

    phase = (t0 % period) / period
    foldedtimes = (((time - phase * period) / period) % 1)
    foldedtimes[foldedtimes > 0.5] -= 1
    foldtimesort = np.argsort(foldedtimes)
    foldfluxes = flux[foldtimesort]
    plt.subplot2grid((8,16), (3,0),colspan=2)
    plt.scatter(foldedtimes, flux, s=2)
    plt.plot(np.sort(foldedtimes), scipy.ndimage.filters.median_filter(foldfluxes, 40), lw=2, color='r', label=f'P={period:.2f} days, dur={dur:.2f} hrs')
    plt.xlabel('Phase')
    plt.ylabel('Flux')
    plt.xlim(-0.5, 0.5)
    plt.ylim(-0.0025, 0.0025)
    plt.legend(loc=0)

    fig = plt.gcf()
    fig.patch.set_facecolor('white')
    fig.suptitle(f'{ticid}', fontsize=14)
    fig.set_size_inches(12, 10)

    if save_data:
        np.savetxt(outdir+'/timeseries/'+str(ticid)+'.dat.ts', np.transpose([time, flux]), fmt='%.8f', delimiter=' ')
        np.savetxt(outdir+'/fft/'+str(ticid)+'.dat.ts.fft', np.transpose([freq, fts]), fmt='%.8f', delimiter=' ')
        with open(os.path.join(outdir,"transit_stats.txt"), "a+") as file:
            file.write(f"{ticid} {depth} {depth_snr} {period} {t0} {dur}\n")

    """
    ---------------
    TRANSIT VETTING
    ---------------
    """
    tpf = get_cutout(ticid, cutout_size=11)
    ica_lcs = find_ica_components(tpf)

    fig = plt.subplot2grid((8,16),(0,8),colspan=4,rowspan=4)
    fig.patch.set_facecolor('white')

    tpf.plot(ax=fig, title='', show_colorbar=False)
    add_gaia_figure_elements(tpf, fig)

    fig = plt.subplot2grid((8,16),(2,8),colspan=4,rowspan=2)
    lc.fold(2*period, t0+period/2).scatter(ax=fig, c='k', label='Odd Transit')
    lc.fold(2*period, t0+period/2).bin(3).plot(ax=fig, c='C1', lw=2)
    plt.xlim(-.5, 0)
    rms = np.std(lc.flux)
    plt.ylim(-3*rms, rms)

    fig = plt.subplot2grid((8,16),(3,8),colspan=4,rowspan=2)
    lc.fold(2*period, t0+period/2).scatter(ax=fig, c='k', label='Even Transit')
    lc.fold(2*period, t0+period/2).bin(3).plot(ax=fig, c='C1', lw=2)
    plt.xlim(0, .5)
    plt.ylim(-3*rms, rms)

    fig = plt.subplot2grid((8,16),(0,12),colspan=4,rowspan=4)
    for i,ilc in enumerate(ica_lcs):
        scale = 1
        plt.plot(ilc + i*scale)
    plt.xlim(0, len(ica_lcs[0]))
    plt.ylim(-scale, len(ica_lcs)*scale)

    """
    STARRY MODEL
    ------------
    """
    from .utils import _fit

    x, y, yerr = lc.time, lc.flux, lc.flux_err
    model, static_lc = _fit(x, y, yerr, target_list=target_list)

    model_lc = lk.LightCurve(time=x, flux=static_lc)

    with model:
        period = model.map_soln['period'][0]
        t0 = model.map_soln['t0'][0]
        r_pl = model.map_soln['r_pl'] * 9.96
        a = model.map_soln['a'][0]
        b = model.map_soln['b'][0]

    try:
        r_star = target_list[target_list['ID'] == ticid]['rad'].values[0]
    except:
        r_star = 10.

    fig = plt.subplot2grid((8,16),(4,0),colspan=4,rowspan=2)
    '''
    Plot unfolded transit
    ---------------------
    '''
    lc.scatter(c='k', label='Corrected Flux')
    lc.bin(binsize=7).plot(c='b', lw=1.5, alpha=.75, label='binned')
    model_lc.plot(c='r', lw=2, label='Transit Model')
    plt.ylim([-.002, .002])
    plt.xlim([lc.time[0], lc.time[-1]])

    fig = plt.subplot2grid((8,16),(6,0),colspan=4,rowspan=2)
    '''
    Plot folded transit
    -------------------
    '''
    lc.fold(period, t0).scatter(c='k', label=rf'$P={period:.3f}, t0={t0:.3f}, '
                                                         'R_p={r_pl:.3f} R_J, b={b:.3f}')
    lc.fold(period, t0).bin(binsize=7).plot(c='b', alpha=.75, lw=2)
    model_lc.fold(period, t0).plot(c='r', lw=2)
    plt.xlim([-0.5, .5])
    plt.ylim([-.002, .002])
예제 #10
0
def make_ica_plot(tic, tpf=None):
    """
    """

    if tpf is None:
        tpf = lk.search_tesscut(f'TIC {tic}').download(cutout_size=11)
    raw_lc = tpf.to_lightcurve(aperture_mask='all')

    ##Perform ICA
    n_components = 20

    X = np.ascontiguousarray(np.nan_to_num(tpf.flux), np.float64)
    X_flat = X.reshape(len(tpf.flux), -1) #turns three dimensional into two dimensional

    f1 = np.reshape(X_flat, (len(X), -1))
    X_pix = f1 / np.nansum(X_flat, axis=-1)[:, None]

    ica = FastICA(n_components=n_components) #define n_components
    S_ = ica.fit_transform(X_pix)
    A_ = ica.mixing_ #combine x_flat to get x

    a = np.dot(S_.T, S_)
    a[np.diag_indices_from(a)] += 1e-5
    b = np.dot(S_.T, raw_lc.flux)

    w = np.linalg.solve(a, b)

    comp_lcs = []
    blss = []
    max_powers = []

    for i,s in enumerate(S_.T):
        component_lc = s * w[i]
        comp_lcs.append(component_lc)
        # plt.plot(component_lc + i*1e5)

        model = BoxLeastSquares(tpf.time, component_lc)
        results = model.autopower(0.16, minimum_period=.5, maximum_period=24.)
        # model = transitleastsquares(tpf.time, component_lc)
        # results = model.power()
        period, power = results.period, results.power
        blss.append([period, power])
        # print(results.depth_snr[np.argmax(power)])
        if (np.std(component_lc) > 1e4) or (np.abs(period[np.argmax(power)] - 14) < 2) or (results.depth[np.argmax(power)]/np.median(component_lc) < 0):
            power = [0]

        max_powers.append(np.max(power))

    # plt.ylim(-1e5, 10e5)

    best_pers = blss[np.argmax(max_powers)][0]
    best_powers = blss[np.argmax(max_powers)][1]

    period = best_pers[np.argmax(best_powers)]

    transit_lc = lk.LightCurve(time=tpf.time, flux=comp_lcs[np.argmax(max_powers)])

    fig, ax = plt.subplots(2, 3, figsize=(10, 7))
    fig.suptitle(f'TIC {tic}')

    for i,c in enumerate(comp_lcs):
        ax[0,0].plot(tpf.time, c + i*1e5)
    ax[0,0].set_ylim(-1e5, n_components*1e5)
    ax[0,0].set_xlim(tpf.time[0], tpf.time[-1])
    ax[0,0].set_xlabel('Time')
    ax[0,0].set_ylabel('Flux')
    ax[0,0].yaxis.set_major_formatter(mtick.FormatStrFormatter('%.e'))
    ax[0,0].set_title('ICA Components')

    transit_lc.plot(ax=ax[0,1])
    ax[0,1].set_xlim(tpf.time[0], tpf.time[-1])
    ax[0,1].yaxis.set_major_formatter(mtick.FormatStrFormatter('%.e'))
    ax[0,1].set_title('ICA comp with max BLS power')

    transit_lc.remove_outliers(9).fold(period).scatter(ax=ax[0,2], c='k', label=f'Period={period:.2f}')
    transit_lc.remove_outliers(9).fold(period).bin(7).plot(ax=ax[0,2], c='r', lw=2, C='C1', label='Binned')
    ax[0,2].set_ylim(-5*np.std(transit_lc.flux), 2*np.std(transit_lc.flux))
    ax[0,2].set_xlim(-.5,.5)
    ax[0,2].set_title('Folded ICA Transit Component')

    A_useful = A_.reshape(11,11,n_components).T #reshape from 2d to 3d

    weighted_comp = A_useful[np.argmax(max_powers)].T * w[np.argmax(max_powers)]

    ax[1,0].imshow(weighted_comp, origin='lower')
    ax[1,1].imshow(tpf.flux[200], origin='lower')
    im = ax[1,2].imshow(weighted_comp / tpf.flux[200], origin='lower')

    ax[1,0].set_title('Weighted Transit Component')
    ax[1,1].set_title('TPF')
    ax[1,2].set_title('Model / Flux')

    plt.colorbar(im)
    fig.tight_layout(rect=[0, 0.03, 1, 0.95])
    fig.patch.set_facecolor('white')
    fig.set_size_inches(10, 7)

    return fig
예제 #11
0
def plot_quicklook(lc, ticid, breakpoints, target_list, save_data=True, outdir=None):

    if outdir is None:
        outdir = os.path.join(self.PACKAGEDIR, 'outputs')

    time, flux, flux_err = lc.time, lc.flux, lc.flux_err

    model = BoxLeastSquares(time, flux)
    results = model.autopower(0.16, minimum_period=2., maximum_period=21.)
    period = results.period[np.argmax(results.power)]
    t0 = results.transit_time[np.argmax(results.power)]
    depth = results.depth[np.argmax(results.power)]
    depth_snr = results.depth_snr[np.argmax(results.power)]

    '''
    Plot Filtered Light Curve
    -------------------------
    '''
    plt.subplot2grid((4,4),(1,0),colspan=2)

    plt.plot(time, flux, 'k', label="filtered")
    for val in breakpoints:
        plt.axvline(val, c='b', linestyle='dashed')
    plt.legend()
    plt.ylabel('Normalized Flux')
    plt.xlabel('Time')

    osample=5.
    nyq=283.

    # calculate FFT
    freq, amp, nout, jmax, prob = lomb.fasper(time, flux, osample, 3.)
    freq = 1000. * freq / 86.4
    bin = freq[1] - freq[0]
    fts = 2. * amp * np.var(flux * 1e6) / (np.sum(amp) * bin)

    use = np.where(freq < nyq + 150)
    freq = freq[use]
    fts = fts[use]

    # calculate ACF
    acf = np.correlate(fts, fts, 'same')
    freq_acf = np.linspace(-freq[-1], freq[-1], len(freq))

    fitT = build_ktransit_model(ticid=ticid, lc=lc, vary_transit=False)
    dur = _individual_ktransit_dur(fitT.time, fitT.transitmodel)

    freq = freq
    fts1 = fts/np.max(fts)
    fts2 = scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 5)
    fts3 = scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 50)

    '''
    Plot Periodogram
    ----------------
    '''
    plt.subplot2grid((4,4),(0,2),colspan=2,rowspan=4)
    plt.loglog(freq, fts/np.max(fts))
    plt.loglog(freq, scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 5), color='C1', lw=2.5)
    plt.loglog(freq, scipy.ndimage.filters.gaussian_filter(fts/np.max(fts), 50), color='r', lw=2.5)
    plt.axvline(283,-1,1, ls='--', color='k')
    plt.xlabel("Frequency [uHz]")
    plt.ylabel("Power")
    plt.xlim(10, 400)
    plt.ylim(1e-4, 1e0)

    # annotate with transit info
    font = {'family':'monospace', 'size':10}
    plt.text(10**1.04, 10**-3.50, f'depth = {depth:.4f}        ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.62, f'depth_snr = {depth_snr:.4f}    ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.74, f'period = {period:.3f} days    ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    plt.text(10**1.04, 10**-3.86, f't0 = {t0:.3f}            ', fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    try:
        # annotate with stellar params
        # won't work for TIC ID's not in the list
        if isinstance(ticid, str):
            ticid = int(re.search(r'\d+', str(ticid)).group())
        Gmag = target_list[target_list['ID'] == ticid]['GAIAmag'].values[0]
        Teff = target_list[target_list['ID'] == ticid]['Teff'].values[0]
        R = target_list[target_list['ID'] == ticid]['rad'].values[0]
        M = target_list[target_list['ID'] == ticid]['mass'].values[0]
        plt.text(10**1.7, 10**-3.50, rf"G mag = {Gmag:.3f} ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.62, rf"Teff = {int(Teff)} K  ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.74, rf"R = {R:.3f} $R_\odot$  ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
        plt.text(10**1.7, 10**-3.86, rf"M = {M:.3f} $M_\odot$    ", fontdict=font).set_bbox(dict(facecolor='white', alpha=.9, edgecolor='none'))
    except:
        pass

    # plot ACF inset
    ax = plt.gca()
    axins = inset_axes(ax, width=2.0, height=1.4)
    axins.plot(freq_acf, acf)
    axins.set_xlim(1,25)
    axins.set_xlabel("ACF [uHz]")

    '''
    Plot BLS
    --------
    '''
    plt.subplot2grid((4,4),(2,0),colspan=2)

    plt.plot(results.period, results.power, "k", lw=0.5)
    plt.xlim(results.period.min(), results.period.max())
    plt.xlabel("period [days]")
    plt.ylabel("log likelihood")

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

    phase = (t0 % period) / period
    foldedtimes = (((time - phase * period) / period) % 1)
    foldedtimes[foldedtimes > 0.5] -= 1
    foldtimesort = np.argsort(foldedtimes)
    foldfluxes = flux[foldtimesort]
    plt.subplot2grid((4,4), (3,0),colspan=2)
    plt.scatter(foldedtimes, flux, s=2)
    plt.plot(np.sort(foldedtimes), scipy.ndimage.filters.median_filter(foldfluxes, 40), lw=2, color='r', label=f'P={period:.2f} days, dur={dur:.2f} hrs')
    plt.xlabel('Phase')
    plt.ylabel('Flux')
    plt.xlim(-0.5, 0.5)
    plt.ylim(-0.0025, 0.0025)
    plt.legend(loc=0)

    fig = plt.gcf()
    fig.patch.set_facecolor('white')
    fig.suptitle(f'{ticid}', fontsize=14)
    fig.set_size_inches(10, 7)

    if save_data:
        np.savetxt(outdir+'/timeseries/'+str(ticid)+'.dat.ts', np.transpose([time, flux]), fmt='%.8f', delimiter=' ')
        np.savetxt(outdir+'/fft/'+str(ticid)+'.dat.ts.fft', np.transpose([freq, fts]), fmt='%.8f', delimiter=' ')
        with open(os.path.join(outdir,"transit_stats.txt"), "a+") as file:
            file.write(f"{ticid} {depth} {depth_snr} {period} {t0} {dur}\n")

    return fig
예제 #12
0
plot = figure(plot_height=200,
              plot_width=1000,
              title='Curva de luz',
              x_range=[np.nanmin(t), np.nanmax(t)])

plot.xaxis.axis_label = 'Tiempo (dias)'
plot.yaxis.axis_label = 'Flujo'

plot.circle('t', 'f', source=src, size=1)
#plot.line('t', 'trn', source=ndata, line_width=1, color='lime')

#BLS
print('Calculando período...')
durations = np.linspace(0.05, 0.2, 60)
model = BLS(t, f)
result = model.autopower(durations, frequency_factor=2.0)
idx = np.argmax(result.power)
per = result.period[idx] if args.period is None else args.period

pgram = figure(width=1000,
               height=200,
               x_range=[0, 20],
               title='Periodograma (BLS)')
pgram.xaxis.axis_label = 'Periodo'
pgram.yaxis.axis_label = 'Potencia'
freqs = 1 / np.arange(1 / 30., 1 / 30. + 50000 * 1e-4, 1e-4)

#blsda = ColumnDataSource(data=dict(per=freqs, pow=blsre[0]))
#pgram.line('per', 'pow', source=blsda)
print('Done!')
'''