Skip to content

virgil.fields

Gaussian-process priors for pixel images. A GaussianField can take the place of an Image's log-brightness array: the log-brightness is then a stationary Gaussian process about an optional template, parameterized by whitened coefficients on the image's cosine basis, which imaging.image_priors gives standard-normal priors. A MultipoleField is the same idea on a polar grid in a disk's frame, a residual aligned with a MultipoleDisk.

Gaussian-process log-brightness fields for pixel images.

A GaussianField stands in for the log_brightness of an Image: a stationary Gaussian process with a Matérn-like spectrum, written as independent standard-normal latent coefficients on the cosine (DCT-II) basis. Fitting the latents under a standard-normal prior is MAP estimation with a GP prior; see Gaussian processes and IFT.

Source: Edenhofer et al. (2024), Arras et al. (2022), Enßlin et al. (2009), references. No code is taken from NIFTy.

GaussianField

Bases: Base

A Gaussian-process log-brightness for an Image.

η = log(μ/max μ + ε) + IDCT[√S ⊙ z]: the orthonormal inverse DCT-II of the latents z scaled by the spectrum S of field_spectrum, about an optional positive template μ. With a standard-normal prior on latent (from image_priors) it is a Gaussian process of standard deviation sigma and correlation length length_mas; latent = 0 gives the floored template. Fix sigma and length_mas or sample them: their MAP values are biased (fit warns). See Gaussian processes and IFT.

Source: Edenhofer et al. (2024), references.

Parameters:

Name Type Description Default
latent (array - like, shape(nrow, ncol))

Whitened cosine coefficients.

required
sigma float or array - like

Standard deviation of the field (default 1).

1.0
length_mas float or array - like

Correlation length in mas (default 1), or a pair (ℓ_row, ℓ_col) along the image's vertical and horizontal axes (with the Image's rotation_deg at a structure's position angle: along and across it).

1.0
order int

Exponent of the spectrum (default 2).

2
mean optional

Positive template image of the same shape (default flat), and its floor as a fraction of its peak (default 1e-3).

None
mean_floor optional

Positive template image of the same shape (default flat), and its floor as a fraction of its peak (default 1e-3).

None

Examples:

field = GaussianField(np.zeros((32, 32)), sigma=2.0, length_mas=3.0)
env = Image(field, pixel_scale_mas=0.6, flux=0.3)

mean instance-attribute

mean_floor = eqx.field(static=True) class-attribute instance-attribute

latent = np.asarray(latent, dtype=float) instance-attribute

sigma = np.asarray(sigma, dtype=float) instance-attribute

length_mas = np.asarray(length_mas, dtype=float) instance-attribute

order = int(order) class-attribute instance-attribute

shape property

The image's shape, (nrow, ncol).

__init__(latent, sigma=1.0, length_mas=1.0, order=2, mean=None, mean_floor=0.001)

evaluate(pixel_scale_mas)

The log-brightness η on pixels of pixel_scale_mas.

MultipoleField

Bases: Base

A multipole-kernel residual field for an Image.

Provisional

May change in any 0.4.x release without a deprecation cycle.

The log-brightness is a Gaussian process on a polar grid in the disk's frame (n_r radii, n_theta azimuths) with a separable Matérn prior: radial as RadialGP, periodic azimuthal as MultipoleKernel. The brightness is the softmax of the field, outside beyond the grid. The latents are whitened standard normals. Priors: multipole_field_priors; kernel, tied geometry and fallback: Model notes.

Parameters:

Name Type Description Default
latent (array - like, shape(n_r, n_theta))

Whitened coefficients; their shape sets the polar grid.

required
image_shape tuple of int

(nrow, ncol) of the Image's pixel grid.

required
r_max_mas float

Outermost radius of the polar grid (mas, disk plane); the field fades to zero over one node spacing beyond it.

required
r_min_mas float

Innermost radius (default 0); standard deviation of the field (1).

0.0
sigma float

Innermost radius (default 0); standard deviation of the field (1).

0.0
length_r float or array - like

Radial (mas; default five node spacings) and azimuthal (radians; 1) correlation lengths.

None
length_theta float or array - like

Radial (mas; default five node spacings) and azimuthal (radians; 1) correlation lengths.

None
inc float or array - like

Disk inclination, major-axis position angle (degrees, North to East) and centre (mas) relative to the Image's.

0.0
pa float or array - like

Disk inclination, major-axis position angle (degrees, North to East) and centre (mas) relative to the Image's.

0.0
dra float or array - like

Disk inclination, major-axis position angle (degrees, North to East) and centre (mas) relative to the Image's.

0.0
ddec float or array - like

Disk inclination, major-axis position angle (degrees, North to East) and centre (mas) relative to the Image's.

0.0
nu (0.5, 1.5, 2.5, inf)

Kernel smoothness (default 1.5; nu_theta defaults to nu).

0.5
nu_theta (0.5, 1.5, 2.5, inf)

Kernel smoothness (default 1.5; nu_theta defaults to nu).

0.5
geometry_from str or None

Sibling System component whose inc, pa, dra, ddec the field follows (default: its own).

None
mean optional

As for GaussianField.

None
mean_floor optional

As for GaussianField.

None
outside float

Log-brightness beyond the grid (default -20; 0 leaves a flat background the latents cannot remove).

-20.0

Examples:

field = MultipoleField(np.zeros((24, 32)), image_shape=(64, 64),
                       r_max_mas=40.0, inc=50.0, pa=30.0)
env = Image(field, pixel_scale_mas=1.5, flux=0.3)

