def make_periodogram(data, ticid, pipeline, outdir=None, period_min=0.1,
                     period_max=20, manual_peak=None, samples_per_peak=50,
                     nterms_0=6):

    if pipeline in ['spoc', 'kepler']:
        time = data[LCKEYDICT[pipeline]['time']]
        flux = data[LCKEYDICT[pipeline]['flux']]
        err = flux*1e-4
        qual = data[LCKEYDICT[pipeline]['quality']]
        sel = np.isfinite(time) & np.isfinite(flux) & np.isfinite(err) # (qual == 0)
        time, flux, err = time[sel], flux[sel], err[sel]
        med_flux = np.nanmedian(flux)
        flux /= med_flux
        err /= med_flux
    elif pipeline == 'cdips':
        time = data['time']
        flux = data['flux']
        err = data['err']
    else:
        raise NotImplementedError

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

    from astropy.timeseries import LombScargle
    from scipy.signal import find_peaks

    plt.close('all')

    fig, ax = plt.subplots()

    ls = LombScargle(time, flux, err, nterms=nterms_0)
    freq, power = ls.autopower(minimum_frequency=1/period_max,
                               maximum_frequency=1/period_min,
                               samples_per_peak=samples_per_peak)

    period = 1/freq
    ax.plot(period, power)

    ls_freq_0 = freq[np.argmax(power)]
    ls_period_0 = 1/ls_freq_0
    ax.axvline(ls_period_0, alpha=0.4, lw=1, color='C0')
    ax.axvline(2*ls_period_0, alpha=0.4, lw=1, color='C0')
    ax.axvline(0.5*ls_period_0, alpha=0.4, lw=1, color='C0')

    if manual_peak:
        ax.axvline(manual_peak, alpha=0.4, lw=1, color='C1')
        ax.axvline(2*manual_peak, alpha=0.4, lw=1, color='C1')
        ax.axvline(0.5*manual_peak, alpha=0.4, lw=1, color='C1')

    peaks, props = find_peaks(power, height=1e-1)
    print(period[peaks])

    tstr = f'LS period = {ls_period_0:.6f} d'
    ax.set_title(tstr)
    ax.set_yscale('log')
    ax.set_xscale('log')

    ax.set_xlabel('period [d]')
    ax.set_ylabel('power')

    if outdir is None:
        outdir = '../results/quicklooklc/TIC{}'.format(ticid)
    savpath = os.path.join(outdir, 'ls_periodogram.png')
    fig.savefig(savpath, dpi=300, bbox_inches='tight')
    print('made {}'.format(savpath))

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

    flux_fit_0 = ls.model(time, ls_freq_0)
    flux_r1 = flux - flux_fit_0

    nterms_1=6
    ls = LombScargle(time, flux_r1, err, nterms=nterms_1)
    freq, power = ls.autopower(minimum_frequency=1/period_max,
                               maximum_frequency=1/period_min)

    period = 1/freq

    ls_freq_1 = freq[np.argmax(power)]
    ls_period_1 = 1/ls_freq_1

    flux_fit_1 = ls.model(time, ls_freq_1)
    flux_r2 = flux_r1 - flux_fit_1

    ##########

    nterms_2=6
    ls = LombScargle(time, flux_r2, err, nterms=nterms_2)
    freq, power = ls.autopower(minimum_frequency=1/period_max,
                               maximum_frequency=1/period_min)

    period = 1/freq
    ls_freq_2 = freq[np.argmax(power)]
    ls_period_2 = 1/ls_freq_2

    flux_fit_2 = ls.model(time, ls_freq_2)
    flux_r3 = flux_r2 - flux_fit_2



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

    plt.close('all')
    fig, axs = plt.subplots(nrows=4, figsize=(14,10), sharex=True)

    axs[0].scatter(time, flux, c='k', s=1, zorder=1)
    axs[0].plot(time, flux_fit_0, zorder=2, lw=1)
    axs[0].set_title(f'model: {nterms_0} fourier terms at {ls_period_0:.6f} days',
                     fontsize='x-small')

    axs[1].scatter(time, flux_r1, c='k', s=1, zorder=1)
    axs[1].plot(time, flux_fit_1, zorder=2, lw=1)
    axs[1].set_title(f'model: {nterms_1} fourier terms at {ls_period_1:.6f} days',
                     fontsize='x-small')

    axs[2].scatter(time, flux_r2, c='k', s=1, zorder=1)
    axs[2].plot(time, flux_fit_2, zorder=2, lw=1)
    axs[2].set_title(f'model: {nterms_2} fourier terms at {ls_period_2:.6f} days',
                     fontsize='x-small')

    axs[3].scatter(time, flux_r3, c='k', s=1, zorder=1)
    axs[3].plot(time, flux_fit_2-flux_fit_2, zorder=2, lw=1)
    axs[3].set_title('', fontsize='x-small')

    axs[0].set_ylabel('raw')
    axs[1].set_ylabel('resid 1')
    axs[2].set_ylabel('resid 2')
    axs[3].set_ylabel('resid 3')
    axs[3].set_xlabel('btjd')

    fig.tight_layout()

    savpath = os.path.join(outdir, 'ls_models_resids.png')
    fig.savefig(savpath, dpi=300, bbox_inches='tight')
    print('made {}'.format(savpath))




    ##########################################
    show_tls = 0

    if show_tls:
        from transitleastsquares import transitleastsquares
        model = transitleastsquares(time, flux)
        results = model.power(period_min=period_min, period_max=period_max,
                              M_star_min=0.1, M_star_max=5, R_star=0.5, M_star=0.5)

        print(42*'-')
        print(
            't0: {}'.format(results.T0)+
            '\nperiod: {}'.format(results.period)+
            '\nperiod_unc: {}'.format(results.period_uncertainty)
        )
        print(42*'-')

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

        plt.close('all')
        fig = plt.figure()
        ax = plt.gca()
        ax.axvline(results.period, alpha=0.4, lw=3)
        plt.xlim(np.min(results.periods), np.max(results.periods))
        for n in range(2, 10):
            ax.axvline(n*results.period, alpha=0.4, lw=1, linestyle="dashed")
            ax.axvline(results.period / n, alpha=0.4, lw=1, linestyle="dashed")
        plt.ylabel(r'SDE')
        plt.xlabel('Period (days)')
        plt.plot(results.periods, results.power, color='black', lw=0.5)
        plt.xlim(0, max(results.periods))

        savpath = os.path.join(outdir, 'tls_periodogram.png')
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))

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

        plt.close('all')
        fig = plt.figure()
        plt.scatter(results.folded_phase, results.folded_y, color='gray', s=2,
                    alpha=0.8, zorder=4, linewidths=0)

        pd = phase_bin_magseries(results.folded_phase, results.folded_y,
                                 binsize=0.01)
        plt.scatter(pd['binnedphases'], pd['binnedmags'], color='black', s=8,
                    alpha=1, zorder=5, linewidths=0)

        plt.title(f'period {results.period:.8f}d')
        plt.xlabel('Phase')
        plt.ylabel('Relative flux')
        plt.xticks([0, 0.25, 0.5, 0.75, 1])
        plt.grid(which='major', axis='both', linestyle='--', zorder=-3,
                 alpha=0.5, color='gray')

        pct_80 = np.percentile(results.model_folded_model, 80)
        pct_20 = np.percentile(results.model_folded_model, 20)
        center = np.nanmedian(results.model_folded_model)
        delta_y = (10/6)*np.abs(pct_80 - pct_20)
        plt.ylim(( center-0.7*delta_y, center+0.7*delta_y ))

        savpath = os.path.join(outdir, 'phasefold.png')
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))
Beispiel #2
0
def detrend_lightcurve_wotan(data, window_length=0.25, iscdips=True):

    #NOTE: junky. doesnt work.
    # try two simple harmonic oscillators with periods separated by a factor of
    # two...

    if iscdips:
        sector_data = data[0]
        time = sector_data['TMID_BJD']
        flux = vp._given_mag_get_flux(sector_data['IRM1'])
    else:
        d = data[0]
        time = d['TIME']
        flux = d['PDCSAP_FLUX'] / np.nanmedian(d['PDCSAP_FLUX'])

    from wotan import flatten

    _, trend_lc2 = flatten(
        time,  # Array of time values
        flux,  # Array of flux values
        method='biweight',
        robust=True,  # Iteratively clip 2-sigma outliers until convergence
        window_length=
        window_length,  # The length of the filter window in units of ``time``
        break_tolerance=0.5,  # Split into segments at breaks longer than that
        return_trend=True,  # Return trend and flattened light curve
    )
    if window_length == 99:
        trend_lc2 = np.ones_like(flux) * np.nanmedian(flux)

    # flatten_lc2, trend_lc2 = flatten(
    #         time,                  # Array of time values
    #         flux,                  # Array of flux values
    #         method='gp',
    #         kernel='periodic',     # GP kernel choice
    #         kernel_period=0.498818,  # GP kernel period
    #         kernel_size=50,        # GP kernel length
    #         break_tolerance=0.5,   # Split into segments at breaks longer than
    #         return_trend=True,     # Return trend and flattened light curve
    # )

    # plot!
    plt.close('all')
    if iscdips:
        f, axs = plt.subplots(nrows=2, ncols=1, figsize=(16, 7))
    else:
        f, axs = plt.subplots(nrows=2, ncols=1, figsize=(32, 7))

    axs[0].scatter(time, flux, c='k', s=5, zorder=2)
    axs[0].plot(time, trend_lc2, c='orange', lw=1, zorder=3)

    dtr_flux = flux - trend_lc2
    sel = ~np.isnan(dtr_flux)
    axs[1].scatter(time[sel], dtr_flux[sel], c='k', s=5)

    axs[1].set_xlabel('time [bjdtdb]')
    axs[0].set_ylabel('IRM1 flux')
    axs[1].set_ylabel('residual')

    axs[0].set_title('biweight detrend, {}d'.format(window_length))

    if not iscdips:
        axs[1].set_ylim([-0.1, 0.05])
        if window_length == 99:
            axs[1].set_ylim([-0.1, 0.1])

    isspoc = '' if iscdips else '_spoc2min'
    savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d.png'.format(
        isspoc, window_length)
    f.savefig(savpath, dpi=300, bbox_inches='tight')
    print('made {}'.format(savpath))

    if not iscdips:

        from transitleastsquares import transitleastsquares
        model = transitleastsquares(
            time[sel], 1 + dtr_flux[sel] + np.nanmedian(dtr_flux[sel]))
        results = model.power(period_min=0.3,
                              period_max=0.6,
                              M_star_min=0.1,
                              M_star_max=5,
                              R_star=0.5,
                              M_star=0.5)

        print(42 * '-')
        print('t0: {}'.format(results.T0) +
              '\nperiod: {}'.format(results.period) +
              '\nperiod_unc: {}'.format(results.period_uncertainty))
        print(42 * '-')

        plt.close('all')
        fig = plt.figure()
        ax = plt.gca()
        ax.axvline(results.period, alpha=0.4, lw=3)
        plt.xlim(np.min(results.periods), np.max(results.periods))
        for n in range(2, 10):
            ax.axvline(n * results.period, alpha=0.4, lw=1, linestyle="dashed")
            ax.axvline(results.period / n, alpha=0.4, lw=1, linestyle="dashed")
        plt.ylabel(r'SDE')
        plt.xlabel('Period (days)')
        plt.plot(results.periods, results.power, color='black', lw=0.5)
        plt.xlim(0, max(results.periods))

        savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d_periodogram.png'.format(
            isspoc, window_length)
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))

        plt.close('all')
        fig = plt.figure()
        # plt.plot(results.model_folded_phase, results.model_folded_model,
        #          color='orange', zorder=3)
        plt.scatter(results.folded_phase,
                    results.folded_y,
                    color='gray',
                    s=2,
                    alpha=0.8,
                    zorder=4,
                    linewidths=0)

        pd = phase_bin_magseries(results.folded_phase,
                                 results.folded_y,
                                 binsize=0.01)

        plt.scatter(pd['binnedphases'],
                    pd['binnedmags'],
                    color='black',
                    s=8,
                    alpha=1,
                    zorder=5,
                    linewidths=0)

        #plt.xlim(0.35, 0.65)
        rstr = '(on residual)' if window_length <= 0.2 else '(on raw)'
        plt.title('{} period {:.8f}d'.format(rstr, results.period))
        plt.xlabel('Phase')
        plt.ylabel('Relative flux')
        plt.xticks([0, 0.25, 0.5, 0.75, 1])
        plt.grid(which='major',
                 axis='both',
                 linestyle='--',
                 zorder=-3,
                 alpha=0.5,
                 color='gray')

        pct_80 = np.percentile(results.model_folded_model, 80)
        pct_20 = np.percentile(results.model_folded_model, 20)
        center = np.nanmedian(results.model_folded_model)
        delta_y = (10 / 6) * np.abs(pct_80 - pct_20)
        plt.ylim((center - 0.7 * delta_y, center + 0.7 * delta_y))

        savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d_phasefold.png'.format(
            isspoc, window_length)
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))
Beispiel #3
0
def generate_verification_page(lcd, ls, freq, power, cutoutpaths, c_obj,
                               outvppath, outd, show_binned=True):
    """
    Make the verification page, which consists of:

    top row: entire light curve (with horiz bar showing rotation period)

    bottom row:
        lomb scargle periodogram  |  phased light curve  |  image w/ aperture

    ----------
    args:

        lcd (dict): has the light curve, aperture positions, some lomb
        scargle results.

        ls: LombScargle instance with everything passed.

        cutoutpaths (list): FFI cutout FITS paths.

        c_obj (SkyCoord): astropy sky coordinate of the target

        outvppath (str): path to save verification page to
    """
    cutout_wcs = lcd['cutout_wcss'][0]

    mpl.rcParams['xtick.direction'] = 'in'
    mpl.rcParams['ytick.direction'] = 'in'

    plt.close('all')

    fig = plt.figure(figsize=(12,12))

    #ax0 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
    #ax1 = plt.subplot2grid((3, 3), (1, 0), colspan=3)
    #ax2 = plt.subplot2grid((3, 3), (2, 0))
    #ax3 = plt.subplot2grid((3, 3), (2, 1))
    #ax4 = plt.subplot2grid((3, 3), (2, 2), projection=cutout_wcs)

    ax0 = plt.subplot2grid((3, 3), (1, 0), colspan=3)
    ax1 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
    ax2 = plt.subplot2grid((3, 3), (0, 0))
    ax3 = plt.subplot2grid((3, 3), (0, 1))
    ax4 = plt.subplot2grid((3, 3), (0, 2), projection=cutout_wcs)

    #
    # row 0: entire light curve, pre-detrending (with horiz bar showing
    # rotation period). plot model LC too.
    #
    try:
        ax0.scatter(lcd['predetrending_time'], lcd['predetrending_rel_flux'],
                    c='k', alpha=1.0, zorder=3, s=10, rasterized=True,
                    linewidths=0)
    except KeyError as e:
        print('ERR! {}\nReturning.'.format(e))
        return


    try:
        model_flux = nparr(lcd['predetrending_rel_flux']/lcd['rel_flux'])
    except ValueError:
        model_flux = 0

    if isinstance(model_flux, np.ndarray):
        ngroups, groups = find_lc_timegroups(lcd['predetrending_time'], mingap=0.5)
        for group in groups:
            ax0.plot(lcd['predetrending_time'][group], model_flux[group], c='C0',
                     alpha=1.0, zorder=2, rasterized=True, lw=2)

    # add the bar showing the derived period
    ymax = np.percentile(lcd['predetrending_rel_flux'], 95)
    ymin = np.percentile(lcd['predetrending_rel_flux'], 5)
    ydiff = 1.15*(ymax-ymin)

    epoch = np.nanmin(lcd['predetrending_time']) + lcd['ls_period']
    ax0.plot([epoch, epoch+lcd['ls_period']], [ymax, ymax], color='red', lw=2,
             zorder=4)

    ax0.set_ylim((ymin-ydiff,ymax+ydiff))

    #ax0.set_xlabel('Time [BJD$_{\mathrm{TDB}}$]')
    ax0.set_xticklabels('')
    ax0.set_ylabel('Raw flux')

    name = outd['name']
    group_id = outd['group_id']
    if name=='nan':
        nstr = 'Group {}'.format(group_id)
    else:
        nstr = '{}'.format(name)


    if not np.isfinite(outd['teff']):
        outd['teff'] = 0

    ax0.text(0.98, 0.97,
        'Teff={:d}K. {}'.format(int(outd['teff']), nstr),
             ha='right', va='top', fontsize='large', zorder=2,
             transform=ax0.transAxes
    )

    #
    # row 1: entire light curve (with horiz bar showing rotation period)
    #
    ax1.scatter(lcd['time'], lcd['rel_flux'], c='k', alpha=1.0, zorder=2, s=10,
                rasterized=True, linewidths=0)

    # add the bar showing the derived period
    ymax = np.percentile(lcd['rel_flux'], 95)
    ymin = np.percentile(lcd['rel_flux'], 5)
    ydiff = 1.15*(ymax-ymin)

    epoch = np.nanmin(lcd['time']) + lcd['ls_period']
    ax1.plot([epoch, epoch+lcd['ls_period']], [ymax, ymax], color='red', lw=2)

    ax1.set_ylim((ymin-ydiff,ymax+ydiff))

    ax1.set_xlabel('Time [BJD$_{\mathrm{TDB}}$]')
    ax1.set_ylabel('Detrended flux')

    #
    # row 2, col 0: lomb scargle periodogram
    #
    ax2.plot(1/freq, power, c='k')
    ax2.set_xscale('log')
    ax2.text(0.03, 0.97, 'FAP={:.1e}\nP={:.1f}d'.format(
        lcd['ls_fap'], lcd['ls_period']), ha='left', va='top',
        fontsize='large', zorder=2, transform=ax2.transAxes
    )
    ax2.set_xlabel('Period [day]', labelpad=-1)
    ax2.set_ylabel('LS power')

    #
    # row 2, col 1: phased light curve 
    #
    phzd = phase_magseries(lcd['time'], lcd['rel_flux'], lcd['ls_period'],
                           lcd['time'][np.argmin(lcd['rel_flux'])], wrap=False,
                           sort=True)

    ax3.scatter(phzd['phase'], phzd['mags'], c='k', rasterized=True, s=10,
                linewidths=0, zorder=1)

    if show_binned:
        try:
            binphasedlc = phase_bin_magseries(phzd['phase'], phzd['mags'],
                                              binsize=1e-2, minbinelems=5)
            binplotphase = binphasedlc['binnedphases']
            binplotmags = binphasedlc['binnedmags']

            ax3.scatter(binplotphase, binplotmags, s=10, c='darkorange',
                        linewidths=0, zorder=3, rasterized=True)
        except TypeError as e:
            print(e)
            pass

    xlim = ax3.get_xlim()
    ax3.hlines(1.0, xlim[0], xlim[1], colors='gray', linestyles='dotted',
               zorder=2)
    ax3.set_xlim(xlim)

    ymax = np.percentile(lcd['rel_flux'], 95)
    ymin = np.percentile(lcd['rel_flux'], 5)
    ydiff = 1.15*(ymax-ymin)
    ax3.set_ylim((ymin-ydiff,ymax+ydiff))

    ax3.set_xlabel('Phase', labelpad=-1)
    ax3.set_ylabel('Flux', labelpad=-0.5)

    #
    # row2, col2: image w/ aperture. put on the nbhr stars as dots too, to
    # ensure the wcs isn't wonky!
    #

    # acquire neighbor stars.
    radius = 2.0*u.arcminute

    nbhr_stars = Catalogs.query_region(
        "{} {}".format(float(c_obj.ra.value), float(c_obj.dec.value)),
        catalog="TIC",
        radius=radius
    )

    try:
        Tmag_cutoff = 15
        px,py = cutout_wcs.all_world2pix(
            nbhr_stars[nbhr_stars['Tmag'] < Tmag_cutoff]['ra'],
            nbhr_stars[nbhr_stars['Tmag'] < Tmag_cutoff]['dec'],
            0
        )
    except Exception as e:
        print('ERR! wcs all_world2pix got {}'.format(repr(e)))
        return

    tmags = nbhr_stars[nbhr_stars['Tmag'] < Tmag_cutoff]['Tmag']

    sel = (px > 0) & (px < 19) & (py > 0) & (py < 19)
    px,py = px[sel], py[sel]
    tmags = tmags[sel]

    ra, dec = float(c_obj.ra.value), float(c_obj.dec.value)
    target_x, target_y = cutout_wcs.all_world2pix(ra,dec,0)

    #
    # finally make it
    #

    img = lcd['median_imgs'][0]

    # some images come out as nans.
    if np.all(np.isnan(img)):
        img = np.ones_like(img)

    interval = vis.PercentileInterval(99.9)
    vmin,vmax = interval.get_limits(img)
    norm = vis.ImageNormalize(
        vmin=vmin, vmax=vmax, stretch=vis.LogStretch(1000))

    cset = ax4.imshow(img, cmap='YlGnBu_r', origin='lower', zorder=1,
                      norm=norm)

    ax4.scatter(px, py, marker='x', c='r', s=5, rasterized=True, zorder=2,
                linewidths=1)
    ax4.plot(target_x, target_y, mew=0.5, zorder=5, markerfacecolor='yellow',
             markersize=7, marker='*', color='k', lw=0)

    #ax4.coords.grid(True, color='white', ls='dotted', lw=1)
    lon = ax4.coords['ra']
    lat = ax4.coords['dec']

    lon.set_ticks(spacing=1*u.arcminute)
    lat.set_ticks(spacing=1*u.arcminute)

    lon.set_ticklabel(exclude_overlapping=True)
    lat.set_ticklabel(exclude_overlapping=True)

    ax4.coords.grid(True, color='white', alpha=0.3, lw=0.3, ls='dotted')

    #cb0 = fig.colorbar(cset, ax=ax4, extend='neither', fraction=0.046, pad=0.04)

    # overplot aperture
    radius_px = 3
    circle = plt.Circle((target_x, target_y), radius_px,
                         color='C1', fill=False, zorder=5)
    ax4.add_artist(circle)

    #
    # cleanup
    # 
    for ax in [ax0,ax1,ax2,ax3,ax4]:
        ax.get_yaxis().set_tick_params(which='both', direction='in',
                                       labelsize='small', top=True, right=True)
        ax.get_xaxis().set_tick_params(which='both', direction='in',
                                       labelsize='small', top=True, right=True)

    fig.tight_layout(w_pad=0.5, h_pad=0)

    #
    # save
    #
    fig.savefig(outvppath, dpi=300, bbox_inches='tight')
    print('made {}'.format(outvppath))
