def test_properties2(capfd):
    """Test if the describe function produces an output.
    The output is 1870 characters at the moment, but we might add more properties."""
    tpf = KeplerTargetPixelFile(filename_tpf_all_zeros)
    tpf.show_properties()
    out, err = capfd.readouterr()
    assert len(out) > 1000
示例#2
0
def test_accessor_k2_campaign():
    # scaled down version of tess sector test, as they share the same codepath
    lc0 = KeplerLightCurve(
        time=np.arange(1, 5),
        flux=np.arange(1, 5),
        flux_err=np.arange(1, 5),
        targetid=50000,
    )
    lc0.meta["CAMPAIGN"] = 2
    lc1 = KeplerLightCurve(
        time=np.arange(10, 15),
        flux=np.arange(10, 15),
        flux_err=np.arange(10, 15),
        targetid=120334,
    )
    lc1.meta["CAMPAIGN"] = 1
    lcc = LightCurveCollection([lc0, lc1])
    assert (lcc.campaign == [2, 1]).all()

    # ensure it works for TPFs too.
    tpf0 = KeplerTargetPixelFile(filename_tpf_all_zeros)
    tpf0.hdu[0].header["CAMPAIGN"] = 2
    tpf1 = KeplerTargetPixelFile(filename_tpf_one_center)
    tpf1.hdu[0].header["CAMPAIGN"] = 1
    tpfc = TargetPixelFileCollection([tpf0, tpf1])
    assert (tpfc.campaign == [2, 1]).all()
def test_bitmasking(quality_bitmask, answer):
    """Test whether the bitmasking behaves like it should"""
    tpf = KeplerTargetPixelFile(filename_tpf_one_center,
                                quality_bitmask=quality_bitmask)
    with warnings.catch_warnings():
        # Ignore "LightCurve contains NaN times" warnings triggered by liberal masks
        warnings.simplefilter("ignore", LightkurveWarning)
        lc = tpf.to_lightcurve()
    assert len(lc.flux) == answer
示例#4
0
def test_tpfcollection_plot():
    tpf = KeplerTargetPixelFile(filename_tpf_all_zeros)
    tpf2 = KeplerTargetPixelFile(filename_tpf_one_center)
    # Does plotting work with 3 TPFs?
    coll = TargetPixelFileCollection([tpf, tpf2, tpf2])
    coll.plot()
    # Does plotting work with one TPF?
    coll = TargetPixelFileCollection([tpf])
    coll.plot()
    plt.close("all")
def test_wcs_tabby(method):
    """Test the centroids from Tabby's star against simbad values"""
    tpf = KeplerTargetPixelFile(TABBY_TPF)
    tpf.wcs
    ra, dec = tpf.get_coordinates(0)
    col, row = tpf.estimate_centroids(method=method)
    col = col.value - tpf.column
    row = row.value - tpf.row
    y, x = int(np.round(col[0])), int(np.round(row[1]))
    # Compare with RA and Dec from Simbad
    assert np.isclose(ra[x, y], 301.5643971, 1e-4)
    assert np.isclose(dec[x, y], 44.4568869, 1e-4)
def test_sine_sff():
    """Can we recover a synthetic sine curve using SFF and LombScargle?"""
    # Retrieve the custom, known signal properties
    tpf = KeplerTargetPixelFile(filename_synthetic_sine)
    true_period = np.float(tpf.hdu[3].header["PERIOD"])
    true_amplitude = np.float(tpf.hdu[3].header["SINE_AMP"])

    # Run the SFF algorithm
    lc = tpf.to_lightcurve()
    corrector = SFFCorrector(lc)
    cor_lc = corrector.correct(
        tpf.pos_corr2,
        tpf.pos_corr1,
        niters=4,
        windows=1,
        bins=7,
        restore_trend=True,
        timescale=0.5,
    )

    # Verify that we get the period within ~20%
    pg = cor_lc.to_periodogram(
        method="lombscargle", minimum_period=1, maximum_period=10, oversample_factor=10
    )
    ret_period = pg.period_at_max_power.value
    threshold = 0.2
    assert (ret_period > true_period * (1 - threshold)) & (
        ret_period < true_period * (1 + threshold)
    )

    # Verify that we get the amplitude to within 10%
    n_cad = len(tpf.time)
    design_matrix = np.vstack(
        [
            np.ones(n_cad),
            np.sin(2.0 * np.pi * cor_lc.time.value / ret_period),
            np.cos(2.0 * np.pi * cor_lc.time.value / ret_period),
        ]
    ).T
    ATA = np.dot(design_matrix.T, design_matrix / cor_lc.flux_err[:, None] ** 2)
    least_squares_coeffs = np.linalg.solve(
        ATA, np.dot(design_matrix.T, cor_lc.flux / cor_lc.flux_err ** 2)
    )
    const, sin_weight, cos_weight = least_squares_coeffs

    fractional_amplitude = (sin_weight ** 2 + cos_weight ** 2) ** (0.5) / const
    assert (fractional_amplitude > true_amplitude / 1.1) & (
        fractional_amplitude < true_amplitude * 1.1
    )
