virgil.aliases
Orbits whose epochs undersample the period: the alias bands
N = round(T/P), a cheap position-level profile, and the band evidences
from the closure phases of every epoch, with per-epoch error scales
integrated out.
Orbits whose epochs undersample the period: alias bands and their evidences.
Provisional
May change in any 0.4.x release without a deprecation cycle.
When epochs are far apart compared with the period, the number of orbital
cycles between them is ambiguous, and the likelihood has one narrow ridge per
candidate count. fit_orbit_aliases labels
the ridges N = round(T/P) (T the span), fits each band of periods
directly to the observables of every epoch and weighs the bands by their
marginal likelihoods. Positions only start the fits. Each epoch's observable
blocks have an error scale with a Jeffreys prior, integrated out
(marginal_loglike); a band's evidence is the
sum over its modes of a Laplace approximation, checked by importance sampling.
Source: VanderPlas (2018), Lucy (2014), Price-Whelan et al. (2017), Jeffreys (1946), MacKay (1992).
AliasResult
dataclass
Result of fit_orbit_aliases.
save and
load keep it as JSON; scene,
residuals and chi2_per_night use the best band.
Attributes:
| Name | Type | Description |
|---|---|---|
t_ref, times, span |
(float, ndarray, float)
|
Reference time of |
bands |
list of AliasBandResult
|
One per alias band, by decreasing |
samples |
dict
|
|
positions |
list of dict or None
|
Per-band position diagnostic (not saved). |
primary_diam, vis_amp, p_range, prior, unseeded |
optional
|
The primary, the V^2 amplitude range, the period window (days), the prior ranges, and flagged nights that seeded nothing. |
period_bound, period_at_lower_bound |
bool
|
P is unconstrained (best P within 10% of the top of |
window_capped, primary_fit, temper_f, temper_blocks, temper_f_raw, temper_rho |
Lower end wanted when a default window was capped; the |
|
outlier, night_flags, short_arc |
dict or None
|
Outlier mixture ( |
t_ref
instance-attribute
times
instance-attribute
span
instance-attribute
bands
instance-attribute
samples
instance-attribute
positions = None
class-attribute
instance-attribute
primary_diam = None
class-attribute
instance-attribute
vis_amp = None
class-attribute
instance-attribute
unseeded = ()
class-attribute
instance-attribute
p_range = None
class-attribute
instance-attribute
period_bound = False
class-attribute
instance-attribute
primary_fit = None
class-attribute
instance-attribute
period_at_lower_bound = False
class-attribute
instance-attribute
window_capped = None
class-attribute
instance-attribute
temper_f = None
class-attribute
instance-attribute
temper_blocks = None
class-attribute
instance-attribute
temper_f_raw = None
class-attribute
instance-attribute
temper_rho = None
class-attribute
instance-attribute
prior = None
class-attribute
instance-attribute
short_arc = None
class-attribute
instance-attribute
outlier = None
class-attribute
instance-attribute
night_flags = None
class-attribute
instance-attribute
tempering
property
Whether the tempering is outside what the likelihood can trust:
a block f above 2, a raw f below 0.5, or a flat (not
AR(1)) correlation in temper_rho. False without a factor.
Returns:
| Type | Description |
|---|---|
bool
|
|
best
property
The band with the highest evidence.
labels_free
property
Whether the stars' labels are not determined by the data: in the
best band, a mode that is the point reflection of the best mode
has an evidence within LABELS_FREE_NATS (3 nats) of it. A
comparison with another orbit may then accept the reflection
(ω + 180°, Ω unchanged).
__init__(t_ref, times, span, bands, samples, positions=None, primary_diam=None, vis_amp=None, unseeded=(), p_range=None, period_bound=False, primary_fit=None, period_at_lower_bound=False, window_capped=None, temper_f=None, temper_blocks=None, temper_f_raw=None, temper_rho=None, prior=None, short_arc=None, outlier=None, night_flags=None)
__post_init__()
block_dof()
The block-keyed dof ({block: 1/f_b}) that reproduces
this fit's tempering in marginal_loglike(block_dof=).
Returns:
| Type | Description |
|---|---|
dict
|
Empty when no factor was applied. |
table()
One row per band: raw χ²/ν, error scales (scales flat over
epochs and blocks; epoch_scales one list per epoch), log Z
(Laplace and IS), p, ESS and the flags.
scene(params=None)
The best band's fitted scene; see
AliasBandResult.scene.
residuals(data, params=None)
Whitened residuals at the best band's best orbit; see
AliasBandResult.residuals.
chi2_per_night(data, params=None)
Raw χ² and N per night at the best band's best orbit; see
AliasBandResult.chi2_per_night.
to_json(path, n_samples=0)
Write the band table and each band's modes to path as JSON.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
The file to write. |
required |
n_samples
|
int or None
|
Posterior draws written per band: none by default, the first
|
0
|
Notes
load reads the file back.
positions is not written.
save(path)
Write the whole result to path as JSON, every posterior draw
included; load is its inverse.
Non-finite numbers are written as null (strict JSON) and restored
on loading. The positions diagnostic is not written.
load(path, primary_diam=UNRECORDED, vis_amp=UNRECORDED)
classmethod
Read a result written by save or
to_json.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
The JSON file. |
required |
primary_diam
|
optional
|
Settings for a file written before they were saved (else the accessors raise); they override a file that records them. |
UNRECORDED
|
vis_amp
|
optional
|
Settings for a file written before they were saved (else the accessors raise); they override a file that records them. |
UNRECORDED
|
Returns:
| Type | Description |
|---|---|
AliasResult
|
|
AliasBandResult
dataclass
The fit of one alias band (see AliasResult).
A band from a legacy file lacking t_ref, primary_diam or vis_amp
has UNRECORDED, and scene, residuals and chi2_per_night raise
unless AliasResult.load was given them.
Attributes:
| Name | Type | Description |
|---|---|---|
t_ref |
float or None
|
Reference time (MJD) of |
primary_diam |
float, ``"fit"`` or None
|
A point (None), a uniform disk (mas), or one fitted ( |
vis_amp |
tuple or None
|
Range of the per-epoch V^2 amplitude if fitted. |
flipped, labels_free |
bool
|
The best mode has the stars' labels swapped; a point-reflected partner is
within |
n
instance-attribute
p_lo
instance-attribute
p_hi
instance-attribute
modes
instance-attribute
log_z
instance-attribute
log_z_is
instance-attribute
ess
instance-attribute
flagged
instance-attribute
flags = dataclasses.field(default_factory=list)
class-attribute
instance-attribute
p = float('nan')
class-attribute
instance-attribute
best = dataclasses.field(default_factory=dict)
class-attribute
instance-attribute
chi2_red = float('nan')
class-attribute
instance-attribute
epochs = dataclasses.field(default_factory=list)
class-attribute
instance-attribute
flipped = False
class-attribute
instance-attribute
labels_free = False
class-attribute
instance-attribute
error = ''
class-attribute
instance-attribute
n_starts_failed = 0
class-attribute
instance-attribute
t_ref = None
class-attribute
instance-attribute
primary_diam = None
class-attribute
instance-attribute
vis_amp = None
class-attribute
instance-attribute
__init__(n, p_lo, p_hi, modes, log_z, log_z_is, ess, flagged, flags=list(), p=float('nan'), best=dict(), chi2_red=float('nan'), epochs=list(), flipped=False, labels_free=False, error='', n_starts_failed=0, t_ref=None, primary_diam=None, vis_amp=None)
scene(params=None)
The scene the band was fitted with, at its best orbit.
Built from best (or params) as the fit's likelihood builds it;
the swapped scene if flipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
dict
|
Elements to use instead of |
None
|
Returns:
| Type | Description |
|---|---|
OrbitalBinary
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the band failed, has no |
residuals(data, params=None)
Whitened residuals of data at the best orbit, block by block.
The fit's own residuals on the quoted errors (float64, V^2 amplitude re-profiled), from virgil's model: they check the bookkeeping, not the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
sequence of OIData
|
The epochs the band was fitted to, in order. |
required |
params
|
dict
|
Elements to use instead of |
None
|
Returns:
| Type | Description |
|---|---|
list of dict
|
One |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
chi2_per_night(data, params=None)
Raw chi-squared and its count of independent observables, per night.
On the quoted errors, at the best orbit. chi2 counts only the n
independent observables; chi2_fit adds the fit's penalty rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
sequence of OIData
|
The epochs the band was fitted to, in order. |
required |
params
|
dict
|
Elements to use instead of |
None
|
Returns:
| Type | Description |
|---|---|
list of dict
|
Per epoch: |
Raises:
| Type | Description |
|---|---|
ValueError
|
As for |
AliasBand
dataclass
One period band, N = round(T/P): p_lo <= P <= p_hi (days).
n
instance-attribute
p_lo
instance-attribute
p_hi
instance-attribute
__init__(n, p_lo, p_hi)
fit_orbit_aliases(data, p_range=None, *, positions=None, times=None, t_ref=None, a_range=(1.0, 30.0), flux_range=(0.01, 1.0), ecc_max=0.9, s_max=None, n_candidates=100, n_refine=6, n_random=None, k=9.0, eccs=None, sign_free=True, min_distance_mas=0.5, max_steps=200, n_is=2000, n_samples=1000, p_min_samples=0.01, flag_nats=1.0, ess_min=50.0, seed=0, checkpoint_dir=None, on_band=None, primary_diam='auto', diam_range=None, vis_amp=True, flip_flux=True, init=None, skip_flagged=True, n_bands_max=_N_BANDS_MAX, temper=True, batch_size=None, memory_budget=None, short_arcs=True, arc_jitter=ARC_JITTER, arc_delta_chi2=ARC_DELTA_CHI2, arc_min_gap=ARC_MIN_GAP, outlier_eps=0.0)
Weigh the period aliases of an undersampled orbit with the observables.
Each alias band (an integer number of orbits between the epochs) is fitted to all epochs and given an evidence; the defaults need no per-system arguments (how, settings).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
sequence of OIData
|
One dataset per epoch. |
required |
p_range
|
(float, float)
|
Period range (days); default |
None
|
positions
|
PositionData or EpochPositions
|
Seeds for the fits (else random orbits). |
None
|
times
|
optional
|
Epoch times and |
None
|
t_ref
|
optional
|
Epoch times and |
None
|
a_range
|
optional
|
Epoch times and |
None
|
flux_range
|
optional
|
Epoch times and |
None
|
ecc_max
|
optional
|
Epoch times and |
None
|
s_max
|
optional
|
Epoch times and |
None
|
n_candidates
|
optional
|
Search effort, sampling and a warm start. |
100
|
n_refine
|
optional
|
Search effort, sampling and a warm start. |
100
|
n_random
|
optional
|
Search effort, sampling and a warm start. |
100
|
n_is
|
optional
|
Search effort, sampling and a warm start. |
100
|
n_samples
|
optional
|
Search effort, sampling and a warm start. |
100
|
seed
|
optional
|
Search effort, sampling and a warm start. |
100
|
init
|
optional
|
Search effort, sampling and a warm start. |
100
|
min_distance_mas
|
optional
|
Modes closer than |
0.5
|
max_steps
|
optional
|
Modes closer than |
0.5
|
p_min_samples
|
optional
|
Modes closer than |
0.5
|
flag_nats
|
optional
|
Modes closer than |
0.5
|
ess_min
|
optional
|
Modes closer than |
0.5
|
checkpoint_dir
|
optional
|
Bands finished in |
None
|
on_band
|
optional
|
Bands finished in |
None
|
primary_diam
|
optional
|
|
'auto'
|
diam_range
|
optional
|
|
'auto'
|
vis_amp
|
optional
|
Profiled V^2 amplitude; sign-free seeds; label-swapped refit at the flux ceiling; flagged nights seed nothing. |
True
|
sign_free
|
optional
|
Profiled V^2 amplitude; sign-free seeds; label-swapped refit at the flux ceiling; flagged nights seed nothing. |
True
|
flip_flux
|
optional
|
Profiled V^2 amplitude; sign-free seeds; label-swapped refit at the flux ceiling; flagged nights seed nothing. |
True
|
skip_flagged
|
optional
|
Profiled V^2 amplitude; sign-free seeds; label-swapped refit at the flux ceiling; flagged nights seed nothing. |
True
|
temper
|
bool or float
|
True estimates the evidence tempering (needs
|
True
|
outlier_eps
|
float
|
Outlier weight in [0, 1); default 0 (no mixture), unlike |
0.0
|
n_bands_max
|
optional
|
Band cap, grid density, seed eccentricities, batching. |
_N_BANDS_MAX
|
k
|
optional
|
Band cap, grid density, seed eccentricities, batching. |
_N_BANDS_MAX
|
eccs
|
optional
|
Band cap, grid density, seed eccentricities, batching. |
_N_BANDS_MAX
|
batch_size
|
optional
|
Band cap, grid density, seed eccentricities, batching. |
_N_BANDS_MAX
|
memory_budget
|
optional
|
Band cap, grid density, seed eccentricities, batching. |
_N_BANDS_MAX
|
short_arcs
|
optional
|
Fit only the bands the short arcs admit ( |
True
|
arc_jitter
|
optional
|
Fit only the bands the short arcs admit ( |
True
|
arc_delta_chi2
|
optional
|
Fit only the bands the short arcs admit ( |
True
|
arc_min_gap
|
optional
|
Fit only the bands the short arcs admit ( |
True
|
Returns:
| Type | Description |
|---|---|
AliasResult
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If every band fails (chained to the last error). |
ValueError
|
If no band lies in |
alias_bands(times, p_range)
The alias bands of the epochs within p_range.
Band N holds the periods T/(N + 1/2) <= P <= T/(N - 1/2) that
fit N cycles, rounded, between the first and last epoch (span T),
clipped to p_range. The bands are one cycle wide in frequency, so
they tile the period prior without gaps. Periods above 2T form band
N = 0: not an alias, but the part of the prior with less than one
cycle across the span.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
times
|
array - like
|
The epochs' times (days). |
required |
p_range
|
(float, float)
|
The shortest and longest period (days) to consider. |
required |
Returns:
| Type | Description |
|---|---|
list of AliasBand
|
Ordered by |
period_window(times, field, night_length, *, resolution, motion_fraction=0.5, span_factor=4.0, p_floor=_P_FLOOR)
The periods worth searching, from the data alone: (p_min, p_max).
The lower end is a Nyquist-style sampling limit (the companion must not move
much in a night); the upper end is span_factor times the span. No published
period enters (why).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
times
|
array - like
|
The epochs' times (days). |
required |
field
|
float
|
The largest companion separation (mas), the longest span within one night (days) and the finest resolution lambda/B_max (mas). |
required |
night_length
|
float
|
The largest companion separation (mas), the longest span within one night (days) and the finest resolution lambda/B_max (mas). |
required |
resolution
|
float
|
The largest companion separation (mas), the longest span within one night (days) and the finest resolution lambda/B_max (mas). |
required |
motion_fraction
|
float
|
Fraction of |
0.5
|
span_factor
|
float
|
Fraction of |
0.5
|
p_floor
|
float
|
Fraction of |
0.5
|
Returns:
| Type | Description |
|---|---|
(float, float)
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the epochs span no time, an input is not positive, or the window is empty. |
position_profile(positions, bands, k=9.0, n_best=3, eccs=None, sign_free=False)
A cheap diagnostic: the best position-level χ² in each band.
For each band, the best Thiele–Innes fits
(starting_orbits) of positions
on a coherent period grid. Positions are lossy: use this to see
which bands are viable and to seed the fits, not to weigh them.
With sign_free the orbits of the sign-free fit (each night's
position known only up to its sign) are added to those of the signed
fit: n_best of each.
Returns:
| Type | Description |
|---|---|
list of dict
|
Per band: |