def test_checkplot_with_multiple_same_pfmethods():
    '''
    This tests running the same period-finder for different period ranges.

    '''

    outpath = os.path.join(os.path.dirname(LCPATH), 'test-checkplot.pkl')

    lcd, msg = hatlc.read_and_filter_sqlitecurve(LCPATH)

    gls_1 = periodbase.pgen_lsp(lcd['rjd'],
                                lcd['aep_000'],
                                lcd['aie_000'],
                                startp=0.01,
                                endp=0.1)
    gls_2 = periodbase.pgen_lsp(lcd['rjd'],
                                lcd['aep_000'],
                                lcd['aie_000'],
                                startp=0.1,
                                endp=300.0)
    pdm_1 = periodbase.stellingwerf_pdm(lcd['rjd'],
                                        lcd['aep_000'],
                                        lcd['aie_000'],
                                        startp=0.01,
                                        endp=0.1)
    pdm_2 = periodbase.stellingwerf_pdm(lcd['rjd'],
                                        lcd['aep_000'],
                                        lcd['aie_000'],
                                        startp=0.1,
                                        endp=300.0)

    assert isinstance(gls_1, dict)
    assert isinstance(gls_2, dict)
    assert isinstance(pdm_1, dict)
    assert isinstance(pdm_2, dict)

    cpf = checkplot.checkplot_pickle([gls_1, gls_2, pdm_1, pdm_2],
                                     lcd['rjd'],
                                     lcd['aep_000'],
                                     lcd['aie_000'],
                                     outfile=outpath,
                                     objectinfo=lcd['objectinfo'])

    assert os.path.exists(cpf)
    assert os.path.abspath(cpf) == os.path.abspath(outpath)

    cpd = _read_checkplot_picklefile(cpf)
    pfmethods = list(cpd['pfmethods'])

    assert len(pfmethods) == 4

    assert '0-gls' in pfmethods
    assert '1-gls' in pfmethods
    assert '2-pdm' in pfmethods
    assert '3-pdm' in pfmethods
Exemple #2
0
def test_checkplot_pickle_make():
    '''
    Tests if a checkplot pickle can be made.

    '''

    outpath = os.path.join(os.path.dirname(LCPATH),
                           'test-checkplot.pkl')

    lcd, msg = hatlc.read_and_filter_sqlitecurve(LCPATH)
    gls = periodbase.pgen_lsp(lcd['rjd'], lcd['aep_000'], lcd['aie_000'])

    assert isinstance(gls, dict)
    assert_allclose(gls['bestperiod'], 1.54289477)

    pdm = periodbase.stellingwerf_pdm(lcd['rjd'],
                                      lcd['aep_000'],
                                      lcd['aie_000'])

    assert isinstance(pdm, dict)
    assert_allclose(pdm['bestperiod'], 3.08578956)

    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo']
    )

    assert os.path.exists(outpath)
Exemple #3
0
def test_checkplot_pickle_update():
    '''
    Tests if a checkplot pickle can be made, read back, and updated.

    '''

    outpath = os.path.join(os.path.dirname(LCPATH),
                           'test-checkplot.pkl')

    lcd, msg = hatlc.read_and_filter_sqlitecurve(LCPATH)
    gls = periodbase.pgen_lsp(lcd['rjd'], lcd['aep_000'], lcd['aie_000'])

    assert isinstance(gls, dict)
    assert_allclose(gls['bestperiod'], 1.54289477)

    pdm = periodbase.stellingwerf_pdm(lcd['rjd'],
                                      lcd['aep_000'],
                                      lcd['aie_000'])

    assert isinstance(pdm, dict)
    assert_allclose(pdm['bestperiod'], 3.08578956)

    # test write
    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo']
    )

    assert os.path.exists(outpath)

    # test read back
    cpd = checkplot._read_checkplot_picklefile(cpf)

    assert isinstance(cpd, dict)

    cpdkeys = set(list(cpd.keys()))
    testset = {'0-gls', '1-pdm', 'comments', 'externalplots',
               'finderchart', 'magseries', 'neighbors', 'normmingap',
               'normto', 'objectid', 'objectinfo', 'pfmethods', 'sigclip',
               'signals', 'status', 'varinfo'}
    assert (testset - cpdkeys) == set()

    assert_allclose(cpd['0-gls']['bestperiod'], 1.54289477)
    assert_allclose(cpd['1-pdm']['bestperiod'], 3.08578956)

    # test update write to pickle
    cpd['comments'] = ('this is a test of the checkplot pickle '
                       'update mechanism. this is only a test.')
    cpfupdated = checkplot.checkplot_pickle_update(cpf, cpd)

    cpdupdated = checkplot._read_checkplot_picklefile(cpfupdated)

    assert cpdupdated['comments'] == cpd['comments']