示例#7
0
def test_get_model_prf():
    tpf_fn = get_pkg_data_filename("../../tests/data/test-tpf-star.fits")
    tpf = KeplerTargetPixelFile(tpf_fn)

    prf = KeplerPRF(channel=tpf.channel,
                    shape=tpf.shape[1:],
                    column=tpf.column,
                    row=tpf.row)
    prf_from_tpf = tpf.get_prf_model()

    assert type(prf) == type(prf_from_tpf)
    assert prf.channel == prf_from_tpf.channel
    assert prf.shape == prf_from_tpf.shape
    assert prf.column == prf_from_tpf.column
    assert prf.row == prf_from_tpf.row
示例#8
0
文件: tpf.py 项目: zkbt/illumination
    def plot(self, *args, **kwargs):
        """
        Plot a target pixel file at a given frame (index) or cadence number.

        Parameters
        ----------
        ax : matplotlib.axes._subplots.AxesSubplot
            A matplotlib axes object to plot into. If no axes is provided,
            a new one will be generated.
        frame : int
            Frame number. The default is 0, i.e. the first frame.
        cadenceno : int, optional
            Alternatively, a cadence number can be provided.
            This argument has priority over frame number.
        bkg : bool
            If True, background will be added to the pixel values.
        aperture_mask : ndarray
            Highlight pixels selected by aperture_mask.
        show_colorbar : bool
            Whether or not to show the colorbar
        mask_color : str
            Color to show the aperture mask
        style : str
            matplotlib.pyplot.style.context, default is 'fast'
        kwargs : dict
            Keywords arguments passed to `lightkurve.utils.plot_image`.

        Returns
        -------
        ax : matplotlib.axes._subplots.AxesSubplot
            The matplotlib axes object.
        """
        ax = KeplerTargetPixelFile.plot(self, *args, **kwargs)
        ax.set_title('TIC: {}'.format(self.tic_id))
        return ax
def test_centroids():
    """Test the estimate centroid method."""
    for fn in (
        filename_synthetic_sine,
        filename_synthetic_transit,
        filename_synthetic_flat,
    ):
        tpf = KeplerTargetPixelFile(fn)
        xraw, yraw = tpf.estimate_centroids()
        xnorm = xraw - np.median(xraw)
        ynorm = yraw - np.median(yraw)
        xposc = tpf.pos_corr2 - np.median(tpf.pos_corr2)
        yposc = tpf.pos_corr1 - np.median(tpf.pos_corr1)
        rmax = np.max(np.sqrt((xnorm.value - xposc) ** 2 + (ynorm.value - yposc) ** 2))
        # The centroids should agree to within a hundredth of a pixel.
        assert rmax < 0.01
def test_interact_sky():
    """Test the Jupyter notebook interact() widget."""
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tess),
    ]:
        tpf.interact_sky()
def test_tpf_plot():
    """Sanity check to verify that tpf plotting works"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tpf_one_center),
        ]
    for tpf in tpfs:
        tpf.plot()
        tpf.plot(aperture_mask=tpf.pipeline_mask)
        tpf.plot(aperture_mask="all")
        tpf.plot(frame=3)
        with pytest.raises(ValueError):
            tpf.plot(frame=999999)
        tpf.plot(cadenceno=125250)
        with pytest.raises(ValueError):
            tpf.plot(cadenceno=999)
        tpf.plot(bkg=True)
        tpf.plot(scale="sqrt")
        tpf.plot(scale="log")
        with pytest.raises(ValueError):
            tpf.plot(scale="blabla")
        tpf.plot(column="FLUX")
        tpf.plot(column="FLUX_ERR")
        tpf.plot(column="FLUX_BKG")
        tpf.plot(column="FLUX_BKG_ERR")
        tpf.plot(column="RAW_CNTS")
        tpf.plot(column="COSMIC_RAYS")
        with pytest.raises(ValueError):
            tpf.plot(column="not a column")

        plt.close("all")
def test_repr():
    """Do __str__ and __repr__ work?"""
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tess),
    ]:
        str(tpf)
        repr(tpf)
def test_load_bad_file():
    """Test if a light curve can be opened without exception."""
    with pytest.raises(ValueError) as exc:
        KeplerTargetPixelFile(TABBY_Q8)
    assert "is this a target pixel file?" in exc.value.args[0]
    with pytest.raises(ValueError) as exc:
        TessTargetPixelFile(TABBY_Q8)
    assert "is this a target pixel file?" in exc.value.args[0]
示例#14
0
def test_transform_and_ylim_funcs():
    """Test the transform_func and ylim_func"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [KeplerTargetPixelFile(filename_tpf_tabby_lite), TessTargetPixelFile(example_tpf)]
    for tpf in tpfs:
        tpf.interact(transform_func=lambda lc: lc.normalize())
        tpf.interact(transform_func=lambda lc: lc.flatten().normalize())
        tpf.interact(transform_func=lambda lc: lc, ylim_func=lambda lc: (0, 2))
        tpf.interact(ylim_func=lambda lc: (0, lc.flux.max()))
