virgil.epochs
Datasets grouped into named epochs, with one snapshot of a moving scene per dataset, for orbit fits to visibilities and closure phases across epochs, and the tools that start and sample those fits: ranking trial orbits by the data, choosing distinct starts for each chain, and starting from a fit of positions.
start_from_positions is superseded
For an orbit with an unknown period use
fit_orbit_aliases or
OrbitPipeline (see Orbits from interferometric
data). start_from_positions remains for starting a
fit of a model of your own from per-night positions.
Named epochs of data, with one snapshot of a moving scene per dataset.
Provisional
May change in any 0.4.x release without a deprecation cycle.
When nothing moves appreciably during an observation (a period much longer
than a night), one static snapshot of the scene per dataset replaces
OIData.model's evaluation at every sample's own
time, and is much cheaper. Epochs keys epochs and
datasets by name, so per-dataset nuisance terms stay attached to the right
data, and hands fit and
numpyro_model a model function, the
datasets and one noise dict per dataset.
Fringe aliases make the likelihood multimodal on the scale of λ/B, so an orbit fit needs a start in the right basin:
rank_orbits: trial orbits ranked by the likelihood of all the data;chain_starts: the best distinct orbits, one per chain;epoch_positions: the companion's position in each dataset;start_from_positions: the whole start (positions, starting orbits, ranking,fitfrom distinct orbits);OrbitStart.chain_valuesgives one start per chain forchain_init_params.
Epochs
Datasets grouped into named epochs, each seen as one snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
epochs
|
dict
|
|
required |
at
|
(dataset, epoch)
|
Snapshot at the mean time of each dataset's samples (default) or of the whole epoch. |
"dataset"
|
times
|
dict
|
|
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
names, dataset_names, epoch_of |
tuple of str
|
The epochs, the datasets (epoch by epoch), and each dataset's epoch. |
data |
tuple of OIData
|
The datasets in |
times, spread_days |
ndarray
|
Snapshot time (MJD) of each dataset, and the largest distance of its samples from it (days); the scene should move far less than the resolution over it. |
names = tuple(epochs)
instance-attribute
dataset_names = tuple(names)
instance-attribute
epoch_of = tuple(epoch_of)
instance-attribute
data = tuple(data)
instance-attribute
at = at
instance-attribute
resolution_mas
property
The finest resolution λ/B_max over the datasets (mas).
Only unflagged samples count (see
OIData.unflagged).
Fringe aliases of a companion's position are spaced by about this much, so starting orbits closer together than a fraction of it are one mode.
__init__(epochs, at='dataset', times=None)
__len__()
__repr__()
index(name)
The position of dataset name in data (and in noise).
Fitted per-dataset noise terms are the sites
"noise[<index>].<term>" of fit and numpyro_model.
snapshots(scene)
The scene at each dataset's snapshot time, one model per dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scene
|
SourceModel or sequence of SourceModel
|
One scene for all datasets, or one per dataset (e.g. with per-dataset fluxes). A static scene is its own snapshot. |
required |
Returns:
| Type | Description |
|---|---|
list of SourceModel
|
Static models, in the order of |
model_fn(scene_fn)
A model function for fit/numpyro_model: the snapshots of
scene_fn(**values), one per dataset.
noise(terms)
One noise dict per dataset, from terms keyed by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
terms
|
dict
|
|
required |
Returns:
| Type | Description |
|---|---|
list of dict
|
In the order of |
loglike(scene, noise=None)
The log likelihood of all the data, one snapshot per dataset.
The sum over datasets of
model_loglike of each
snapshot, with noise (values, keyed by name as for
:meth:noise) applied to each dataset. Traceable: it can be
jitted, differentiated or vmapped in the scene's parameters.
RankedOrbits
dataclass
Orbits ranked by the log likelihood of multi-epoch data, best first.
Returned by rank_orbits and
chain_starts. Iterating gives
(orbit, loglike) pairs, like the (orbit, χ²) pairs of
starting_orbits, and
ranked[k] is the k-th pair.
Attributes:
| Name | Type | Description |
|---|---|---|
orbits |
tuple
|
The orbits, best first. |
loglike |
ndarray
|
The log likelihood of all the data for each orbit (with the
|
order |
ndarray
|
The position of each orbit in the list that was ranked. |
times |
ndarray
|
The snapshot times of the datasets (MJD), at which
:meth: |
resolution_mas |
float
|
The finest resolution λ/B_max of the data (mas). |
orbits
instance-attribute
loglike
instance-attribute
order
instance-attribute
times
instance-attribute
resolution_mas
instance-attribute
best
property
The orbit with the highest log likelihood.
__init__(orbits, loglike, order, times, resolution_mas)
__len__()
__getitem__(k)
__iter__()
positions()
The companion's position (dra, ddec) (mas) of each orbit at
each snapshot time, shape (n_orbits, n_times, 2).
PrimaryDiameter
dataclass
The primary's uniform-disk diameter, from
estimate_primary_diameter.
Attributes:
| Name | Type | Description |
|---|---|---|
diam |
float
|
Best diameter (mas); 0 when a point primary is as good. |
sigma |
float
|
1σ uncertainty (mas); NaN when the maximum is on the grid edge. |
delta_nats |
float
|
Gain in summed marginal score at |
resolved |
bool
|
|
at_grid_edge |
bool
|
The best diameter is the last grid point, so |
grid, profile |
ndarray
|
The diameters tried ( |
positions |
EpochPositions
|
The input positions, re-refined at |
diam
instance-attribute
sigma
instance-attribute
delta_nats
instance-attribute
resolved
instance-attribute
grid
instance-attribute
profile
instance-attribute
positions
instance-attribute
at_grid_edge = False
class-attribute
instance-attribute
__init__(diam, sigma, delta_nats, resolved, grid, profile, positions, at_grid_edge=False)
EpochPositions
dataclass
The companion's position in each dataset, from
epoch_positions.
Positions, covariances and gap_marginal come from the marginal
surface, so scaling the quoted errors leaves them unchanged.
Attributes:
| Name | Type | Description |
|---|---|---|
names |
tuple of str
|
The datasets. |
mjd |
ndarray
|
Snapshot time of each dataset (MJD). |
dra, ddec, cov |
ndarray
|
Positions (mas, East and North) and their covariance, |
flux |
ndarray
|
Fitted companion/primary flux (at most 1). |
gap_marginal |
ndarray
|
Best peak's score minus its best rival's more than |
chi2_raw, scale |
tuple of dict
|
Per dataset, χ²/N on the quoted errors per block and |
peaks |
tuple of EpochPeaks
|
Per dataset, the catalogue of its peaks. |
flags |
tuple of tuple of NightFlag
|
Per dataset, why its position should not seed an orbit (see |
primary_diam |
float or None
|
The uniform-disk primary the positions were fitted with (mas). |
grid |
optional
|
The search grid's axes; None if not from a grid. |
exact_fraction |
tuple of float or None
|
Fraction of grid points scored with the full scale integral (1 unless
the coarse pass skipped some; see |
names
instance-attribute
mjd
instance-attribute
dra
instance-attribute
ddec
instance-attribute
cov
instance-attribute
flux
instance-attribute
gap_marginal
instance-attribute
chi2_raw
instance-attribute
scale
instance-attribute
peaks = ()
class-attribute
instance-attribute
flags = ()
class-attribute
instance-attribute
primary_diam = None
class-attribute
instance-attribute
grid = None
class-attribute
instance-attribute
exact_fraction = None
class-attribute
instance-attribute
flagged
property
Whether each dataset carries a blocking flag (flags): a
flagged night seeds nothing in
fit_orbit_aliases, but its
data still count in the likelihood. Non-blocking flags (see
NightFlag.blocking) are reported by flag_codes only.
edge
property
Whether each dataset's best peak started at the edge of the
position grid (see EpochPeaks.edge).
__init__(names, mjd, dra, ddec, cov, flux, gap_marginal, chi2_raw, scale, peaks=(), flags=(), primary_diam=None, grid=None, exact_fraction=None)
flag_codes()
The flag codes of each dataset, {name: [code, ...]}, for
the datasets with any flag, blocking or not.
decisive(min_gap)
Whether each dataset's gap_marginal exceeds min_gap.
positions(*, t_ref, min_gap=None, skip_flagged=True)
The positions as PositionData,
for starting_orbits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t_ref
|
float
|
The reference time (MJD) of the orbits fitted to them: give
the |
required |
min_gap
|
float
|
Keep only the datasets whose |
None
|
skip_flagged
|
bool
|
Drop the flagged datasets ( |
True
|
EpochPeaks
dataclass
The catalogue of one dataset's peaks, from
epoch_positions, best first.
Attributes:
| Name | Type | Description |
|---|---|---|
dra, ddec, flux |
ndarray
|
Peak positions (mas, East and North) and fluxes, after refinement. |
loglike |
ndarray
|
Log likelihood of each peak on the quoted errors. |
marginal |
ndarray
|
Scale-marginalized score of each peak (the sort key). |
weight |
ndarray
|
Posterior mass of each peak in this dataset (sums to 1; Laplace
approximation, or the height exp(m) where |
edge |
ndarray
|
Peak started on the grid edge: a best peak there may stand for a companion outside the grid, so treat the dataset as ambiguous. |
laplace |
ndarray
|
Weight is a Laplace mass (false without |
dra
instance-attribute
ddec
instance-attribute
flux
instance-attribute
loglike
instance-attribute
marginal
instance-attribute
weight
instance-attribute
edge
instance-attribute
laplace
instance-attribute
__init__(dra, ddec, flux, loglike, marginal, weight, edge, laplace)
__len__()
NightFlag
dataclass
Why one night's position should not seed an orbit.
Attributes:
| Name | Type | Description |
|---|---|---|
code |
str
|
A short code: |
reason |
str
|
A human-readable reason with the numbers behind it. |
blocking |
bool
|
Whether the flag keeps the night from seeding an orbit (the default).
A non-blocking flag is reported only: the night still seeds and, as
always, counts in the likelihood. |
code
instance-attribute
reason
instance-attribute
blocking = True
class-attribute
instance-attribute
__init__(code, reason, blocking=True)
OrbitStart
dataclass
A start for a multi-epoch orbit fit, from
start_from_positions.
Attributes:
| Name | Type | Description |
|---|---|---|
positions |
EpochPositions
|
The per-dataset positions that seeded the orbits. |
candidates |
RankedOrbits
|
The starting orbits, ranked by the visibilities. |
fits |
tuple of FitResult
|
Fits from the distinct best candidates, lowest loss first (non-finite
last); |
data |
Epochs
|
The data. |
failed |
tuple of (int, str)
|
Candidates whose refinement raised, with the error. |
seeded, ambiguous |
tuple of str
|
Datasets whose positions seeded the orbits ( |
positions
instance-attribute
candidates
instance-attribute
fits
instance-attribute
data
instance-attribute
failed = ()
class-attribute
instance-attribute
seeded = ()
class-attribute
instance-attribute
ambiguous = ()
class-attribute
instance-attribute
best
property
The fit with the lowest loss.
__init__(positions, candidates, fits, data, failed=(), seeded=(), ambiguous=())
modes(*, max_delta_loss=10.0, same_mode_chi2=1.0)
The distinct fits, lowest loss first.
Two fits are one mode when their predictions differ by less than
same_mode_chi2 in χ² (the sum of squared differences of their
whitened residuals, with the quoted errors). Fits whose loss is
more than max_delta_loss above the best's are dropped: a
difference Δ in loss is a factor of about e^Δ in posterior
density. Fits with a non-finite loss are left out.
chain_values(n_chains, **options)
One start (fitted values) per chain, cycling through the
distinct modes (see :meth:modes, which takes options).
Pass them to
chain_init_params to
start each chain of numpyro's MCMC in its own mode.
rank_orbits(model, data, orbits, *, scales='marginal', noise=None, dof=1.0, s_max=None, batch_size=None, dtype='float64')
Rank trial orbits by the log likelihood of multi-epoch data.
Each orbit's scene is evaluated at every dataset's snapshot time, in one compiled kernel mapped over the orbits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
callable
|
|
required |
data
|
Epochs
|
The data, one snapshot per dataset. |
required |
orbits
|
sequence or orbit
|
Orbits, |
required |
scales
|
(marginal, quoted)
|
Marginalize the error scales ( |
"marginal"
|
noise
|
dict
|
Noise values by epoch or dataset name (conventions). |
None
|
dof
|
optional
|
As for |
1.0
|
s_max
|
optional
|
As for |
1.0
|
batch_size
|
int
|
Orbits evaluated together (default about a million model visibilities). |
None
|
dtype
|
(float64, float32)
|
Precision. |
"float64"
|
Returns:
| Type | Description |
|---|---|
RankedOrbits
|
Best first; a non-finite one ranks last. |
chain_starts(ranked, n_chains, *, min_distance_mas=None)
The best distinct orbits of a ranking, one per chain.
Two orbits are one mode when the companion's positions at every snapshot
time agree within min_distance_mas: the mirror orbit (Ω + 180°,
ω + 180°) is the same mode, a fringe or period alias is not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ranked
|
RankedOrbits
|
From |
required |
n_chains
|
int
|
Number of starts. |
required |
min_distance_mas
|
float
|
Largest position difference (mas) for one mode; default half the finest resolution λ/B_max. |
None
|
Returns:
| Type | Description |
|---|---|
RankedOrbits
|
|
epoch_positions(data, grid, *, gap_mas=None, refine=True, n_peaks=5, dof=1.0, s_max=None, batch_size=None, memory_budget=None, coarse_nats=30.0, coarse_margin=1, primary_diam=None, flag_nights=True, flag_alias_nats=2.0, flag_min_gap=5.0, flag_sep_fraction=0.5, flag_flux_tol=0.02, flag_sep_blocks=False)
The companion's position in each dataset of a binary.
Scores a static binary on a grid, refines the n_peaks best maxima and
ranks them; each night also gets flags
(tutorial).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Epochs
|
The data (gains, offsets and model-dependent covariances are refused). |
required |
grid
|
dict
|
|
required |
gap_mas
|
float
|
Distance (mas) beyond which a peak rivals the best (default: resolution). |
None
|
refine
|
optional
|
Refine grid peaks; peaks kept per dataset (1 can commit to the wrong
peak); as for |
True
|
n_peaks
|
optional
|
Refine grid peaks; peaks kept per dataset (1 can commit to the wrong
peak); as for |
True
|
dof
|
optional
|
Refine grid peaks; peaks kept per dataset (1 can commit to the wrong
peak); as for |
True
|
s_max
|
optional
|
Refine grid peaks; peaks kept per dataset (1 can commit to the wrong
peak); as for |
True
|
batch_size
|
optional
|
Speed knobs; the coarse ones limit the exact scale integral to the best points (None: everywhere). |
None
|
memory_budget
|
optional
|
Speed knobs; the coarse ones limit the exact scale integral to the best points (None: everywhere). |
None
|
coarse_nats
|
optional
|
Speed knobs; the coarse ones limit the exact scale integral to the best points (None: everywhere). |
None
|
coarse_margin
|
optional
|
Speed knobs; the coarse ones limit the exact scale integral to the best points (None: everywhere). |
None
|
primary_diam
|
float
|
Fixed uniform-disk primary diameter (mas); None or 0 is a point primary. Never the diameter implied by the orbit under test. |
None
|
flag_nights
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
flag_sep_blocks
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
flag_alias_nats
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
flag_min_gap
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
flag_sep_fraction
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
flag_flux_tol
|
optional
|
Night flags and thresholds (night flags);
None disables a numeric threshold; |
True
|
Returns:
| Type | Description |
|---|---|
EpochPositions
|
|
Warns:
| Type | Description |
|---|---|
UserWarning
|
If a best peak is on the grid edge, has raw chi-squared/N above 4, or did not converge. |
estimate_primary_diameter(data, positions, *, resolve_nats=RESOLVE_NATS, diam_grid=None, s_max=None, vis_amp=None, dof=1.0, block_dof=None)
Estimate a shared uniform-disk primary diameter and whether the data resolve it.
Each night's binary is re-refined over a diameter grid and the scores summed (rule).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Epochs or sequence of OIData
|
The datasets, in the order of |
required |
positions
|
EpochPositions
|
Per-night positions; flagged nights are left out unless all are. |
required |
resolve_nats
|
float
|
Gain (nats) over a point primary at which it counts as resolved (5). |
RESOLVE_NATS
|
diam_grid
|
array - like
|
Positive diameters (mas) to try besides 0. |
None
|
s_max
|
optional
|
As for |
None
|
dof
|
optional
|
As for |
None
|
block_dof
|
optional
|
As for |
None
|
vis_amp
|
(float, float)
|
Profile a V^2 amplitude per night in this range, so contrast loss is not read as a disk. |
None
|
Returns:
| Type | Description |
|---|---|
PrimaryDiameter
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Warns:
| Type | Description |
|---|---|
UserWarning
|
If the best diameter is the largest tried, or a refinement did not converge. |
marginal_loglike(model, data, *, dof=1.0, block_dof=None, s_max=None, **noise)
The log likelihood with each block's error scale marginalized.
Integrating each block's scale out under its Jeffreys prior gives, up to a
constant, m = -sum_b (nu_b/2) ln chi2_b. It is a search surface, not a
replacement for model_loglike
(derivation).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
SourceModel
|
Model to evaluate. |
required |
data
|
OIData
|
Data to compare with. Gains, closure-phase offsets and extra
observables with a model-dependent covariance raise
|
required |
dof
|
float
|
Effective degrees of freedom as a fraction of |
1.0
|
block_dof
|
dict
|
|
None
|
s_max
|
float
|
Bound each scale to |
None
|
**noise
|
Other noise terms; not |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
|
broad_loglike(data, dof, *, a_max, flux_range, step, s_max=None, primary_diam=None, batch_size=None, memory_budget=None, coarse_nats=30.0, coarse_margin=1, n_flux=_N_FLUX)
Each night's log mean likelihood over the orbit prior's companion
positions: the outlier component of
fit_orbit_aliases.
The positions are uniform on the disc |p| <= a_max and the flux is
log-uniform on flux_range. The scale-marginalized surface of
epoch_positions is scored as the orbit
is: pass the fit's block dof and s_max.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
sequence of OIData
|
|
required |
dof
|
sequence of array
|
One vector of block |
required |
a_max
|
float or tuple
|
Disc radius (mas; |
required |
flux_range
|
float or tuple
|
Disc radius (mas; |
required |
step
|
float or tuple
|
Disc radius (mas; |
required |
s_max
|
optional
|
As for |
None
|
primary_diam
|
optional
|
As for |
None
|
batch_size
|
optional
|
As for |
None
|
memory_budget
|
optional
|
As for |
None
|
coarse_nats
|
optional
|
As for |
None
|
coarse_margin
|
optional
|
As for |
None
|
n_flux
|
int
|
Log-spaced flux nodes. |
_N_FLUX
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
sidelobe_flags(data, positions, predicted, *, k_sigma=3.0, delta_nats=10.0, dof=1.0)
Flag nights whose orbit sits on a secondary peak of the night's surface.
A night is flagged (orbit-prefers-secondary) when its best peak lies
more than k_sigma from the predicted position, yet the marginal
surface there is within delta_nats of the peak. The flag is reported,
never used to exclude the night.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Epochs or sequence of OIData
|
The data |
required |
positions
|
EpochPositions
|
The single-night positions. |
required |
predicted
|
tuple of array
|
|
required |
k_sigma
|
float
|
Distance (sigma), surface margin (nats) and dof fraction. |
3.0
|
delta_nats
|
float
|
Distance (sigma), surface margin (nats) and dof fraction. |
3.0
|
dof
|
float
|
Distance (sigma), surface margin (nats) and dof fraction. |
3.0
|
Returns:
| Type | Description |
|---|---|
list of NightFlag or None
|
One entry per night. |
start_from_positions(model, priors, data, start_values, *, grid, periods, t_ref, scales='marginal', noise=None, dof=1.0, s_max=None, eccs=None, n_phase=36, n_candidates=200, n_refine=4, min_gap=5.0, refine_positions=True, n_peaks=5, batch_size=None, primary_diam=None, skip_flagged=True, flag_options=None, **fit_options)
Start an orbit fit to multi-epoch visibilities from a positions fit.
Thiele-Innes orbits from per-dataset
epoch_positions, ranked by all the
data, then fit from the best distinct ones. It
only chooses where the fits start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
callable
|
As for |
required |
priors
|
dict
|
As for |
required |
data
|
Epochs
|
The data. |
required |
start_values
|
callable
|
|
required |
grid
|
dict
|
Per-dataset grid of positions and fluxes (see |
required |
periods
|
array - like
|
Trial periods (days), e.g. from |
required |
t_ref
|
float
|
Reference time (MJD) of the starting orbits. |
required |
scales
|
optional
|
As for |
'marginal'
|
noise
|
optional
|
As for |
'marginal'
|
dof
|
optional
|
As for |
'marginal'
|
s_max
|
optional
|
As for |
'marginal'
|
batch_size
|
optional
|
As for |
'marginal'
|
eccs
|
optional
|
As for |
'marginal'
|
n_phase
|
optional
|
As for |
'marginal'
|
n_candidates
|
optional
|
Orbits ranked (200), distinct ones refined (4), and the
|
200
|
n_refine
|
optional
|
Orbits ranked (200), distinct ones refined (4), and the
|
200
|
min_gap
|
optional
|
Orbits ranked (200), distinct ones refined (4), and the
|
200
|
refine_positions
|
optional
|
As for |
True
|
n_peaks
|
optional
|
As for |
True
|
primary_diam
|
optional
|
As for |
True
|
skip_flagged
|
optional
|
As for |
True
|
flag_options
|
optional
|
As for |
True
|
**fit_options
|
Passed to the refinement fits; one that raises goes in |
{}
|
Returns:
| Type | Description |
|---|---|
OrbitStart
|
The ranked orbits, the refined fits, |