virgil.gains
Calibration gains correlated across the channels of a frame, as low-rank
blocks of the visibility covariance that the likelihood marginalizes
analytically. Add them with
OIData.with_gains, and fit their widths
with the noise terms vis_gain_telescope, vis_gain_baseline,
vis_gain_chromatic and vis_gain_modes (e.g.
fit(..., noise={"vis_gain_telescope": dist.LogUniform(1e-4, 0.1)})). Widths
are scale parameters, so their default (Jeffreys) prior is log-uniform on
stated bounds; a Uniform(0, ...) would favour large widths.
Closure-phase offsets common to a frame's channels work the same way, on the
whitened closure phases: add them with
OIData.with_closure_offsets and
fit their widths with phi_offset_baseline, phi_offset_triangle and
phi_offset_modes. They are off by default.
Calibration gains correlated across channels, marginalized analytically.
The calibration of spectro-interferometric data (the transfer function, its drift between calibrators, injection and piston losses) multiplies every channel of a frame's baseline by much the same factor. Independent error bars cannot describe this: an error common to all channels averages down in them, but not in the data. Here each such error is a gain on log |V|,
log |V|_obs = log |V| + Σ_j τ_j z_j m_j, z_j ~ N(0, 1),
where m_j is a mode (a shape over the data's visibility samples) and τ_j its width. The modes come in groups, with one width each:
telescope: one gain per (frame, telescope), on the frame's baselines that include that telescope;baseline: one gain per (frame, baseline), on all its channels;chromatic: one per (frame, baseline) shaped (λ_ref/λ)², the first order of a coherence loss exp(−a/λ²) from piston jitter;modes: shapes supplied from outside, per 1σ, e.g. from a calibrator PCA (as virgil-vlti makes), whose width scales them (1 = as given).
For small gains (τ ≲ 0.2) the observable changes linearly, by J m_j with J = dObs/dlog|V| = 2V² for squared visibilities, |V| for amplitudes and 1 for log-amplitudes, taken from the model (so the covariance does not depend on the noisy data; Lachaume 2021). The gains are then Gaussian and are marginalized analytically: the visibility covariance becomes
C = D + U Uᵀ, U = J τ m (one column per mode),
with D the diagonal of squared errors. Modes that share no sample are independent, so C is block diagonal, one block per connected group of modes (one per frame, for the built-in groups).
Whitening. Each block is whitened by successive rank-one steps, the
shared machinery for linear marginalization in virgil._linear
(whiten_blocks). Only square roots of scalars appear, so the gradients
stay smooth, also where modes are degenerate and where widths go to zero.
GAIN_GROUPS = ('telescope', 'baseline', 'chromatic', 'modes')
module-attribute
OFFSET_GROUPS = ('baseline', 'triangle', 'modes')
module-attribute
GainModes
Bases: Module
Low-rank gain modes on the visibility observables.
Built by gain_modes (or
OIData.with_gains); see the
module notes for the model.
Modes within one frame are kept in blocks, the connected groups of such modes (one per frame for the built-in groups), padded to a common size. Modes that span frames (only supplied ones can) are kept apart, as dense columns, and whitened after the blocks. That way, a few modes across frames do not merge every frame into one dense block.
Attributes:
| Name | Type | Description |
|---|---|---|
rows |
Array
|
|
shapes |
Array
|
|
group |
Array
|
|
spanning |
Array or None
|
|
spanning_group |
Array or None
|
|
widths |
Array
|
The default width of each group. |
groups |
tuple of str
|
The groups present, a subset of |
n_vis |
int
|
The number of visibility observables. |
rows
instance-attribute
shapes
instance-attribute
group
instance-attribute
spanning
instance-attribute
spanning_group
instance-attribute
widths
instance-attribute
groups = eqx.field(static=True)
class-attribute
instance-attribute
n_vis = eqx.field(static=True)
class-attribute
instance-attribute
widths_for(terms=None)
Each group's width, with vis_gain_<group> terms replacing them.
whiten(x, jacobian, widths)
Whiten residuals for the covariance I + Σ w_j w_jᵀ.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array - like
|
Visibility residuals divided by their errors, |
required |
jacobian
|
array - like
|
|
required |
widths
|
array - like
|
Each group's width (see |
required |
Returns:
| Type | Description |
|---|---|
tuple
|
The whitened residuals |
covariance(errors, jacobian, widths)
The dense visibility covariance D + U Uᵀ (for checks; O(n²)).
jacobian is dObs/dlog|V| itself here, not divided by the errors.
sample(key, widths)
Draw the gains: log |V| offset of each visibility observable.
subset(keep)
The modes on the visibility observables where keep is True.
A Gaussian's marginal on a subset of its variables is the same covariance restricted to them, so dropping rows is exact.
labels_shared(labels)
Whether any mode touches observables with different labels.
labels (one per visibility observable) partitions the data, e.g.
into epochs; a partition's likelihoods add up to the whole only if
no gain is shared between its parts.
ClosureOffsets
Bases: Module
Closure-phase offsets common to the channels of a frame, marginalized.
Built by closure_offsets (or
OIData.with_closure_offsets).
Each offset is a mode m over the closure phases, in radians per unit
width: φ_obs = φ + Σ τ_j z_j m_j with z_j ~ N(0, 1).
The likelihood of correlated closure phases whitens their sines with
OIData.cp_noise (see likelihood._whiten). The offsets add
τ² m mᵀ to that covariance: a small-phase approximation, since an
offset δ changes sin Δ by about δ cos Δ. It holds for offsets (and
residuals) below about 0.3 rad; larger widths are not marginalized
exactly. Each mode is
whitened the same way, one closure-phase group (frame and channel) at
a time, and the modes of a frame then form one block of the rank-one
whitening (GainModes has the details).
The periodic penalty rows are left as they are.
Attributes:
| Name | Type | Description |
|---|---|---|
groups |
ndarray
|
|
group_mask |
ndarray
|
|
values |
ndarray
|
|
group |
ndarray
|
|
rows |
ndarray
|
|
widths |
Array
|
The default width of each group, in radians. |
groups_present |
tuple of str
|
The groups present, a subset of |
n_out |
int
|
The number of whitened closure phases ( |
groups
instance-attribute
group_mask
instance-attribute
values
instance-attribute
group
instance-attribute
rows
instance-attribute
widths
instance-attribute
groups_present = eqx.field(static=True)
class-attribute
instance-attribute
n_out = eqx.field(static=True)
class-attribute
instance-attribute
widths_for(terms=None)
Each group's width, with phi_offset_<group> terms replacing them.
whiten(cp_noise, x, sigma, widths)
Whiten the closure-phase sines x (already whitened by cp_noise).
Returns the whitened values and, per value, the log of the factor its effective error grows by (summing to ½ log det).
modes(cp_noise, n_phase, widths=None)
The modes as dense columns over the closure phases (for checks).
sample(key, cp_noise, n_phase, widths)
Draw the offsets: radians added to each closure phase.
gain_modes(data, telescope=None, baseline=None, chromatic=None, modes=None)
Gain modes for a dataset, with default widths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
OIData
|
Unprojected data, with frames ( |
required |
telescope
|
float
|
Widths (1σ, on log |V|, so 0.01 is a 1% amplitude or 2% V² gain) of
gains per (frame, telescope), per (frame, baseline), and per
(frame, baseline) shaped (λ_ref/λ)² with λ_ref the median
wavelength. |
None
|
baseline
|
float
|
Widths (1σ, on log |V|, so 0.01 is a 1% amplitude or 2% V² gain) of
gains per (frame, telescope), per (frame, baseline), and per
(frame, baseline) shaped (λ_ref/λ)² with λ_ref the median
wavelength. |
None
|
chromatic
|
float
|
Widths (1σ, on log |V|, so 0.01 is a 1% amplitude or 2% V² gain) of
gains per (frame, telescope), per (frame, baseline), and per
(frame, baseline) shaped (λ_ref/λ)² with λ_ref the median
wavelength. |
None
|
modes
|
array - like
|
Further modes, |
None
|
Returns:
| Type | Description |
|---|---|
GainModes
|
|
closure_offsets(data, baseline=None, triangle=None, modes=None)
Closure-phase offsets for a dataset, with default widths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
OIData
|
Closure phases from four or more telescopes ( |
required |
baseline
|
float
|
Width (radians) of a phase offset per (frame, baseline), common to all channels, which reaches the closure phases as T·e (T the triangle-by-baseline signs). The design's default form. |
None
|
triangle
|
float
|
Width (radians) of an offset per (frame, triangle), common to all channels: what a pair test of consecutive frames measures. |
None
|
modes
|
array - like
|
Further modes, |
None
|
Returns:
| Type | Description |
|---|---|
ClosureOffsets
|
|