def test_wcs():
    """Test the wcs property."""
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tess),
    ]:
        w = tpf.wcs
        ra, dec = tpf.get_coordinates()
        assert ra.shape == tpf.shape
        assert dec.shape == tpf.shape
        assert type(w).__name__ == "WCS"
def test_bkg_lightcurve():
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tess),
    ]:
        lc = tpf.get_bkg_lightcurve()
        lc = tpf.get_bkg_lightcurve(aperture_mask=None)
        lc = tpf.get_bkg_lightcurve(aperture_mask="all")
        assert lc.time.scale == "tdb"
        assert lc.flux.shape == lc.flux_err.shape
        assert len(lc.time) == len(lc.flux)
def test_tpf_shapes():
    """Are the data array shapes of the TargetPixelFile object consistent?"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tpf_all_zeros),
        ]
    for tpf in tpfs:
        assert tpf.quality_mask.shape == tpf.hdu[1].data["TIME"].shape
        assert tpf.flux.shape == tpf.flux_err.shape
def test_transit_sff():
    """Can we recover a synthetic exoplanet signal using SFF and BLS?"""
    # Retrieve the custom, known signal properties
    tpf = KeplerTargetPixelFile(filename_synthetic_transit)
    true_period = np.float(tpf.hdu[3].header["PERIOD"])
    true_rprs = np.float(tpf.hdu[3].header["RPRS"])
    true_transit_lc = tpf.hdu[3].data["NOISELESS_INPUT"]
    max_depth = 1 - np.min(true_transit_lc)

    # Run the SFF algorithm
    lc = tpf.to_lightcurve().normalize()
    corrector = SFFCorrector(lc)
    cor_lc = corrector.correct(
        tpf.pos_corr2,
        tpf.pos_corr1,
        niters=4,
        windows=1,
        bins=7,
        restore_trend=False,
        timescale=0.5,
    )

    # Verify that we get the transit period within 5%
    pg = cor_lc.to_periodogram(
        method="bls",
        minimum_period=1,
        maximum_period=9,
        frequency_factor=0.05,
        duration=np.arange(0.1, 0.6, 0.1),
    )
    ret_period = pg.period_at_max_power.value
    threshold = 0.05
    assert (ret_period > true_period * (1 - threshold)) & (
        ret_period < true_period * (1 + threshold)
    )

    # Verify that we get the transit depth in expected bounds
    assert (pg.depth_at_max_power >= true_rprs ** 2) & (
        pg.depth_at_max_power < max_depth
    )
def test_detrending_residuals():
    """Test the detrending residual distributions"""
    # Retrieve the custom, known signal properties
    tpf = KeplerTargetPixelFile(filename_synthetic_flat)

    # Run the SFF algorithm
    lc = tpf.to_lightcurve()
    corrector = SFFCorrector(lc)
    cor_lc = corrector.correct(
        tpf.pos_corr2, tpf.pos_corr1, niters=10, windows=5, bins=7, restore_trend=True
    )

    # Verify that we get a significant reduction in RMS
    cdpp_improvement = lc.estimate_cdpp() / cor_lc.estimate_cdpp()
    assert cdpp_improvement > 10.0

    # The residuals should be Gaussian-"ish"
    # Table 4.1 of Ivezic, Connolly, Vanerplas, Gray 2014
    anderson_threshold = 1.57

    resid_n_sigmas = (cor_lc.flux - np.mean(cor_lc.flux)) / cor_lc.flux_err
    A_value, _, _ = stats.anderson(resid_n_sigmas)
    assert A_value ** 2 < anderson_threshold

    n_sigma = np.std(resid_n_sigmas)
    assert n_sigma < 2.0

    corrector = tpf.to_corrector("pld")
    cor_lc = corrector.correct(restore_trend=False)

    cdpp_improvement = lc.estimate_cdpp() / cor_lc.estimate_cdpp()
    assert cdpp_improvement > 10.0

    resid_n_sigmas = (cor_lc.flux - np.mean(cor_lc.flux)) / cor_lc.flux_err
    A_value, crit, sig = stats.anderson(resid_n_sigmas)
    assert A_value ** 2 < anderson_threshold

    n_sigma = np.std(resid_n_sigmas)
    assert n_sigma < 2.0
def test_aperture_photometry():
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tess),
    ]:
        tpf.extract_aperture_photometry()
        for mask in [None, "all", "default", "threshold", "background"]:
            tpf.extract_aperture_photometry(aperture_mask=mask)
        if np.any(tpf.pipeline_mask):
            tpf.extract_aperture_photometry(aperture_mask="pipeline")
        else:
            with pytest.raises(ValueError):
                tpf.extract_aperture_photometry(aperture_mask="pipeline")
def test_get_models():
    """Can we obtain PRF and TPF models?"""
    tpf = KeplerTargetPixelFile(filename_tpf_all_zeros, quality_bitmask=None)
    with warnings.catch_warnings():
        # Ignore "RuntimeWarning: All-NaN slice encountered"
        warnings.simplefilter("ignore", RuntimeWarning)
        tpf.get_model()
        tpf.get_prf_model()
def test_tpf_to_fits():
    """Can we write a TPF back to a fits file?"""
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tess),
    ]:
        # `delete=False` is necessary to enable writing to the file on Windows
        # but it means we have to clean up the tmp file ourselves
        tmp = tempfile.NamedTemporaryFile(delete=False)
        try:
            tpf.to_fits(tmp.name)
        finally:
            tmp.close()
            os.remove(tmp.name)
示例#23
0
def test_tpfcollection():
    tpf = KeplerTargetPixelFile(filename_tpf_all_zeros)
    tpf2 = KeplerTargetPixelFile(filename_tpf_one_center)
    tpfc = TargetPixelFileCollection([tpf, tpf2])
    assert len(tpfc) == 2
    assert tpfc.data == [tpf, tpf2]
    tpfc.append(tpf2)
    assert len(tpfc) == 3
    assert tpfc[0] == tpf
    assert tpfc[1] == tpf2
    assert tpfc[2] == tpf2
    with pytest.raises(IndexError):
        tpfc[51]
    # ensure index by boolean array also works for TPFs
    tpfc_f = tpfc[[False, True, True]]
    assert tpfc_f.data == [tpf2, tpf2]
    assert type(tpfc_f) is TargetPixelFileCollection
    # Test __setitem__
    tpf3 = KeplerTargetPixelFile(filename_tpf_one_center, targetid=55)
    tpfc[1] = tpf3
    assert tpfc[1] == tpf3
    tpfc.append(tpf2)
    assert tpfc[2] == tpf2
    str(tpfc)  # Regression test for #564
示例#24
0
def test_custom_aperture_mask():
    """Can we provide a custom lightcurve to show?"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [KeplerTargetPixelFile(filename_tpf_tabby_lite), TessTargetPixelFile(example_tpf)]
    import bokeh

    for tpf in tpfs:
        mask = tpf.flux[0, :, :] == tpf.flux[0, :, :]
        tpf.interact(aperture_mask=mask)
        mask = None
        tpf.interact(aperture_mask=mask)
        mask = "threshold"
        tpf.interact(aperture_mask=mask)