def do_period_finding_fitslc(lcpath,
                             fluxap='TFA2',
                             period_min=0.5,
                             outdir=None):

    if not outdir:
        outdir = os.path.dirname(lcpath)
    outfile = os.path.basename(lcpath).replace('.fits',
                                               '_spdm_blsp_checkplot.png')
    outpath = os.path.join(outdir, outfile)
    if os.path.exists(outpath):
        print('found & skipped {}'.format(outpath))
        return

    hdulist = fits.open(lcpath)
    hdr, lc = hdulist[0].header, hdulist[1].data

    times, mags, errs = (lc['TMID_BJD'], lc[fluxap], np.ones_like(lc[fluxap]) *
                         np.nanmedian(lc[fluxap]) / 1000)

    #glsp = periodbase.pgen_lsp(times,mags,errs)
    spdm = periodbase.stellingwerf_pdm(times, mags, errs)
    blsp = periodbase.bls_parallel_pfind(times,
                                         mags,
                                         errs,
                                         startp=period_min,
                                         get_stats=False)

    objectinfo = {}
    keys = ['objectid', 'ra', 'decl', 'pmra', 'pmdecl', 'teff', 'gmag']
    hdrkeys = [
        'Gaia-ID', 'RA[deg]', 'Dec[deg]', 'PM_RA[mas/yr]', 'PM_Dec[mas/year]',
        'teff_val', 'phot_g_mean_mag'
    ]
    for k, hk in zip(keys, hdrkeys):
        if hk in hdr:
            objectinfo[k] = hdr[hk]
        else:
            objectinfo[k] = np.nan

    cp = checkplot.twolsp_checkplot_png(blsp,
                                        spdm,
                                        times,
                                        mags,
                                        errs,
                                        objectinfo=objectinfo,
                                        outfile=outpath,
                                        sigclip=[50., 5.],
                                        plotdpi=100,
                                        phasebin=3e-2,
                                        phasems=6.0,
                                        phasebinms=12.0,
                                        unphasedms=6.0)
    print('did {}'.format(outpath))
def test_pdm():
    '''
    Tests periodbase.stellingwerf_pdm.

    '''
    lcd, msg = hatlc.read_and_filter_sqlitecurve(LCPATH)
    pdm = periodbase.stellingwerf_pdm(lcd['rjd'], lcd['aep_000'],
                                      lcd['aie_000'])

    assert isinstance(pdm, dict)
    assert_allclose(pdm['bestperiod'], 3.08578956)
def stellarvar_process_raw_lc(lcfile, mingap=0.5, windowsize=48 * 3):
    """
    process raw lightcurve (IRM2) to show off stellar variability.  turn it to
    relative flux units. stitch consistent normalization across orbits. (also,
    median filter with a BIG window).  get the stellingwerf period and t0 as
    well.

        mingap (float): units of days

    return:

        time, whitened_flux, err_flux, flux, outdir, spdm
    """
    if windowsize % 2 == 0:
        windowsize += 1

    hdulist = fits.open(lcfile)
    data = hdulist[1].data

    time, mag, err_mag = data['TMID_BJD'], data['IRM2'], data['IRE2']

    time, flux, err_flux = _get_flux_from_mags(time, mag, err_mag)

    # for detrending, need to split into orbits.  get time groups, and filter
    # each one
    ngroups, groups = lcmath.find_lc_timegroups(time, mingap=mingap)
    assert ngroups == 2

    tg_smooth_flux = []
    for group in groups:
        #tg_smooth_flux.append( medfilt(flux[group], windowsize) )
        tg_smooth_flux.append(savgol(flux[group], windowsize, polyorder=1))

    flux_smooth = np.concatenate(tg_smooth_flux)

    func = interp1d(time, flux_smooth)
    flux_to_div = func(time)

    outdir = os.path.dirname(lcfile)
    divsavpath = os.path.join(
        outdir, 'DIVMODEL_{}.png'.format(os.path.basename(lcfile)))
    _divmodel_plot(time, flux, flux_to_div, divsavpath)

    whitened_flux = flux / flux_to_div

    spdm = periodbase.stellingwerf_pdm(time,
                                       whitened_flux,
                                       err_flux,
                                       magsarefluxes=True,
                                       nworkers=8)

    return time, whitened_flux, err_flux, flux, outdir, spdm
Exemple #7
0
def allvar_periodogram_checkplot(a):

    ap = int(a['ap'])
    time, flux, err = a['STIME'], a[f'SPCA{ap}'], a[f'SPCAE{ap}']

    spdm = periodbase.stellingwerf_pdm(time,
                                       flux,
                                       err,
                                       magsarefluxes=True,
                                       startp=0.05,
                                       endp=30,
                                       sigclip=5.0,
                                       nworkers=nworkers)

    lsp = periodbase.pgen_lsp(time,
                              flux,
                              err,
                              magsarefluxes=True,
                              startp=0.05,
                              endp=30,
                              autofreq=True,
                              sigclip=5.0,
                              nworkers=nworkers)

    objectinfo = {}
    keys = ['objectid', 'ra', 'decl', 'pmra', 'pmdecl', 'teff', 'gmag']
    hdrkeys = [
        'Gaia-ID', 'RA_OBJ', 'DEC_OBJ', 'PM_RA[mas/yr]', 'PM_Dec[mas/year]',
        'teff_val', 'phot_g_mean_mag'
    ]
    hdr = a['dtr_infos'][0][0]
    for k, hk in zip(keys, hdrkeys):
        if hk in hdr:
            objectinfo[k] = hdr[hk]
        else:
            objectinfo[k] = np.nan

    import matplotlib as mpl
    mpl.rcParams['axes.titlesize'] = 'xx-large'
    mpl.rcParams['axes.labelsize'] = 'xx-large'

    fig = checkplot.twolsp_checkplot_png(lsp,
                                         spdm,
                                         time,
                                         flux,
                                         err,
                                         magsarefluxes=True,
                                         objectinfo=objectinfo,
                                         varepoch='min',
                                         sigclip=None,
                                         plotdpi=100,
                                         phasebin=3e-2,
                                         phasems=6.0,
                                         phasebinms=14.0,
                                         unphasedms=6.0,
                                         figsize=(30, 24),
                                         returnfigure=True,
                                         circleoverlay=APSIZEDICT[ap] * 21,
                                         yticksize=20,
                                         trimylim=True)

    axs = fig.get_axes()

    for ax in axs:
        ax.get_yaxis().set_tick_params(which='both',
                                       direction='in',
                                       labelsize='xx-large')
        ax.get_xaxis().set_tick_params(which='both',
                                       direction='in',
                                       labelsize='xx-large')

    return fig, lsp, spdm, objectinfo