def plot_phasefold(picklepath, xlim=None, ylim0=None, ylim1=None):

    # d['magseries'].keys()
    # dict_keys(['times', 'mags', 'errs', 'magsarefluxes'])
    # d['fitinfo'].keys()
    # dict_keys(['initialparams', 'initialmags', 'fixedparams',
    #            'finalparams', 'finalparamerrs', 'fitmags', 'fitepoch'])
    # d['fitinfo']['finalparams'].keys()
    # dict_keys(['incl', 'period', 'rp', 'sma', 't0', 'u_linear', 'u_quad'])
    d = pickle.load(open(picklepath, 'rb'))

    times = d['magseries']['times']
    fluxs = d['magseries']['mags']
    fitfluxs = d['fitinfo']['fitmags']
    errs = d['magseries']['errs']

    fit_t0 = d['fitinfo']['finalparams']['t0']
    # NOTE: might want to use the best-fit value from the tables, instead of
    # the BLS period here.
    fit_period = d['fitinfo']['finalparams']['period']

    phzd = phase_magseries(times,
                           fluxs,
                           fit_period,
                           fit_t0,
                           wrap=True,
                           sort=True)
    fit_phzd = phase_magseries(times,
                               fitfluxs,
                               fit_period,
                               fit_t0,
                               wrap=True,
                               sort=True)

    phase = phzd['phase']
    phz_flux = phzd['mags']
    fit_phz_flux = fit_phzd['mags']

    binsize = 0.003
    bin_phzd = phase_bin_magseries(phase, phz_flux, binsize=binsize)
    bin_phase = bin_phzd['binnedphases']
    bin_fluxs = bin_phzd['binnedmags']
    fit_bin_phzd = phase_bin_magseries(phase, fit_phz_flux, binsize=binsize)
    fit_bin_phase = fit_bin_phzd['binnedphases']
    fit_bin_fluxs = fit_bin_phzd['binnedmags']

    ##########################################
    plt.close('all')
    f, (a0, a1) = plt.subplots(nrows=2,
                               ncols=1,
                               sharex=True,
                               figsize=(0.8 * 6, 0.8 * 4),
                               gridspec_kw={'height_ratios': [3, 1]})

    a0.scatter(phase * fit_period * 24,
               phz_flux,
               c='k',
               alpha=0.12,
               label='data',
               zorder=1,
               s=10,
               rasterized=True,
               linewidths=0)
    a0.plot(bin_phase * fit_period * 24,
            bin_fluxs,
            alpha=1,
            mew=0.5,
            zorder=8,
            label='binned',
            markerfacecolor='yellow',
            markersize=8,
            marker='.',
            color='black',
            lw=0,
            rasterized=True)
    a0.plot(phase * fit_period * 24,
            fit_phz_flux,
            c='#4346ff',
            zorder=2,
            rasterized=True,
            lw=1.5,
            alpha=0.7,
            label='model')

    trans = transforms.blended_transform_factory(a0.transAxes, a0.transData)
    a0.errorbar(0.88,
                0.97,
                yerr=np.median(errs),
                fmt='none',
                ecolor='gray',
                elinewidth=1,
                capsize=2,
                transform=trans)

    a1.scatter(phase * fit_period * 24,
               phz_flux - fit_phz_flux,
               c='k',
               alpha=0.12,
               rasterized=True,
               s=10,
               linewidths=0,
               zorder=1)
    a1.plot(bin_phase * fit_period * 24,
            bin_fluxs - fit_bin_fluxs,
            alpha=1,
            mew=0.5,
            zorder=8,
            markerfacecolor='yellow',
            markersize=8,
            marker='.',
            color='black',
            lw=0,
            rasterized=True)
    a1.plot(phase * fit_period * 24,
            fit_phz_flux - fit_phz_flux,
            c='#4346ff',
            zorder=2,
            rasterized=True,
            lw=1.5,
            alpha=0.7)

    a1.set_xlabel('Time from mid-transit [hours]')
    a0.set_ylabel('Relative flux')
    a1.set_ylabel('Residual')
    for a in [a0, a1]:
        a.get_yaxis().set_tick_params(which='both', direction='in')
        a.get_xaxis().set_tick_params(which='both', direction='in')
        if xlim:
            a.set_xlim(xlim)
    if ylim0:
        a0.set_ylim(ylim0)
    if ylim1:
        a1.set_ylim(ylim1)
    a0.legend(loc='best', fontsize='small')

    f.tight_layout(h_pad=-.3, w_pad=0)
    savpath = '../results/phasefold.png'
    f.savefig(savpath, dpi=600, bbox_inches='tight')
    print('made {}'.format(savpath))
    copyfile(savpath, '../paper/f2.png')
    print('saved ../paper/f2.png')
