Batch Workflows with TestGroup
TestGroup holds labelled collections of objects (GOOD / BAD / ANY) so
you can clean, analyse, and visualise many stars with one call instead
of a manual loop.
from varistar import TimeSeries, LightCurve, TestGroup
from _synthetic import make_sinusoidal_lightcurve
lightcurves = []
for i, seed in enumerate([1, 2, 3, 4, 5, 6]):
df = make_sinusoidal_lightcurve(period=2.0 + 0.3 * i, seed=seed)
ts = TimeSeries(magnitude="mag I", time_scale="HJD")
ts.load_data_from_df(df, data_id=f"star_{i:03d}")
ts.clean_by_error(max_error=0.05)
lightcurves.append(LightCurve(ts))
group = TestGroup(good_ts=lightcurves[:4], bad_ts=lightcurves[4:], name="synthetic_sample")
group.summary()
[clean_by_error] Removed 0 points (err > 0.05).
[clean_by_error] Removed 0 points (err > 0.05).
[clean_by_error] Removed 0 points (err > 0.05).
[clean_by_error] Removed 0 points (err > 0.05).
[clean_by_error] Removed 0 points (err > 0.05).
[clean_by_error] Removed 0 points (err > 0.05).
TestGroup 'synthetic_sample' | GOOD: 4 BAD: 2 ANY/LC: 0 (total: 6)
Bulk period-finding
apply() calls an unbound method on every registered object.
find_best_period also fills in is_harmonic, which we’ll use below:
group.apply(LightCurve.find_best_period)
Mosaic view
group.plot_mosaic(LightCurve.plot_phased, n_cols=3, fit_model="fourier")

Filtering and export
short_period = group.filter_by("periods", lambda p: p[0] < 3.0, target="any")
short_period.summary()
TestGroup 'synthetic_sample[filtered]' | GOOD: 0 BAD: 0 ANY/LC: 4 (total: 4)
group.export_periods()
shape: (6, 4)
| timeseries_id | best_period | n_candidates | status |
|---|---|---|---|
| str | f64 | i64 | str |
| "unknown" | 1.998568 | 20 | "GOOD" |
| "unknown" | 2.299374 | 20 | "GOOD" |
| "unknown" | 2.598417 | 20 | "GOOD" |
| "unknown" | 2.899632 | 20 | "GOOD" |
| "unknown" | 3.19618 | 20 | "BAD" |
| "unknown" | 3.504806 | 20 | "BAD" |
Next: ML Feature Pipeline.