def test_to_lightcurve():
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tess),
    ]:
        tpf.to_lightcurve()
        tpf.to_lightcurve(aperture_mask=None)
        tpf.to_lightcurve(aperture_mask="all")
        lc = tpf.to_lightcurve(aperture_mask="threshold")
        assert lc.time.scale == "tdb"
        assert lc.label == tpf.hdu[0].header["OBJECT"]
        if np.any(tpf.pipeline_mask):
            tpf.to_lightcurve(aperture_mask="pipeline")
        else:
            with pytest.raises(ValueError):
                tpf.to_lightcurve(aperture_mask="pipeline")
def test_tpf_math():
    """Can you add, subtract, multiply and divide?"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [
            KeplerTargetPixelFile(filename_tpf_all_zeros),
            TessTargetPixelFile(filename_tpf_all_zeros),
        ]

        # These should work
        for tpf in tpfs:
            for other in [1, np.ones(tpf.flux.shape[1:]), np.ones(tpf.shape)]:
                tpf + other
                tpf - other
                tpf * other
                tpf / other

                tpf += other
                tpf -= other
                tpf *= other
                tpf /= other

        # These should fail with a value error because their shape is wrong.
        for tpf in tpfs:
            for other in [
                    np.asarray([1, 2]),
                    np.arange(len(tpf.time) - 1),
                    np.ones([100, 1]),
                    np.ones([1, 2, 3]),
            ]:
                with pytest.raises(ValueError):
                    tpf + other

        # Check the values are correct
        assert np.all(((tpf.flux.value +
                        2) == (tpf + 2).flux.value)[np.isfinite(tpf.flux)])
        assert np.all(((tpf.flux.value -
                        2) == (tpf - 2).flux.value)[np.isfinite(tpf.flux)])
        assert np.all(((tpf.flux.value *
                        2) == (tpf * 2).flux.value)[np.isfinite(tpf.flux)])
        assert np.all(((tpf.flux.value /
                        2) == (tpf / 2).flux.value)[np.isfinite(tpf.flux)])
        assert np.all(((tpf.flux_err.value *
                        2) == (tpf * 2).flux_err.value)[np.isfinite(tpf.flux)])
        assert np.all(((tpf.flux_err.value /
                        2) == (tpf / 2).flux_err.value)[np.isfinite(tpf.flux)])
def test_cutout():
    """Test tpf.cutout() function."""
    for tpf in [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tess, quality_bitmask=None),
    ]:
        ntpf = tpf.cutout(size=2)
        assert ntpf.flux[0].shape == (2, 2)
        assert ntpf.flux_err[0].shape == (2, 2)
        assert ntpf.flux_bkg[0].shape == (2, 2)
        ntpf = tpf.cutout((0, 0), size=3)
        ntpf = tpf.cutout(size=(1, 2))
        assert ntpf.flux.shape[1] == 2
        assert ntpf.flux.shape[2] == 1
        ntpf = tpf.cutout(SkyCoord(tpf.ra, tpf.dec, unit="deg"), size=2)
        ntpf = tpf.cutout(size=2)
        assert np.product(ntpf.flux.shape[1:]) == 4
        assert ntpf.targetid == "{}_CUTOUT".format(tpf.targetid)
示例#28
0
def test_custom_exported_filename():
    """Can we provide a custom lightcurve to show?"""
    import bokeh

    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [KeplerTargetPixelFile(filename_tpf_tabby_lite), TessTargetPixelFile(example_tpf)]
    for tpf in tpfs:
        tpf.interact(exported_filename="demo.fits")
        tpf[0:2].interact()
        tpf[0:2].interact(exported_filename="string_only")
        tpf[0:2].interact(exported_filename="demo2.FITS")
        tpf[0:2].interact(exported_filename="demo3.png")
        tpf[0:2].interact(exported_filename="")
        tpf.interact(exported_filename=210690913)
        mask = tpf.time == tpf.time
        tpf[mask].interact()
def test_tpf_ones(centroid_method):
    """Does the LightCurve of a one-flux TPF make sense?"""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tpf_one_center),
        ]
    for tpf in tpfs:
        lc = tpf.to_lightcurve(aperture_mask="all",
                               centroid_method=centroid_method)
        assert np.all(lc.flux.value == 1)
        assert np.all(
            (lc.centroid_col.value < tpf.column + tpf.shape[1]).all() *
            (lc.centroid_col.value > tpf.column).all())
        assert np.all((lc.centroid_row.value < tpf.row + tpf.shape[2]).all() *
                      (lc.centroid_row.value > tpf.row).all())
def test_tpf_ones(centroid_method):
    """Does the LightCurve of a one-flux TPF make sense? Regression test for #1103."""
    with warnings.catch_warnings():
        # Ignore the "TELESCOP is not equal to TESS" warning
        warnings.simplefilter("ignore", LightkurveWarning)
        tpfs = [
            KeplerTargetPixelFile(filename_tpf_one_center),
            TessTargetPixelFile(filename_tpf_one_center),
        ]
    for tpf in tpfs:
        lc = tpf.to_lightcurve(aperture_mask="all",
                               centroid_method=centroid_method)
        assert np.all(lc.flux.value == 1)
        # The test TPF file contains 3x3 pixels with a single bright pixel in the center pixel.
        # Because pixel coordinates refer to the center of a pixel (cf. #755),
        # we expect the centroid to be exactly one larger than the corner coordinates.
        # This is a regression test for #1103.
        assert np.all(lc.centroid_row.value == tpf.row + 1)
        assert np.all(lc.centroid_col.value == tpf.column + 1)