Feature extractors: basics¶
This tutorial introduces the light_curve feature extractor interface: creating features, combining them with Extractor, reading names and descriptions, and batch processing.
Setup¶
We create a synthetic sinusoidal light curve with Gaussian noise:
In [ ]:
Copied!
import light_curve as lc
import numpy as np
rng = np.random.default_rng(42)
t = np.sort(rng.uniform(0, 100, 200))
m = 15.0 + 0.3 * np.sin(2 * np.pi * t / 20) + rng.normal(0, 0.05, 200)
err = np.full(200, 0.05)
print(f'Observations: {len(t)}')
print(f'Time range: {t[0]:.1f} – {t[-1]:.1f} days')
print(f'Mag range: {m.min():.2f} – {m.max():.2f}')
import light_curve as lc
import numpy as np
rng = np.random.default_rng(42)
t = np.sort(rng.uniform(0, 100, 200))
m = 15.0 + 0.3 * np.sin(2 * np.pi * t / 20) + rng.normal(0, 0.05, 200)
err = np.full(200, 0.05)
print(f'Observations: {len(t)}')
print(f'Time range: {t[0]:.1f} – {t[-1]:.1f} days')
print(f'Mag range: {m.min():.2f} – {m.max():.2f}')
Observations: 200 Time range: 0.7 – 99.2 days Mag range: 14.60 – 15.41
Single feature¶
Each feature class is callable. It accepts (t, m, sigma) arrays and returns a NumPy array.
The .names attribute lists the output column names:
In [ ]:
Copied!
amp = lc.Amplitude()
result = amp(t, m, err)
print(f'names: {amp.names}')
print(f'result: {result}')
amp = lc.Amplitude()
result = amp(t, m, err)
print(f'names: {amp.names}')
print(f'result: {result}')
Traceback (most recent call last):
File "<string>", line 1, in <module>
import sys; sys.path.insert(0, '/workdir/light-curve-python/light-curve'); amp = lc.Amplitude()
^^
NameError: name 'lc' is not defined
.descriptions gives a human-readable explanation of each output:
In [ ]:
Copied!
print(amp.descriptions)
print(amp.descriptions)
Traceback (most recent call last):
File "<string>", line 1, in <module>
import sys; sys.path.insert(0, '/workdir/light-curve-python/light-curve'); print(amp.descriptions)
^^^
NameError: name 'amp' is not defined
Combining features with Extractor¶
Extractor combines multiple features into a single callable evaluated in one pass:
In [ ]:
Copied!
ext = lc.Extractor(
lc.Amplitude(),
lc.BeyondNStd(nstd=1),
lc.BeyondNStd(nstd=2),
lc.StandardDeviation(),
lc.WeightedMean(),
lc.LinearFit(),
lc.StetsonK(),
)
result = ext(t, m, err)
for name, value in zip(ext.names, result):
print(f' {name:35s} = {value:.5f}')
ext = lc.Extractor(
lc.Amplitude(),
lc.BeyondNStd(nstd=1),
lc.BeyondNStd(nstd=2),
lc.StandardDeviation(),
lc.WeightedMean(),
lc.LinearFit(),
lc.StetsonK(),
)
result = ext(t, m, err)
for name, value in zip(ext.names, result):
print(f' {name:35s} = {value:.5f}')
Traceback (most recent call last):
File "<string>", line 1, in <module>
import sys; sys.path.insert(0, '/workdir/light-curve-python/light-curve'); ext = lc.Extractor(
^^
NameError: name 'lc' is not defined
Batch processing with .many()¶
.many() processes a list of (t, m, sigma) tuples in parallel with reduced Python–Rust call overhead — the preferred path for large datasets:
In [ ]:
Copied!
n_lc = 5000
light_curves = [
(
np.sort(rng.uniform(0, 100, rng.integers(50, 200))),
15.0 + rng.normal(0, 0.2, rng.integers(50, 200)),
np.full(rng.integers(50, 200), 0.05),
)
for _ in range(n_lc)
]
# Batch extraction — one call for all light curves
results = lc.Amplitude().many(light_curves)
print(f'Extracted from {n_lc} light curves: shape = {results.shape}')
print(f'Mean amplitude = {results.mean():.4f} mag')
n_lc = 5000
light_curves = [
(
np.sort(rng.uniform(0, 100, rng.integers(50, 200))),
15.0 + rng.normal(0, 0.2, rng.integers(50, 200)),
np.full(rng.integers(50, 200), 0.05),
)
for _ in range(n_lc)
]
# Batch extraction — one call for all light curves
results = lc.Amplitude().many(light_curves)
print(f'Extracted from {n_lc} light curves: shape = {results.shape}')
print(f'Mean amplitude = {results.mean():.4f} mag')
Traceback (most recent call last):
File "<string>", line 4, in <module>
np.sort(rng.uniform(0, 100, rng.integers(50, 200))),
^^
NameError: name 'np' is not defined
Next steps¶
- Feature table — all 40+ extractors grouped by category
- API reference — full signatures and equations
- Periodogram tutorial — Lomb–Scargle and period search