def main(checklcs=0, processlcs=0, makequadplot=0):

    wasp18file = ('../data/showoff_lightcurves/wasp18/'
                  '4955371367334610048_llc.fits')
    blanco1files = glob('../data/showoff_lightcurves/blanco_1/*.fits')
    toifiles = glob('../data/showoff_lightcurves/toi_324/*.fits')
    toi324file = toifiles[0]

    if checklcs:
        check_lightcurve(wasp18file)
        for blanco1file in blanco1files:
            check_lightcurve(blanco1file)
        for toifile in toifiles:
            check_lightcurve(toifile)

    if processlcs:

        # retrieve the LC for
        # blanco_1/2320822863006024832_llc_spdm_blsp_checkplot.png
        fpath = [f for f in blanco1files if '2320822863006024832' in f][0]
        time, whitened_flux, err_flux, flux, outdir, spdm = (
            stellarvar_process_raw_lc(fpath, windowsize=48 * 12))
        period = spdm['bestperiod']
        t0 = np.nanmedian(time)

        assert 0

        # retrieve and clean wasp-18
        (time, whitened_flux, err_flux, time_oot, flux_oot, err_flux_oot, flux,
         outdir) = (transit_process_raw_lc(wasp18file))
        time, whitened_flux, err_flux = wasp18_fine_tuning(
            wasp18file, time, whitened_flux, err_flux, time_oot, flux_oot,
            err_flux_oot, outdir)
        trapd = get_trapd_given_timeseries(wasp18file, time, whitened_flux,
                                           err_flux)
        period, t0 = (trapd['fitinfo']['finalparams'][0],
                      trapd['fitinfo']['finalparams'][1])

        # ditto toi 324
        (time, whitened_flux, err_flux, time_oot, flux_oot, err_flux_oot, flux,
         outdir) = (transit_process_raw_lc(toi324file,
                                           extra_maskfrac=0.3,
                                           windowsize=48))
        time, whitened_flux, err_flux = toi_fine_tuning(
            toi324file, time, whitened_flux, err_flux, time_oot, flux_oot,
            err_flux_oot, outdir)
        trapd = get_trapd_given_timeseries(toi324file, time, whitened_flux,
                                           err_flux)

    if makequadplot:

        fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(6, 3))

        # retrieve and clean wasp-18
        datapklfile = '../data/showoff_lightcurves/wasp18/plot_data.pickle'
        if not os.path.exists(datapklfile):
            (time, whitened_flux, err_flux, time_oot, flux_oot, err_flux_oot,
             flux, outdir) = (transit_process_raw_lc(wasp18file,
                                                     windowsize=48 * 2,
                                                     extra_maskfrac=0.1))
            time, whitened_flux, err_flux = wasp18_fine_tuning(
                wasp18file, time, whitened_flux, err_flux, time_oot, flux_oot,
                err_flux_oot, outdir)
            trapd = get_trapd_given_timeseries(wasp18file, time, whitened_flux,
                                               err_flux)
            period, t0 = (trapd['fitinfo']['finalparams'][0],
                          trapd['fitinfo']['finalparams'][1])
            outd = {
                'time': time,
                'flux': whitened_flux,
                'period': period,
                't0': t0
            }
            with open(datapklfile, 'wb') as f:
                pickle.dump(outd, f, pickle.HIGHEST_PROTOCOL)
                print('dumped to {}'.format(datapklfile))
        else:
            d = pickle.load(open(datapklfile, 'rb'))
            time = d['time']
            whitened_flux = d['flux']
            period = d['period']
            t0 = d['t0']

        plot_phase(time, whitened_flux, period, t0, axs[0, 0])
        axs[0, 0].text(0.96,
                       0.06,
                       'P={:.2f}d'.format(period),
                       transform=axs[0, 0].transAxes,
                       ha='right',
                       va='bottom')

        # ok now TOI 324
        datapklfile = '../data/showoff_lightcurves/toi_324/plot_data.pickle'
        if not os.path.exists(datapklfile):
            (time, whitened_flux, err_flux, time_oot, flux_oot, err_flux_oot,
             flux, outdir) = (transit_process_raw_lc(toi324file,
                                                     extra_maskfrac=0.3,
                                                     windowsize=48))
            time, whitened_flux, err_flux = toi_fine_tuning(
                toi324file, time, whitened_flux, err_flux, time_oot, flux_oot,
                err_flux_oot, outdir)
            trapd = get_trapd_given_timeseries(toi324file, time, whitened_flux,
                                               err_flux)
            period, t0 = (trapd['fitinfo']['finalparams'][0],
                          trapd['fitinfo']['finalparams'][1])
            outd = {
                'time': time,
                'flux': whitened_flux,
                'period': period,
                't0': t0
            }
            with open(datapklfile, 'wb') as f:
                pickle.dump(outd, f, pickle.HIGHEST_PROTOCOL)
                print('dumped to {}'.format(datapklfile))
        else:
            d = pickle.load(open(datapklfile, 'rb'))
            time = d['time']
            whitened_flux = d['flux']
            period = d['period']
            t0 = d['t0']

        plot_phase(time, whitened_flux, period, t0, axs[1, 0], s=5)
        axs[1, 0].text(0.96,
                       0.06,
                       'P={:.2f}d'.format(period),
                       transform=axs[1, 0].transAxes,
                       ha='right',
                       va='bottom')

        # now the blanco-1 mega-rotator
        datapklfile = '../data/showoff_lightcurves/blanco_1/2320822863006024832_plot_data.pickle'
        if not os.path.exists(datapklfile):
            fpath = [f for f in blanco1files if '2320822863006024832' in f][0]
            time, whitened_flux, err_flux, flux, outdir, spdm = (
                stellarvar_process_raw_lc(fpath, windowsize=48 * 12))
            period = spdm['bestperiod']
            t0 = np.nanmedian(time)
            outd = {
                'time': time,
                'flux': whitened_flux,
                'period': period,
                't0': t0
            }
            with open(datapklfile, 'wb') as f:
                pickle.dump(outd, f, pickle.HIGHEST_PROTOCOL)
                print('dumped to {}'.format(datapklfile))
        else:
            d = pickle.load(open(datapklfile, 'rb'))
            time = d['time']
            whitened_flux = d['flux']
            period = d['period']
            t0 = d['t0']

        plot_phase(time, whitened_flux, period, t0, axs[0, 1])
        axs[0, 1].text(0.96,
                       0.94,
                       'P={:.2f}d'.format(period),
                       transform=axs[0, 1].transAxes,
                       ha='right',
                       va='top')

        # finally, the rapid M dwarf rotator
        datapklfile = '../data/showoff_lightcurves/mdwarf_rotators/4742436853122727040_plot_data.pickle'
        if not os.path.exists(datapklfile):
            fpath = '../data/showoff_lightcurves/mdwarf_rotators/4742436853122727040_llc.fits'
            time, whitened_flux, err_flux, flux, outdir, _ = (
                stellarvar_process_raw_lc(fpath, windowsize=48 * 12))
            spdm = periodbase.stellingwerf_pdm(time,
                                               whitened_flux,
                                               err_flux,
                                               magsarefluxes=True,
                                               nworkers=8,
                                               startp=0.1,
                                               endp=0.2,
                                               stepsize=1e-4,
                                               autofreq=False)

            #the largest three flux points are visible outliers
            badfluxs = whitened_flux[np.argpartition(whitened_flux, -3)[-3:]]
            badinds = np.in1d(whitened_flux, badfluxs)
            okinds = ~badinds
            time = time[okinds]
            whitened_flux = whitened_flux[okinds]

            period = spdm['bestperiod']
            t0 = np.nanmedian(time)
            outd = {
                'time': time,
                'flux': whitened_flux,
                'period': period,
                't0': t0
            }
            with open(datapklfile, 'wb') as f:
                pickle.dump(outd, f, pickle.HIGHEST_PROTOCOL)
                print('dumped to {}'.format(datapklfile))
        else:
            d = pickle.load(open(datapklfile, 'rb'))
            time = d['time']
            whitened_flux = d['flux']
            period = d['period']
            t0 = d['t0']

        plot_phase(time, whitened_flux, period, t0, axs[1, 1])
        axs[1, 1].text(0.96,
                       0.06,
                       'P={:.2f}d'.format(period),
                       transform=axs[1, 1].transAxes,
                       ha='right',
                       va='bottom')

        # TWEAK THINGS
        fig.text(0.5, 0, 'Phase', ha='center')
        fig.text(0, 0.5, 'Relative flux', va='center', rotation=90)

        fig.tight_layout(h_pad=0.1, w_pad=0.1)

        axs[0, 0].set_ylim((0.988, 1.001))
        axs[0, 0].set_xlim((-0.7, 0.7))

        axs[1, 0].set_ylim((0.970, 1.009))
        axs[1, 0].set_xlim((-0.7, 0.7))

        axs[0, 1].set_ylim((0.982, 1.018))
        axs[0, 1].set_xlim((-1, 1))

        axs[1, 1].set_ylim((0.93, 1.07))
        axs[1, 1].set_xlim((-1, 1))

        for ax in axs.flatten():
            ax.yaxis.set_ticks_position('both')
            ax.xaxis.set_ticks_position('both')
            ax.get_yaxis().set_tick_params(which='both', direction='in')
            ax.get_xaxis().set_tick_params(which='both', direction='in')

            for tick in ax.xaxis.get_major_ticks():
                tick.label.set_fontsize('small')
            for tick in ax.yaxis.get_major_ticks():
                tick.label.set_fontsize('small')

        fig.tight_layout(h_pad=0.35, w_pad=0.85, pad=0.95)
        outpath = '../results/showoff_lightcurves/showoff_quadplot.png'
        fig.savefig(outpath, bbox_inches='tight', dpi=400)
        print('made {}'.format(outpath))
