virgil.radio_toeplitz
Provisional
May change in any 0.4.x release without a deprecation cycle.
The radio χ² of a one-Image fit through precomputed dirty beams and images. See Toeplitz χ².
Radio χ² through the dirty beam (Toeplitz embedding), for one-Image scenes.
When the scene is a single Image I (unit sum),
the χ² of ComplexVisData.term is, for
each ddid d of observation e,
χ²_d = (C_d − 2 G_e Iᵀ D_d(δ_e) + G_e² Iᵀ B_d I) / s_d²
with G_e = flux · gain_e, C_d = Σ w|V|², the dirty image D_d at
the observation's offset δ_e and the dirty beam B_d (a Toeplitz
matrix, applied by FFT on a 2N × 2N grid). Precompute them once with
ComplexVisData.toeplitz; an
evaluation then costs a few FFTs of the image grid, whatever the number of
visibilities. See Radio interferometry.
Fitted offsets (offsets="spread") are an opt-in extension. The offset
ramp cancels in |M|², so B_d is offset-free, and with the stored
spread grid b the dirty image is
D(x + δ) = Σ_l b_l e^{2πil(x+δ)/n_f} / ψ̂(x + δ): a phase ramp on b
and the kernel transform at non-integer x + δ (a type-3 evaluation),
exact while no point's kernel wraps. It builds on type-3 NUFFT evaluation;
we know of no prior use of this combination.
Provisional
May change in any 0.4.x release without a deprecation cycle.
Source: Fessler et al. (2005), nufftax, Barnett et al. (2019), Lee & Greengard (2005).
ToeplitzVisData
Bases: Module
Precomputed dirty beams and images of a ComplexVisData (provisional).
Build it with
ComplexVisData.toeplitz; its
term has the χ², log-
normalization, gradient and profiled ŝ of
ComplexVisData.term for a scene that
is one fixed-layout Image.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
ComplexVisData
|
|
mask |
(N,) bool
|
Points used. |
npix, pixel_scale_mas, rotation_deg, smooth_fwhm_mas |
The Image layout the precompute is for. |
|
image_offset_mas |
(float, float)
|
The template's fixed |
free_offsets |
bool
|
Whether |
max_shift_pix |
float
|
Largest image-frame offset allowed, in pixels. |
nyquist_fraction |
float
|
|
margin |
float or None
|
The largest |
arrays |
dict
|
|
plan = dict(idx=np.asarray(used[idx]), valid=np.asarray(valid), group=np.asarray(chunk_group), last=np.asarray(last), tx=chunked(tx), ty=chunked(ty), h=chunked(h), rot=chunked(rot))
instance-attribute
data = data
instance-attribute
mask = mask
instance-attribute
npix = npix
class-attribute
instance-attribute
pixel_scale_mas = float(pix)
class-attribute
instance-attribute
rotation_deg = float(image.rotation_deg)
class-attribute
instance-attribute
smooth_fwhm_mas = image.smooth_fwhm_mas
class-attribute
instance-attribute
image_offset_mas = (dra, ddec)
class-attribute
instance-attribute
free_offsets = free
class-attribute
instance-attribute
max_shift_pix = float(bound)
class-attribute
instance-attribute
nyquist_fraction = tau
class-attribute
instance-attribute
margin = margin
class-attribute
instance-attribute
signature = _signature(nuisance)
class-attribute
instance-attribute
kp = kp
class-attribute
instance-attribute
sizes = (n_groups, nf_b, nf_d)
class-attribute
instance-attribute
arrays = dict(self._compute(data.vis, data.weight), count=np.asarray(count))
instance-attribute
layout
property
(shape, pixel_scale_mas, rotation_deg, smooth_fwhm_mas).
__init__(data, image, nuisance, mask=None, offsets='none', eps=1e-14, max_offset_mas=None, chunk_size=65536)
rebuild(vis, weight)
The same precompute for new full-length vis and weight
(jitted: no recompilation).
term(scene, nuisance, sigma=None)
A likelihood term for fit's likelihoods.
As ComplexVisData.term (same
loss, gradient and derived), but with no residual vector: fit
with method="lbfgs" or "adam". scene(values) must be one
Image of this layout (alone, or the only
part of a System) at the template's fixed
dra, ddec; the observations' offsets are cal.offset.
direct_term(scene, nuisance, **kwargs)
ComplexVisData.term of the
same points, for checks.
chi2_by_ddid(scene, values, nuisance)
(chi2, n) per ddid, as
ComplexVisData.chi2_by_ddid.
crosscheck(scene, values, nuisance, chunk_size=10000000)
The χ² per ddid and the loss both ways, and their largest relative difference.
Returns a dict: chi2 and chi2_direct per ddid, loss and
loss_direct (½χ² + log_norm), max_rel. chunk_size is
the direct term's.