inc instance-attribute

pa instance-attribute

dra instance-attribute

ddec instance-attribute

mean instance-attribute

geometry_from = eqx.field(static=True) class-attribute instance-attribute

fallback = eqx.field(static=True) class-attribute instance-attribute

mean_floor = eqx.field(static=True) class-attribute instance-attribute

latent = np.asarray(latent, dtype=float) instance-attribute

image_shape = tuple(int(n) for n in image_shape) class-attribute instance-attribute

r_min_mas = float(r_min_mas) class-attribute instance-attribute

r_max_mas = float(r_max_mas) class-attribute instance-attribute

nu = _check_nu(nu, 'MultipoleField') class-attribute instance-attribute

nu_theta = _check_nu(nu if nu_theta is None else nu_theta, 'MultipoleField') class-attribute instance-attribute

sigma = np.asarray(sigma, dtype=float) instance-attribute

length_r = np.asarray(length_r, dtype=float) instance-attribute

length_theta = np.asarray(length_theta, dtype=float) instance-attribute

outside = float(outside) class-attribute instance-attribute

shape property

The shape of the latents, (n_r, n_theta).

spacing property

Radial node spacing in milliarcseconds.

__init__(latent, image_shape, r_max_mas, r_min_mas=0.0, sigma=1.0, length_r=None, length_theta=1.0, inc=0.0, pa=0.0, dra=0.0, ddec=0.0, nu=1.5, mean=None, mean_floor=0.001, outside=-20.0, nu_theta=None, geometry_from=None)

from_disk(disk, latent, image_shape, r_max_mas=None, geometry_from=None, **kwargs) classmethod

A field in the frame of disk (its inc, pa, dra, ddec).

r_max_mas defaults to the outer edge of the disk's profile (disk.profile.extent()) plus 20 per cent. The values are copied unless geometry_from is the disk's name in the System the Image will join, which ties them: see the notes of MultipoleField.

with_geometry(inc, pa, dra, ddec)

This field untied, with the given geometry as its own parameters.

What System calls to resolve a tie; the arguments are the grid-frame inc, pa (degrees) and centre (milliarcseconds).

polar_values()

The field η on its polar grid, shape (n_r, n_theta).

evaluate(pixel_scale_mas)

The log-brightness η on pixels of pixel_scale_mas.

multipole_field_priors(path='env.log_brightness', sigma=(0.05, 5.0), length_r=(0.5, 50.0), length_theta=(0.1, 6.0))

Bounded log-uniform priors on a MultipoleField's scales.

Provisional

May change in any 0.4.x release without a deprecation cycle.

Returns a priors dict for fit or numpyro_model: LogUniform priors, which are invariant under rescaling and proper because they are bounded. Add the latents' priors with image_priors. Each range is (low, high): sigma in log-brightness, length_r in milliarcseconds and length_theta in radians. The variance of the azimuthal order m falls as the spectrum of MultipoleKernel in m * length_theta, so a length above about 2 leaves almost only the order 0, an axisymmetric field (for nu = 3/2 the first order, cos θ and sin θ together, has about 1 per cent of the variance at a length of 6), and the default upper limit is effectively axisymmetric.

Parameters:

Name Type Description Default
path str

Path of the field in the model (default "env.log_brightness").

'env.log_brightness'

polar_interpolate(values, r_min, spacing, r, theta, fill=0.0)

Bilinear interpolation of a polar grid at (r, theta).

values[k, j] sits at radius r_min + k * spacing and azimuth 2π j / n_theta (periodic). Outside the radial range the field falls linearly to fill over one spacing and is fill beyond, so there is no edge discontinuity. The error is second order in the grid spacings.

Parameters:

Name Type Description Default
values (array - like, shape(n_r, n_theta))
required
r_min float

Radius of the first node and the node spacing, in milliarcseconds.

required
spacing float

Radius of the first node and the node spacing, in milliarcseconds.

required
r array - like

Radii (mas) and azimuths (radians); any common shape.

required
theta array - like

Radii (mas) and azimuths (radians); any common shape.

required
fill float

The value outside the grid (default 0).

0.0

Returns:

Type Description
Array

The interpolated values, of the shape of r.

field_spectrum(shape, pixel_scale_mas, sigma, length_mas, order=2)

Prior variances of a field's cosine coefficients.

S_jk ∝ (κ² + λ_jk)^(-order), with κ = 1 / length_mas and λ_jk the eigenvalues of the reflecting-boundary (Neumann) Laplacian on the pixel grid, λ_jk = (2/h)² [sin²(πj/2n) + sin²(πk/2m)]. With two lengths (ℓ_row, ℓ_col) the field is anisotropic, S_jk ∝ (1 + ℓ_row² λ_j + ℓ_col² λ_k)^(-order): correlated over ℓ_row down a column and over ℓ_col along a row. The constant mode is zero (a softmax image does not depend on it) and the spectrum is scaled so the field's pixel-averaged variance is sigma².

Parameters:

Name Type Description Default
shape tuple of int

(nrow, ncol).

required
pixel_scale_mas float

Pixel size h in milliarcseconds.

required
sigma float or array - like

Standard deviation of the field, in units of log-brightness.

required
length_mas (float or array - like, shape() or (2,))

Correlation length 1/κ in milliarcseconds, or the pair (ℓ_row, ℓ_col) for an anisotropic field.

required
order int

Exponent of the spectrum (default 2). order=1 makes the prior exactly a total-squared-variation plus L2 penalty on the field.

2

Returns:

Type Description
Array

Variances, of shape shape.