def test_checkplot_pickle_varepoch_handling(capsys):
    '''This tests the various different ways to give varepoch
    to checkplot_pickle.

    Uses the py.test capsys fixture to capture stdout and see if we reported the
    correct epoch being used.

    '''

    outpath = os.path.join(os.path.dirname(LCPATH),
                           'test-checkplot.pkl')

    lcd, msg = hatlc.read_and_filter_sqlitecurve(LCPATH)
    gls = periodbase.pgen_lsp(lcd['rjd'], lcd['aep_000'], lcd['aie_000'])
    pdm = periodbase.stellingwerf_pdm(lcd['rjd'],
                                      lcd['aep_000'],
                                      lcd['aie_000'])

    assert isinstance(gls, dict)
    assert_allclose(gls['bestperiod'], 1.54289477)

    # 1. usual handling where epoch is None
    # should use min(times) as epoch all the time
    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo'],
        varepoch=None
    )

    assert os.path.exists(outpath)

    # capture the stdout
    captured = capsys.readouterr()

    # see if we used the correct periods and epochs
    splitout = captured.out.split('\n')

    # plot output lines
    plotoutlines = [x for x in splitout if 'phased LC with period' in x]

    # these are the periods and epochs to match per line
    lookfor = ['gls phased LC with period 0: 1.542895, epoch: 56092.64056',
               'gls phased LC with period 1: 0.771304, epoch: 56092.64056',
               'gls phased LC with period 2: 0.514234, epoch: 56092.64056',
               'pdm phased LC with period 0: 3.085790, epoch: 56092.64056',
               'pdm phased LC with period 1: 1.542895, epoch: 56092.64056',
               'pdm phased LC with period 2: 6.157824, epoch: 56092.64056']

    for expected, plotline in zip(lookfor,plotoutlines):
        assert expected in plotline


    # 2. handle varepoch = 'min'
    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo'],
        varepoch='min'
    )

    assert os.path.exists(outpath)

    # capture the stdout
    captured = capsys.readouterr()

    # see if we used the correct periods and epochs
    splitout = captured.out.split('\n')

    # plot output lines
    plotoutlines = [x for x in splitout if 'phased LC with period' in x]

    # these are the periods and epochs to match per line
    lookfor = ['gls phased LC with period 0: 1.542895, epoch: 56341.11968',
               'gls phased LC with period 1: 0.771304, epoch: 56856.46618',
               'gls phased LC with period 2: 0.514234, epoch: 56889.88470',
               'pdm phased LC with period 0: 3.085790, epoch: 56828.62835',
               'pdm phased LC with period 1: 1.542895, epoch: 56341.11968',
               'pdm phased LC with period 2: 6.157824, epoch: 56154.33367']

    for expected, plotline in zip(lookfor,plotoutlines):
        assert expected in plotline


    # 3. handle varepoch = some float
    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo'],
        varepoch=56000.5
    )

    assert os.path.exists(outpath)

    # capture the stdout
    captured = capsys.readouterr()

    # see if we used the correct periods and epochs
    splitout = captured.out.split('\n')

    # plot output lines
    plotoutlines = [x for x in splitout if 'phased LC with period' in x]

    # these are the periods and epochs to match per line
    lookfor = ['gls phased LC with period 0: 1.542895, epoch: 56000.50000',
               'gls phased LC with period 1: 0.771304, epoch: 56000.50000',
               'gls phased LC with period 2: 0.514234, epoch: 56000.50000',
               'pdm phased LC with period 0: 3.085790, epoch: 56000.50000',
               'pdm phased LC with period 1: 1.542895, epoch: 56000.50000',
               'pdm phased LC with period 2: 6.157824, epoch: 56000.50000']

    for expected, plotline in zip(lookfor,plotoutlines):
        assert expected in plotline


    # 4. handle varepoch = list of floats
    cpf = checkplot.checkplot_pickle(
        [gls, pdm],
        lcd['rjd'], lcd['aep_000'], lcd['aie_000'],
        outfile=outpath,
        objectinfo=lcd['objectinfo'],
        varepoch=[[56000.1,56000.2,56000.3],
                  [56000.4,56000.5,56000.6]]
    )

    assert os.path.exists(outpath)

    # capture the stdout
    captured = capsys.readouterr()

    # see if we used the correct periods and epochs
    splitout = captured.out.split('\n')

    # plot output lines
    plotoutlines = [x for x in splitout if 'phased LC with period' in x]

    # these are the periods and epochs to match per line
    lookfor = ['gls phased LC with period 0: 1.542895, epoch: 56000.10000',
               'gls phased LC with period 1: 0.771304, epoch: 56000.20000',
               'gls phased LC with period 2: 0.514234, epoch: 56000.30000',
               'pdm phased LC with period 0: 3.085790, epoch: 56000.40000',
               'pdm phased LC with period 1: 1.542895, epoch: 56000.50000',
               'pdm phased LC with period 2: 6.157824, epoch: 56000.60000']

    for expected, plotline in zip(lookfor,plotoutlines):
        assert expected in plotline