Beispiel #5
0
def plot_phase(fpath,
               ax,
               ind,
               s=3,
               alpha=0.3,
               lctype='IRM2',
               periodogramtype=None,
               peakindex=0,
               plot_bin_phase=False,
               overwritecsv=1):

    outsavpath = os.path.join(
        OUTDIR,
        'quilt_s6_s7_' + os.path.basename(fpath).replace('.fits', '.csv'))

    if os.path.exists(outsavpath) and not overwritecsv:
        df = pd.read_csv(outsavpath)
        phase = nparr(df['phase'])
        phz_flux = nparr(df['phz_flux'])
        period = nparr(df['period'])[0]

    else:
        #
        # get data. fpath here is a fits LC file. apply the periodogram requested.
        #
        time = iu.get_data_keyword(fpath, 'TMID_BJD', ext=1)
        mag = iu.get_data_keyword(fpath, lctype, ext=1)

        f_x0 = 1e4
        m_x0 = 10
        flux = f_x0 * 10**(-0.4 * (mag - m_x0))
        flux /= np.nanmedian(flux)

        time, flux = moe.mask_orbit_start_and_end(time, flux)

        # fit out long term trend (light detrending) with median filter of 5 days.
        if 'IRM' in lctype:
            ngroups, groups = lcmath.find_lc_timegroups(time, mingap=0.5)
            assert ngroups == 2

            windowsize = 48 * 5 + 1  # 5 days
            tg_smooth_flux = []
            for group in groups:

                #
                # fit out arbitrary order legendre series
                # p(x) = c_0*L_0(x) + c_1*L_1(x) + c_2*L_2(x) + ... + c_n*L_n(x)
                #
                legendredeg = 2
                p = Legendre.fit(time[group], flux[group], legendredeg)
                coeffs = p.coef
                fit_flux = p(time[group])

                tg_smooth_flux.append(flux[group] / fit_flux)

            flux = np.concatenate(tg_smooth_flux)

        if periodogramtype == 'tls':
            period_min, period_max = 0.5, 5
            tlsp = periodbase.tls_parallel_pfind(
                time,
                flux,
                1e-3 * flux,
                magsarefluxes=True,
                tls_rstar_min=0.1,
                tls_rstar_max=10,
                tls_mstar_min=0.1,
                tls_mstar_max=5.0,
                tls_oversample=8,
                tls_mintransits=1,
                tls_transit_template='default',
                nbestpeaks=5,
                sigclip=None,
                nworkers=52)

            period = tlsp['nbestperiods'][peakindex]
            t0 = tlsp['tlsresult']['T0']
            if peakindex == 1:
                t0 += period / 2

        elif periodogramtype == 'gls':
            period_min, period_max = 0.1, 5
            ls = LombScargle(time, flux, flux * 1e-3)
            freq, power = ls.autopower(minimum_frequency=1 / period_max,
                                       maximum_frequency=1 / period_min,
                                       samples_per_peak=20)
            period = 1 / freq[np.argmax(power)]
            t0 = time[np.argmin(flux)]

        else:
            raise NotImplementedError(
                'got {}, not imlemented'.format(periodogramtype))

        #
        # phase data
        #
        phzd = phase_magseries(time, flux, period, t0, wrap=True, sort=True)

        phase = phzd['phase']
        phz_flux = phzd['mags']

    #
    # plot data
    #
    ax.scatter(phase,
               phz_flux,
               c='k',
               alpha=alpha,
               zorder=3,
               s=s,
               rasterized=True,
               linewidths=0)

    ax.text(0.88,
            0.03,
            '{:.2f}d'.format(period),
            transform=ax.transAxes,
            ha='right',
            va='bottom')

    ax.text(0.04,
            0.06,
            '{}'.format(ind),
            transform=ax.transAxes,
            ha='left',
            va='bottom')

    if overwritecsv:
        outdf = pd.DataFrame({
            'phase': phase,
            'phz_flux': phz_flux,
            'period': np.ones_like(phase) * period
        })
        outdf.to_csv(outsavpath, index=False)

    if plot_bin_phase:

        binphasedlc = phase_bin_magseries(phase,
                                          phz_flux,
                                          binsize=2e-2,
                                          minbinelems=3)
        binplotphase = binphasedlc['binnedphases']
        binplotmags = binphasedlc['binnedmags']

        ax.scatter(binplotphase,
                   binplotmags,
                   c='orange',
                   alpha=alpha,
                   zorder=4,
                   s=s,
                   rasterized=True,
                   linewidths=0)