Source code for exovetter.odd_even

"""Simple average-based odd/even vetter."""
import numpy as np
from exovetter.transit_coverage import compute_phases

__all__ = ['calc_odd_even', 'calc_ratio_significance',
           'calc_diff_significance', 'avg_odd_even']


[docs] def calc_odd_even(time, flux, period, epoch, duration, ingress=None, dur_frac=0.5): """Simple odd/even vetter. Parameters ---------- time : array Times. flux : array Relative flux normalized to 1. period : float Period in the same unit as time. epoch : float Time of transit in same units as time. duration : float Duration of transit in same units as time. ingress : float, optional Ingress time in the same units as time. **This keyword is currently unused.** dur_frac : float, optional Fraction of in-transit duration to use for calculation Returns ------- sigma : float Significance that the difference is not zero. odd_depth : float Odd depth. even_depth : float Even depth. """ offset = 0.25 twicephase = compute_phases(time, 2 * period, epoch, offset=offset) dur_phase = duration / period odd_depth, even_depth = avg_odd_even( twicephase, flux, dur_phase, frac=dur_frac, event_phase=offset) diff, error, sigma = calc_diff_significance(odd_depth, even_depth) return sigma, odd_depth, even_depth
def diagnostic_plot(time, flux, period, epoch, duration, odd_depth, even_depth): # pragma: no cover """ Parameters ---------- time : array Time aray flux : array Array of detrended flux period : float period in units of time epoch : float time of transit in units of time duration : float duration of transit in units of time, used for length of red lines odd_depth : float odd depth in units of flux even_depth : float even depth in units of flux """ import matplotlib.pyplot as plt # TODO ylim=depth +- 4*scatter of out of transit points offset = 0.25 twicephase = compute_phases(time, 2 * period, epoch, offset=offset) dur_phase = duration / (2 * period) half_durphase = dur_phase / 2 wf = 5 # plotting width fraction w = 2 # line width if np.isnan(odd_depth[1]): odd_depth[1] = 0 if np.isnan(even_depth[1]): even_depth[1] = 0 plt.figure(figsize=(8, 5)) ax1 = plt.subplot(121) plt.plot(twicephase, flux, 'b.', ms=3) plt.hlines(odd_depth[0] + odd_depth[1], 0.25 - half_durphase, 0.25 + half_durphase, linestyles='dashed', colors='r', lw=w, label='1 sigma', zorder=10) plt.hlines(odd_depth[0] - odd_depth[1], 0.25 - half_durphase, 0.25 + half_durphase, linestyles='dashed', colors='r', lw=w, zorder=10) plt.legend(loc="upper left") plt.xlim(0.25 - wf * dur_phase, 0.25 + wf * dur_phase) plt.xlabel('odd transit (phase)') plt.title(f'Depth:{odd_depth[0]:.2f} +- {odd_depth[1]:.2f}', fontsize=10) plt.subplot(122, sharey=ax1) plt.plot(twicephase, flux, 'b.', ms=3) plt.hlines(even_depth[0] + even_depth[1], 0.75 - half_durphase, 0.75 + half_durphase, linestyles='dashed', colors='r', label="1 sigma", lw=w, zorder=10) plt.hlines(even_depth[0] - even_depth[1], 0.75 - half_durphase, 0.75 + half_durphase, linestyles='dashed', colors='r', lw=w, zorder=10) plt.legend(loc="upper left") plt.xlim(0.75 - wf * dur_phase, 0.75 + wf * dur_phase) plt.xlabel('even transit (phase)') plt.title(f'Depth:{even_depth[0]:.2f} +- {even_depth[1]:.2f}', fontsize=10)
[docs] def calc_ratio_significance(odd, even): """Calculate ratio significance between odd and even. Parameters ---------- odd, even : float Returns ------- ratio : float Ratio of odd to even. sigma : float Significance that the ratio is not 1. """ error_ratio = ((odd[0] / even[0]) * np.sqrt((odd[1] / odd[0])**2 + (even[1] / even[0])**2)) ratio = odd[0] / even[0] sigma = (ratio - 1) / error_ratio return ratio, sigma
[docs] def calc_diff_significance(odd, even): """Calculate difference significance between odd and even. Parameters ---------- odd, even : float Returns ------- diff : float Difference of ``odd - even``. error : float Uncertainty of the difference. sigma : float Significance that the difference is not zero. """ diff = np.abs(odd[0] - even[0]) error = np.sqrt(odd[1]**2 + even[1]**2) if error != 0: sigma = diff / error else: sigma = np.nan return diff, error, sigma
[docs] def avg_odd_even(phases, flux, duration, event_phase=0.25, frac=0.5): """Simple average-based odd/even vetter. This takes the phases when it is folded at twice the acutal period. The odds are considered to be at ``event_phase``, evens are at ``event_phase + 0.5``. Parameters ---------- phases : array Phases when folding at 2x the period, zeroed at the transit epoch flux : array Relative flux of the light curve. duration : float Duration of the transit in same units as phases. event_phase : float Phase of the odd transit. frac : float Fraction of the in-transit duration to use. Returns ------- odd_depth : tuple of float Depth and error of the odd transit. even_depth : tuple of float Depth and error of the even transit. """ outof_transit_phase = 0.25 # likely phase for out of transit outof_transit_upper = event_phase + outof_transit_phase + duration * frac outof_transit_lower = event_phase + outof_transit_phase - duration * frac outof_transit_flux = flux[(phases > outof_transit_lower) & (phases <= outof_transit_upper)] x = frac * 0.5 * duration odd_lower = event_phase - x odd_upper = event_phase + x even_lower = odd_lower + 0.5 even_upper = odd_upper + 0.5 even_transit_flux = flux[(phases > even_lower) & (phases < even_upper)] odd_transit_flux = flux[(phases > odd_lower) & (phases < odd_upper)] if (len(even_transit_flux) > 1) & (len(odd_transit_flux) > 1): avg_even = np.median(even_transit_flux) avg_odd = np.median(odd_transit_flux) if len(outof_transit_flux) > 1: err_even = np.std(outof_transit_flux) err_odd = err_even else: err_even = np.nan err_odd = np.nan even_depth = [np.abs(avg_even), err_even] odd_depth = [np.abs(avg_odd), err_odd] else: even_depth = [1, 1] odd_depth = [1, 1] return odd_depth, even_depth