Exemple #10
0
def _periodicity_analysis(hatid,
                          times,
                          mags,
                          errs,
                          normlcd,
                          varperiod=None,
                          isresidual=False):
    '''
    Given times, magnitudes, and errors, run Phase Dispersion Minimization and
    Box Least Squares, then write the phase-folded LCs, periodograms, and
    header data to a checkplot pickle.
    Typically, in 03_EB_processing.py, mags will be (data+injected planet), or
    (data + injected planet - EB model).

    Args:
        hatid (str): HAT-XXX-XXXXXXX
        times (np.array): times of measurement (typically RJD)
        mags (np.array): measured magnitudes at observing times
        errs (np.array): measured error on mags
        normlcd: lightcurve dictionary from early reading / astrobase parsing
    Keyword Args:
        varperiod (float, default None): EB period, used to set upper and lower
        bounds of frequency search.
        isresidual (bool, default False): if `mags` is from residuals, use
        this. It will do a denser frequency search, at >~2x the EB period.
    Returns:
        nothing
    '''
    #TODO: fix args, add docs

    if not varperiod:
        #injection has happened
        smallest_p = 0.5
        cpwritepre = '../data/detachedEBs/injs/checkplot-inj-'
    elif isinstance(varperiod, float) and isresidual:
        smallest_p = varperiod * 2. + 0.1
        cpwritepre = '../data/detachedEBs/injres/checkplot-injresiduals-'
    else:
        raise ValueError('smallest_p never properly assigned')

    biggest_p = min((times[-1] - times[0]) / 2.01, 100.)

    print('\nStellingwerf...\n')
    spdmp = periodbase.stellingwerf_pdm(
        times,
        mags,
        errs,
        autofreq=True,
        startp=smallest_p,
        endp=biggest_p,
        normalize=False,
        stepsize=1.0e-5,
        phasebinsize=0.03,
        mindetperbin=9,
        nbestpeaks=5,
        periodepsilon=0.1,  # 0.1days
        sigclip=None,  # no sigma clipping
        nworkers=None)

    varinfo = {
        'objectisvar': True,
        'vartags': None,
        'varisperiodic': True,
        'varperiod': spdmp['bestperiod'],
        'varepoch': None
    }

    print('\nBLS...\n')
    blsp = periodbase.bls_parallel_pfind(times,
                                         mags,
                                         errs,
                                         startp=smallest_p,
                                         endp=biggest_p,
                                         stepsize=1.0e-5,
                                         mintransitduration=0.01,
                                         maxtransitduration=0.6,
                                         nphasebins=200,
                                         autofreq=False,
                                         nbestpeaks=5,
                                         periodepsilon=0.1,
                                         nworkers=None,
                                         sigclip=None)

    lspinfolist = [spdmp, blsp]
    cp = checkplot.checkplot_pickle(lspinfolist,
                                    times,
                                    mags,
                                    errs,
                                    nperiodstouse=3,
                                    objectinfo=normlcd['objectinfo'],
                                    varinfo=varinfo,
                                    findercmap='gray_r',
                                    normto='globalmedian',
                                    normmingap=4.,
                                    outfile=cpwritepre + hatid + '.pkl.gz',
                                    sigclip=[10., -3.],
                                    varepoch='min',
                                    phasewrap=True,
                                    phasesort=True,
                                    phasebin=0.002,
                                    plotxlim=[-0.6, 0.6],
                                    plotdpi=150,
                                    returndict=False,
                                    pickleprotocol=3,
                                    greenhighlight=False,
                                    xgridlines=[-0.5, 0., 0.5])

    #since we don't have easy checkplot_pickle to png written yet, use twolsp_checkplot_png
    #TODO: remove any png writing once happy with output
    if not varperiod:
        injpath = '../data/detachedEBs/plots/3_checkplot-inj-'
    elif isinstance(varperiod, float) and isresidual:
        injpath = '../data/detachedEBs/plots/5_checkplot-injresiduals-'
    else:
        raise ValueError('injpath never properly assigned')

    checkplot.twolsp_checkplot_png(spdmp,
                                   blsp,
                                   times,
                                   mags,
                                   errs,
                                   objectinfo=normlcd['objectinfo'],
                                   findercmap='gray_r',
                                   normto='globalmedian',
                                   normmingap=4.,
                                   outfile=injpath + hatid + '.png',
                                   sigclip=[10., -3.],
                                   varepoch='min',
                                   phasewrap=True,
                                   phasesort=True,
                                   phasebin=0.002,
                                   plotxlim=[-0.6, 0.6],
                                   plotdpi=150)
    plt.close('all')
