Variability & Eclipsing-Binary Classification

Variability indices

classify.variability computes a set of scalar indices used to separate noise from genuine variability — Stetson J/K, IQR, η, amplitude, and more.

from varistar import TimeSeries, LightCurve
from varistar.classify.variability import compute_all_indices
from _synthetic import make_sinusoidal_lightcurve, make_eclipsing_lightcurve

ts_sine = TimeSeries(magnitude="mag I", time_scale="HJD")
ts_sine.load_data_from_df(make_sinusoidal_lightcurve(), data_id="sine_variable")
compute_all_indices(ts_sine)
{'timeseries_id': 'sine_variable',
 'stetson_j': 5.958540106396799,
 'stetson_k': np.float64(0.9003712508415409),
 'eta': 0.4788011773969887,
 'iqr': 0.35810762758015,
 'amplitude': 0.5006500664303033,
 'excess_variance': 0.00014169585360886917}
ts_eb = TimeSeries(magnitude="mag I", time_scale="HJD")
ts_eb.load_data_from_df(make_eclipsing_lightcurve(), data_id="eb_variable")
compute_all_indices(ts_eb)
{'timeseries_id': 'eb_variable',
 'stetson_j': 5.899520975676685,
 'stetson_k': np.float64(0.7535751337326829),
 'eta': 0.5827540774162198,
 'iqr': 0.14695971044955947,
 'amplitude': 0.5477358401404242,
 'excess_variance': 0.00012528997982817376}

Eclipsing-binary detection

score_eb phase-folds at a given period, fits a Fourier series, and checks whether the residual pattern looks like a sharp eclipse Fourier can’t model well:

from varistar.classify.eb_detector import score_eb, classify_eb_type
from varistar.models.gaussian import fit_double_super_gaussian

lc_eb = LightCurve(ts_eb)
lc_eb.run_ls()
best_period = lc_eb.periods[0]

is_eb, mea, _ = score_eb(lc_eb, period=best_period)
is_eb, mea
[score_eb] Possible EB: eb_variable | ρ_dip=62.40  ρ_global=457.00

(True, 0.04769237898416927)

Morphology: detached, semi-detached, or contact

Once a light curve is flagged as an EB, classify_eb_type reads the shape parameter of a fitted Double Super-Gaussian to name the eclipse morphology:

t = ts_eb.timeseries_df[ts_eb.time_col].to_numpy()
y = ts_eb.timeseries_df[ts_eb.mag_col].to_numpy()
phase = ((t - t.min()) / best_period) % 1.0

popt, mea_gauss = fit_double_super_gaussian(phase, y)
classify_eb_type(popt)
'contact'

Next: Batch Workflows.