Source code for lightkurve.correctors.corrector

"""Implements the abstract `Corrector` base class.
"""
from abc import ABC, abstractmethod

import matplotlib
import numpy as np

from .. import LightCurve
from .metrics import overfit_metric_lombscargle, underfit_metric_neighbors


[docs]class Corrector(ABC): """Abstract base class documenting the required structure of classes designed to remove systematic noise from light curves. Attributes ---------- original_lc : LightCurve The uncorrected light curve. Must be passed into (or computed by) the constructor method. corrected_lc : LightCurve Corrected light curve. Must be updated upon each call to the `correct()` method. cadence_mask : np.array of dtype=bool Boolean array with the same length as `original_lc`. True indicates that a cadence should be used to fit the noise model. By setting certain cadences to False, users can exclude those cadences from informing the noise model, which will help prevent the overfitting of those signals (e.g. exoplanet transits). By default, the cadence mask is True across all cadences. Methods ------- __init__() Accepts all the data required to execute the correction. The constructor must set the `original_lc` attribute. correct() -> LightCurve Executes the correction, optionally accepting meaningful parameters that can be used to modify the way the correction is applied. This method must set or update the `corrected_lc` attribute on each run. diagnose() -> matplotlib.axes.Axes Creates plots to elucidate the user's most recent call to `correct()`. """ @property def original_lc(self) -> LightCurve: if hasattr(self, "_original_lc"): return self._original_lc else: raise AttributeError("`original_lc` has not been instantiated yet.") @original_lc.setter def original_lc(self, original_lc): self._original_lc = original_lc @property def corrected_lc(self) -> LightCurve: if hasattr(self, "_corrected_lc"): return self._corrected_lc else: raise AttributeError( "You need to call the `correct()` method " "before you can access `corrected_lc`." ) @corrected_lc.setter def corrected_lc(self, corrected_lc): self._corrected_lc = corrected_lc @property def cadence_mask(self) -> np.array: if not hasattr(self, "_cadence_mask"): self._cadence_mask = np.ones(len(self.original_lc), dtype=bool) return self._cadence_mask @cadence_mask.setter def cadence_mask(self, cadence_mask): self._cadence_mask = cadence_mask
[docs] def __init__(self, original_lc: LightCurve) -> None: """Constructor method. The constructor shall: * accept all data required to run the correction (e.g. light curves, target pixel files, engineering data). * instantiate the `original_lc` property. """ self.original_lc = original_lc
[docs] @abstractmethod def correct( self, cadence_mask: np.array = None, optimize: bool = False ) -> LightCurve: """Returns a `LightCurve` from which systematic noise has been removed. This method shall: * accept meaningful parameters that can be used to tune the correction, including: * `optimize`: should an optimizer be used to tune the parameters? * `cadence_mask`: flags cadences to be used to fit the noise model. * store all parameters as object attributes (e.g. `self.optimize`, `self.cadence_mask`); * store helpful diagnostic information as object attributes; * store the result in the `self.corrected_lc` attribute; * return `self.corrected_lc`. """ if cadence_mask: self.cadence_mask = cadence_mask
# ... perform correction ... # self.corrected_lc = corrected_lc # return corrected_lc
[docs] @abstractmethod def diagnose(self) -> matplotlib.axes.Axes: """Returns plots which elucidate the most recent call to `correct()`. This method shall plot useful diagnostic information which have been stored as object attributes during the most recent call to `correct()`. """ pass
def compute_overfit_metric(self, **kwargs) -> float: """Measures the degree of over-fitting in the correction. See the docstring of `lightkurve.correctors.metrics.overfit_metric_lombscargle` for details. Returns ------- overfit_metric : float A float in the range [0,1] where 0 => Bad, 1 => Good """ return overfit_metric_lombscargle( # Ignore masked cadences in the computation self.original_lc[self.cadence_mask], self.corrected_lc[self.cadence_mask], **kwargs ) def compute_underfit_metric(self, **kwargs) -> float: """Measures the degree of under-fitting the correction. See the docstring of `lightkurve.correctors.metrics.underfit_metric_neighbors` for details. Returns ------- underfit_metric : float A float in the range [0,1] where 0 => Bad, 1 => Good """ return underfit_metric_neighbors(self.corrected_lc[self.cadence_mask], **kwargs)