Exemple #11
0
def periodicity_analysis(out, DSP_lim=None, field_id=None, DEBiL_write=False):
    '''
    Given a specified field (e.g., G199), previous steps have created
    data/HATpipe/blsanalsums/cuts for that field and neighbors (imposing cuts
    on DSP_lim, Ntra_min, and NTV). They've also downloaded the appropriate
    LCs.
    Now rerun the periodicity analysis for these LCs (Box-Least-Squares and
    Stellingwerf Phase Dispersion Minimization), and make eb_checkplots for
    subsequent looking-at ("visual inspection").

    Args:
       DEBiL_write (bool): whether to write a "name and best BLS period" file
           (in basically all use cases, not necessary).
    '''
    assert type(field_id) == str
    print('\nBeginning periodicity analysis...\n\n')

    # File name format: HAT-199-0025234-V0-DR0-hatlc.sqlite.gz
    field_name = 'G' + field_id  # e.g., 'G081'
    LC_read_path = '../data/LCs/' + field_name + '/'  # where sqlitecurves already exist
    tail_str = '-V0-DR0-hatlc.sqlite.gz'
    # paths for LCs and EB checkplots
    LC_write_path = '../data/LCs_cut/' + field_name + '_' + str(DSP_lim)
    CP_write_path = '../data/CPs_cut/' + field_name + '_' + str(DSP_lim)

    for outpath in [
            LC_write_path, LC_write_path + '/periodcut',
            LC_write_path + '/onedaycut', LC_write_path + '/shortcoveragecut',
            CP_write_path, CP_write_path + '/periodcut',
            CP_write_path + '/onedaycut', CP_write_path + '/shortcoveragecut'
    ]:

        if not os.path.isdir(outpath):
            os.makedirs(outpath)

    for ix, hatid in enumerate(out.index):
        if np.all(out.ix[hatid]['has_sqlc']):
            LC_cut_path = LC_write_path + '/' + hatid + tail_str
            LC_periodcut_path = LC_write_path + '/periodcut/' + hatid + tail_str
            LC_onedaycut_path = LC_write_path + '/onedaycut/' + hatid + tail_str
            LC_shortcoveragecut_path = LC_write_path + '/shortcoveragecut/' + hatid + tail_str
            CP_cut_path = CP_write_path + '/' + hatid + '.png'
            CP_periodcut_path = CP_write_path + '/periodcut/' + hatid + '.png'
            CP_onedaycut_path = CP_write_path + '/onedaycut/' + hatid + '.png'
            CP_shortcoveragecut_path = CP_write_path + '/shortcoveragecut/' + hatid + '.png'

            if (not os.path.exists(CP_cut_path)) \
            and (not os.path.exists(CP_periodcut_path)) \
            and (not os.path.exists(CP_onedaycut_path)) \
            and (not os.path.exists(CP_shortcoveragecut_path)):
                # Get sqlitecurve data.
                obj_path = LC_read_path + hatid + tail_str
                lcd, msg = hatlc.read_and_filter_sqlitecurve(obj_path)
                # Make sure all observations are at the same zero-point.
                normlcd = hatlc.normalize_lcdict(lcd)
                # Select recommended EPD aperture with 'G' flag. (Alternate
                # approach: take the smallest aperture to minimize crowding).
                ap = next(iter(lcd['lcbestaperture']['ap']))
                times = normlcd['rjd'][normlcd['aiq_' + ap] == 'G']
                mags = normlcd['aep_' + ap][normlcd['aiq_' + ap] == 'G']
                errs = normlcd['aie_' + ap][normlcd['aiq_' + ap] == 'G']

                # Period analysis: Stellingwerf phase dispersion minimization
                # and rerun Box-Least-Squares. Range of interesting periods:
                # 0.5days-100days. BLS can only search for periods < half the
                # light curve observing baseline. (N.b. 100d signals are
                # basically always going to be stellar rotation)
                smallest_p = 0.5
                biggest_p = min((times[-1] - times[0]) / 2.01, 100.)

                print('\nStellingwerf...\n')
                spdmp = periodbase.stellingwerf_pdm(
                    times,
                    mags,
                    errs,
                    autofreq=True,
                    startp=smallest_p,
                    endp=biggest_p,
                    normalize=False,
                    stepsize=1.0e-4,
                    phasebinsize=0.05,
                    mindetperbin=9,
                    nbestpeaks=5,
                    periodepsilon=0.1,  # 0.1days
                    sigclip=None,  # no sigma clipping
                    nworkers=None)

                print('\nBLS...\n')
                blsp = periodbase.bls_parallel_pfind(
                    times,
                    mags,
                    errs,
                    startp=smallest_p,
                    endp=biggest_p,  # don't search full timebase
                    stepsize=1.0e-5,
                    mintransitduration=0.01,  # minimum transit length in phase
                    maxtransitduration=0.7,  # maximum transit length in phase
                    nphasebins=200,
                    autofreq=False,  # figure out f0, nf, and df automatically
                    nbestpeaks=5,
                    periodepsilon=0.1,  # 0.1
                    nworkers=None,
                    sigclip=None)

                # Make and save checkplot to be looked at.
                cp = plotbase.make_eb_checkplot(
                    spdmp,
                    blsp,
                    times,
                    mags,
                    errs,
                    objectinfo=normlcd['objectinfo'],
                    findercmap='gray_r',
                    normto='globalmedian',
                    normmingap=4.0,
                    outfile=CP_cut_path,
                    sigclip=None,
                    varepoch='min',
                    phasewrap=True,
                    phasesort=True,
                    phasebin=0.002,
                    plotxlim=[-0.6, 0.6])

                # Copy LCs with DSP>DSP_lim to /data/LCs_cut/G???_??/
                if not os.path.exists(LC_cut_path):
                    copyfile(obj_path, LC_cut_path)
                    print('Copying {} -> {}\n'.format(obj_path, LC_cut_path))

                #### CUTS ####
                maxperiod = 30.  # days
                bestperiods = spdmp['nbestperiods'] + blsp['nbestperiods']
                best3periods = spdmp['nbestperiods'][:3]+\
                        blsp['nbestperiods'][:3]
                bparr, b3parr = np.array(bestperiods), np.array(best3periods)

                minperiod = 0.5002  # days; else this harmonic of 1d happens
                proxto1d_s, proxto1d_m, proxto1d_b = 0.01, 0.015, 0.02  # days
                bestbls, bestspdm = blsp['bestperiod'], spdmp['bestperiod']

                mindayscoverage = 3.
                cadence = 4.  # minutes
                minnumpoints = mindayscoverage * 24 * 60 / cadence

                # (If 5 of the 6 best peaks are above max period (30 days)), OR
                # (If all of the SPDM peaks are above max period and the BLS
                # peaks are not, and all the BLS peaks less than the max period
                # are within 0.1days separate from e/other) OR
                # (The same, with BLS/SPDM switched), OR
                # (The difference between all SPDM is <0.1day and the
                # difference between all BLS is <0.1day)
                #
                # [n.b. latter broad-peak behavior happens b/c of stellar rotn]
                sb3parr = np.sort(b3parr)
                spdmn = np.array(spdmp['nbestperiods'][:3])
                blsn = np.array(blsp['nbestperiods'][:3])
                ps = 0.2  # peak_separation, days
                b3pint = b3parr[(b3parr < maxperiod) & (
                    b3parr > 2 * minperiod)]  # interesting periods

                if npall(sb3parr[1:] > maxperiod) \
                   or \
                   ((npall(spdmn>maxperiod) and not npall(blsn>maxperiod)) and
                   npall(abs(npdiff(blsn[blsn<maxperiod]))<ps)) \
                   or \
                   ((npall(blsn>maxperiod) and not npall(spdmn>maxperiod)) and
                   npall(abs(npdiff(spdmn[spdmn<maxperiod]))<ps)) \
                   or \
                   (npall(abs(npdiff(spdmn))<ps) and
                   npall(abs(npdiff(blsn))<ps)):

                    os.rename(LC_cut_path, LC_periodcut_path)
                    os.rename(CP_cut_path, CP_periodcut_path)

                # All 6 best peaks below max period (and above 1d) are within
                # 0.02days of a multiple of 1, OR
                # Both the BLS and SPDM max peak are within 0.015d of a
                # multiple of 1, OR
                # At least one of the best BLS&SPDM peaks are within 0.015d of one,
                # and of the remaining peaks > 1day, the rest are within 0.03days of
                # multiples of one.
                elif (npall(npisclose(npminimum(\
                    b3pint%1., abs((b3pint%1.)-1.)), 0., atol=proxto1d_b)))\
                    or \
                    ((npisclose(npminimum(\
                    bestbls%1., abs((bestbls%1.)-1.)), 0., atol=proxto1d_m))
                    and (npisclose(npminimum(\
                    bestspdm%1., abs((bestspdm%1.)-1.)), 0., atol=proxto1d_m)))\
                    or \
                    (\
                    (npisclose(abs(bestbls-1.), 0., atol=proxto1d_m) or
                    npisclose(abs(bestspdm-1.), 0., atol=proxto1d_m)) and
                    (npall(npisclose(npminimum(\
                    b3pint%1., abs((b3pint%1.)-1.)), 0., atol=proxto1d_m*2.)))\
                    ):

                    os.rename(LC_cut_path, LC_onedaycut_path)
                    os.rename(CP_cut_path, CP_onedaycut_path)

                # If there is not enough coverage. "Enough" means 3 days of
                # observations (at 4 minute cadence).
                elif len(mags) < minnumpoints:
                    os.rename(LC_cut_path, LC_shortcoveragecut_path)
                    os.rename(CP_cut_path, CP_shortcoveragecut_path)

        else:
            print('{:d}: {:s} or LC counterpart exists; continue.'.\
                    format(ix, CP_cut_path))
            continue

    print('\nDone with periodicity analysis for {:s}.\n\n'.format(field_name))

    if DEBiL_write:
        # Write DEBiL "input list" of HAT-IDs and periods.
        write_path = '../data/DEBiL_heads/' + field + '_DSP' + str(
            DSP_lim) + '.txt'
        if not os.path.exists(write_path):
            f_id = open(write_path, 'wb+')
            data = np.array([out.index, out['PERIOD']])
            np.savetxt(f_id, data.T, fmt=['%15s', '%.6f'])
            f_id.close()