MultipoleDisk: radial profiles by quadrature
Provisional
May change in any 0.4.x release without a deprecation cycle.
A disk, ring or halo described by its radial brightness profile \(I(r)\) in
the plane of the disk, as one component of a System. It is
placed and weighted like any other component, and its visibility is the
Hankel transform of the profile. The maths, and a worked fit, are in the
tutorial A planet in a gap between rings. The
ideas follow frank (Jennings et al. 2020)
and vis-r (Kennedy 2025); virgil
reimplements them, with no shared code, for V² and closure-phase data and for
composition in a scene.
Each profile owns its quadrature rule, so the transform is a sum over n_r
nodes that converges spectrally: a narrow ring needs tens of nodes, not the
hundreds of a midpoint stack.
| Profile | Brightness | Rule |
|---|---|---|
ThinRing(radius) |
\(\delta(r - r_0)\) | exact: \(J_0(2\pi q r_0)\) |
GaussianRing(radius, sigma) |
Gaussian in \(r\) | Gauss–Legendre over \(r_0 \pm 6\sigma\) |
RadialPowerLaw(r_in, r_out, index, edge_sigma) |
\(r^{\rm index}\) between the radii, sharp or soft edges | Gauss–Legendre |
ExpTail(r_in, scale_length, *, cutoff) |
\(\exp[-(r - r_{\rm in})/L]\) for \(r \ge r_{\rm in}\) | Gauss–Laguerre, to infinity |
Gap(base, radius, sigma, depth) |
a Gaussian gap cut in base |
that of base |
RadialSum(a=..., b=(profile, weight)) |
named profiles, each normalized and mixed by its weight | each part's |
RadialGP(r_in, r_out, sigma, ell, nu) |
\(\exp g(r)\), \(g\) a Gaussian process | its own: Gauss–Legendre on \([r_{\rm in}, r_{\rm out}]\) |
A profile has no weight of its own: only the parts of a RadialSum do
(disk.profile.outer.weight).
Names and units
One name for one concept across the family. Lengths are in milliarcseconds
in the plane of the disk, angles in degrees, and a name carries a unit
suffix only where the quantity would otherwise be ambiguous
(pixel_scale_mas, rotation_deg), as in the older components.
| Concept | Name | Where |
|---|---|---|
| radius of a feature's centre | radius |
ThinRing, GaussianRing, Gap (as GaussianArc, FlaredDisk) |
| edges of the support | r_in, r_out |
RadialPowerLaw, ExpTail (r_in), RadialGP, RadialGPFunction, MultipoleKernel |
| reference radius of a function | r_ref |
RadialLinear, RadialPower, PowerLawHeight, MultipoleKernel |
| Gaussian standard deviation | sigma (FWHM = 2.355 sigma) |
GaussianRing, Gap, as GaussianDisk; edge_sigma for a soft edge |
| FWHM of a blur | blur_fwhm |
MultipoleDisk |
| e-folding length | scale_length |
ExpTail |
| inclination, position angle of the major axis | inc, pa (degrees; default 0, face-on, North) |
MultipoleDisk, MultipoleField |
| height | h_ref, psi; alpha, tip |
PowerLawHeight, Cone (as TruncatedCone) |
The older components keep their names: ModulatedGaussianRim takes a
diameter diam where a profile takes radius (radius = diam / 2), and
EllipticalGaussian and TruncatedCone take an axis ratio ratio where the
disk takes inc (ratio = cos(inc)).
The options each have their own entry below: azimuthal structure
(Harmonics, VonMises,
and the priors of MultipoleKernel, with
conversions between the forms in virgil.harmonics),
height (Cone, PowerLawHeight),
Gaussian-process priors (gp_priors), and a
residual aligned with the disk (MultipoleField).
virgil.models.MultipoleDisk
Bases: Component
Axisymmetric disk with a radial profile, evaluated by quadrature.
Provisional
May change in any 0.4.x release without a deprecation cycle.
A radial profile \(I(r)\) in the disk plane, inclined by inc and rotated
by pa; the visibility is its Hankel transform summed over n_r nodes
of the profile's quadrature rule. Profiles: ThinRing, GaussianRing,
RadialPowerLaw, ExpTail, Gap, RadialSum,
RadialGP; parameters are reached by path
("disk.profile.radius"). Choosing n_r, symmetry and precision:
Model notes,
guide.
Source: Jennings et al. (2020), references, and Kennedy (2025), references; ideas only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
profile
|
The radial profile; its quadrature rule is set to |
required |
harmonics
|
optional
|
A Harmonics, VonMises or None azimuthal factor of mean one (odd orders make closure phases non-zero); a Cone, PowerLawHeight or None height of each ring above the disk plane (see the notes). |
None
|
height
|
optional
|
A Harmonics, VonMises or None azimuthal factor of mean one (odd orders make closure phases non-zero); a Cone, PowerLawHeight or None height of each ring above the disk plane (see the notes). |
None
|
inc
|
float or array - like
|
Inclination (0 is face-on) and position angle of the projected major axis (North to East), in degrees; FWHM in mas, in the disk plane, of a smoothing Gaussian (exact envelope). |
0.0
|
pa
|
float or array - like
|
Inclination (0 is face-on) and position angle of the projected major axis (North to East), in degrees; FWHM in mas, in the disk plane, of a smoothing Gaussian (exact envelope). |
0.0
|
blur_fwhm
|
float or array - like
|
Inclination (0 is face-on) and position angle of the projected major axis (North to East), in degrees; FWHM in mas, in the disk plane, of a smoothing Gaussian (exact envelope). |
0.0
|
flux
|
optional
|
As for any |
1.0
|
dra
|
optional
|
As for any |
1.0
|
ddec
|
optional
|
As for any |
1.0
|
n_r
|
int
|
Quadrature nodes per profile (default 64; static);
|
64
|
spectral_index
|
optional
|
A float, radial function or RadialGPFunction makes the profile
chromatic, \(I_0(r)(\lambda/\lambda_0)^{\alpha(r)}\); |
None
|
wavel0
|
optional
|
A float, radial function or RadialGPFunction makes the profile
chromatic, \(I_0(r)(\lambda/\lambda_0)^{\alpha(r)}\); |
None
|
Examples:
>>> ring = GaussianRing(radius=10.0, sigma=3.0)
>>> profile = Gap(ring, radius=10.0, sigma=0.8)
>>> disk = MultipoleDisk(profile, inc=50.0, pa=30.0, blur_fwhm=1.0, n_r=48)
suggest_n_r(data)
A starting number of nodes for data's longest baselines.
Enough to sample the Bessel oscillations across the profile and the
phase of a height's lift (at the current parameter values, which
must be concrete), rounded up to a
multiple of 8 (but at most the 144 nodes buildable for a Gauss-Laguerre
tail). A starting point only: check convergence by
doubling n_r.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
OIData
|
Anything with |
required |
freeze_geometry(data)
A disk with its Bessel matrices cached for data.
With inc, pa, height and the nodes fixed, the transform
matrices depend only on the baselines and nodes, so a refit of the
profile, harmonics or spectral index is one matrix-vector product per
call (and per order) instead of the Bessel functions of every baseline
and node. Never automatic: call it once the geometry is settled, and
fit the returned model. The cache checks its baselines, nodes and
geometry at every call and silently falls back to the full computation
(correct, not faster) for any other, so changing a frozen quantity
loses the speed-up. Build it in the precision you evaluate in (inside
jax.enable_x64(True) for a float64 fit; a float32 cache still
matches a float64 fit, to float32 rounding). It holds (2M + 1)
complex matrices of shape (n_samples, n_r) (M the harmonics'
degree).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
OIData
|
Anything with |
required |
Returns:
| Type | Description |
|---|---|
MultipoleDisk
|
This disk with the cache ( |
min_intensity(n_theta=720)
The least brightness relative to the azimuthal mean.
The minimum over the quadrature nodes and n_theta azimuths of
I(r, theta) / I0(r): 1 without harmonics, and negative if the
image goes negative somewhere (possible for the linear and von Mises
forms, never for the positive one). is_physical is false
then.
gp_sites()
The Gaussian-process parts of the disk, by path.
Returns a dict from the path (relative to the disk) of every
RadialGP profile or
RadialGPFunction (a harmonics
coefficient or the spectral index) and of the harmonics when they
carry a MultipoleKernel, to that object.
Its whitened latents are at <path>.z (harmonics.z for the
kernel), its hyperparameters at <path>.sigma, <path>.ell
(harmonics.prior.sigma, .ell_r, .ell_theta).
Profiles
virgil.models.ThinRing
Bases: _RadialProfile
Infinitely thin ring of radius radius,
\(I \propto \delta(r - r_0)\) with \(r_0\) = radius.
Provisional
May change in any 0.4.x release without a deprecation cycle.
Its Hankel transform is \(J_0(2\pi q r_0)\), so it needs no quadrature
(n_r is irrelevant). Rendered, it is a Gaussian a pixel wide.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
radius
|
float or array - like
|
Radius in milliarcseconds, in the plane of the disk. |
required |
virgil.models.GaussianRing
Bases: _RadialProfile
Gaussian ring, \(I \propto \exp[-(r - r_0)^2 / 2\sigma^2]\), with
\(r \ge 0\) and \(r_0\) = radius.
Provisional
May change in any 0.4.x release without a deprecation cycle.
The quadrature runs over \(r_0 \pm 6\sigma\) (clipped at the centre) with a Gauss-Legendre rule, which converges spectrally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
radius
|
float or array - like
|
Radius of the peak in milliarcseconds. |
required |
sigma
|
float or array - like
|
Standard deviation of the radial profile in milliarcseconds (the FWHM is \(2\sqrt{2\ln 2}\,\sigma \approx 2.355\,\sigma\)). |
required |
References
Gaussian rings are the basic building block of the parametric radial models of vis-r (Kennedy 2025, RASTI 4, rzaf004; https://github.com/drgmk/vis-r).
virgil.models.RadialPowerLaw
Bases: _RadialProfile
Power law \(I \propto r^{\rm index}\) between r_in and r_out.
Provisional
May change in any 0.4.x release without a deprecation cycle.
With edge_sigma (a length in mas) both edges are soft error functions
of that standard deviation; the quadrature then runs over 6 edge_sigma
beyond them, and n_r must resolve edge_sigma. With
edge_sigma=None the edges are sharp and the Gauss-Legendre rule spans
exactly [r_in, r_out], spectrally accurate for a smooth power law
(index=0, r_in=0 is a uniform disk).
Source: Kennedy (2025), vis-r, references.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_in
|
float or array - like
|
Inner and outer radius in mas. |
required |
r_out
|
float or array - like
|
Inner and outer radius in mas. |
required |
index
|
float or array - like
|
Power-law index (default 0). |
0.0
|
edge_sigma
|
(float, array - like or None)
|
Standard deviation of the soft edges in mas, or |
None
|
virgil.models.ExpTail
Bases: _RadialProfile
Exponential tail, \(\exp[-(r - r_{\rm in})/L]\) beyond r_in.
Provisional
May change in any 0.4.x release without a deprecation cycle.
By default a Gauss-Laguerre rule integrates the whole tail to infinity, so
no outer radius is needed; r_in = 0 is an exponential disk. The rule of
thumb \(16 \cdot 2\pi q L\) nodes at the longest baseline \(q\) is optimistic
for a well-resolved tail (error in \(V\) about \(2 \times 10^{-4}\) at 128
nodes, \(4 \times 10^{-5}\) at the 150-node cap). For a tail resolved much
more finely, prefer a RadialPowerLaw with
a soft edge, or give a cutoff: the light beyond \(r_{\rm in} +
\mathrm{cutoff}\, L\) is dropped (0.7 % of a thin disk's flux at 5) and a
Gauss-Legendre rule is used. See MultipoleDisk.suggest_n_r and Model
notes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_in
|
float or array - like
|
Inner radius in mas, where the tail starts, and the e-folding length \(L\) in mas. |
required |
scale_length
|
float or array - like
|
Inner radius in mas, where the tail starts, and the e-folding length \(L\) in mas. |
required |
cutoff
|
float or None
|
Cut the tail at |
None
|
virgil.models.Gap
Bases: _RadialProfile
A Gaussian gap cut in another profile.
Provisional
May change in any 0.4.x release without a deprecation cycle.
The brightness is that of base times \(1 - d \exp[-(r - r_0)^2 / 2
\sigma^2]\) (\(r_0\) = radius), so depth=1 empties the gap and
depth=0 leaves base. The quadrature is the base profile's: its
n_r must resolve sigma.
Source: Kennedy (2025), vis-r, references.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
profile
|
The profile the gap is cut in; it must have a brightness, so a
|
required |
radius
|
float or array - like
|
Radius of the gap's centre and its standard deviation in mas. |
required |
sigma
|
float or array - like
|
Radius of the gap's centre and its standard deviation in mas. |
required |
depth
|
float or array - like
|
Fractional depth between 0 and 1 (default 1). |
1.0
|
virgil.models.RadialSum
Bases: _RadialProfile
Sum of named radial profiles, mixed by their weights.
Provisional
May change in any 0.4.x release without a deprecation cycle.
A part is a profile, or a (profile, weight) pair (a bare profile has
weight 1). Each part is normalized to unit total light and then weighted
by its weight (relative to the others), so the weights are the parts'
shares of the disk's flux, as the flux of a
System's components are. Keep the weights as
parameters and fit their ratios: parts are reached by name,
disk.profile.inner.radius and disk.profile.outer.weight.
Each part keeps its own quadrature rule, so the sum has
n_r nodes per part.
Examples:
>>> profile = RadialSum(
... inner=GaussianRing(radius=3.0, sigma=0.5),
... outer=(GaussianRing(radius=8.0, sigma=1.0), 0.5),
... )
>>> disk = MultipoleDisk(profile, inc=40.0, pa=20.0, n_r=32)
virgil.models.Harmonics
Bases: _Azimuthal
Azimuthal harmonics of a MultipoleDisk, of exact degree M.
Provisional
May change in any 0.4.x release without a deprecation cycle.
The brightness of a MultipoleDisk is the
profile \(I_0(r)\) times an azimuthal factor of mean 1 in the disk plane
(\(\theta\) from the projected major axis towards pa + 90, as for
ModulatedGaussianRim), with
harmonics 0..M. form="positive" (the default without c/s)
is \(|h(e^{i\theta})|^2\) normalized, positive for all parameters;
"linear" is \(1 + \sum_m c_m(r)\cos m\theta + s_m(r)\sin m\theta\),
positive if sum(sqrt(c_m**2 + s_m**2)) <= 1
(MultipoleDisk.min_intensity reports violations). Arguments after c
and s are keyword-only; see Model notes and
virgil.harmonics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
c
|
float, radial function or sequence of them
|
Linear form: coefficients of \(\cos m\theta\), \(\sin m\theta\) from first order up; a scalar is first order only, missing orders are zero. |
()
|
s
|
float, radial function or sequence of them
|
Linear form: coefficients of \(\cos m\theta\), \(\sin m\theta\) from first order up; a scalar is first order only, missing orders are zero. |
()
|
re
|
float, radial function or sequence
|
Positive form: real and imaginary parts of the latents \(w_j\), or
(constants only) |
()
|
im
|
float, radial function or sequence
|
Positive form: real and imaginary parts of the latents \(w_j\), or
(constants only) |
()
|
w
|
float, radial function or sequence
|
Positive form: real and imaginary parts of the latents \(w_j\), or
(constants only) |
()
|
degree
|
optional
|
Highest order |
None
|
form
|
optional
|
Highest order |
None
|
prior
|
MultipoleKernel
|
Gaussian-process prior over every order; needs |
None
|
Examples:
>>> w = (0.4 + 0.1j, 0.2j)
>>> harmonics = Harmonics(w=w)
>>> disk = MultipoleDisk(GaussianRing(6.0, 1.0), harmonics=harmonics)
image_harmonics(r=None)
Image harmonics I_0 .. I_M (complex, I_0 = 1) at the radii
r (not needed for constants), shape (M + 1,) + shape(r).
Linear form: \(I_m = (c_m - i s_m)/2\). Positive form: \(I_m = \sum_j h_{j+m} \bar h_j / \sum_j |h_j|^2\).
coefficients(r)
The linear (c, s), each of shape (M,) + shape(r), at the
radii r.
polynomial(r)
The minimum-phase polynomial h_0 .. h_M (h_0 = 1) of the
positive form at the radii r, complex, shape (M + 1,) +
shape(r).
virgil.models.VonMises
Bases: _Azimuthal
A von Mises azimuthal profile, truncated at degree.
Provisional
May change in any 0.4.x release without a deprecation cycle.
The profile \(\exp[\kappa\cos(\theta - \theta_0)]\) is an arc of width \(\sim
1/\sqrt\kappa\) radians at azimuth \(\theta_0\) in the disk plane of a
MultipoleDisk (as for
Harmonics); \(\kappa = 0\) is a uniform ring.
The harmonics come from a small FFT, differentiable in \(\kappa\) and
\(\theta_0\). The truncated series goes slightly negative if degree is
too low (about \(5.7\sqrt\kappa\) for harmonics below \(10^{-6}\));
truncation_power reports the
power dropped (Model notes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kappa
|
float or radial function
|
Concentration (non-negative). |
required |
theta0
|
float or radial function
|
Azimuth of the brightest point in degrees (default 0, the major axis). |
0.0
|
degree
|
int
|
Highest order kept (default the smallest keeping the harmonics above
\(10^{-6}\) for constant |
None
|
n_fft
|
int
|
Highest order kept (default the smallest keeping the harmonics above
\(10^{-6}\) for constant |
None
|
Examples:
>>> arc = VonMises(kappa=5.0, theta0=30.0, degree=20)
>>> ring = MultipoleDisk(GaussianRing(6.0, 1.0), harmonics=arc, inc=40.0)
image_harmonics(r=None)
Image harmonics I_0 .. I_M (I_0 = 1) of the truncated
profile at the radii r (not needed for constants).
truncation_power(r=None)
The fraction of the power of the structure that the truncation at
degree drops, \(\sum_{m > M} |I_m|^2 / \sum_{m \ne 0} |I_m|^2\)
(0 for a degree that holds everything; shape of r).
virgil.models.RadialLinear
Bases: _RadialFunction
value + slope (r - r_ref): a coefficient that varies linearly.
Provisional
May change in any 0.4.x release without a deprecation cycle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float or array - like
|
The function at |
required |
slope
|
float or array - like
|
Gradient per milliarcsecond (default 0). |
0.0
|
r_ref
|
float or array - like
|
Reference radius in milliarcseconds (default 0). |
0.0
|
virgil.models.RadialPower
Bases: _RadialFunction
value (r / r_ref) ** index: a coefficient that follows a power law.
Provisional
May change in any 0.4.x release without a deprecation cycle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float or array - like
|
The function at |
required |
index
|
float or array - like
|
Power-law index. |
required |
r_ref
|
float or array - like
|
Reference radius in milliarcseconds (positive). |
required |
virgil.models.Cone
Bases: _Height
A conical surface: the ring at radius \(r\) lies at the height \(h = r \cot\alpha - \mathrm{tip}\) along the disk's normal.
Provisional
May change in any 0.4.x release without a deprecation cycle.
This is the geometry of TruncatedCone:
the normal is the cone's axis, so the disk's inclination is
$90^\circ - $ the axis's tilt out of the sky, and pa is the
position angle of the major axis, 90 degrees from the projection of the
axis. Positive heights shift towards position angle pa + 90. In
slant distance \(s\) from the apex, \(r = s \sin\alpha\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float or array - like
|
Half-opening angle in degrees (0 < alpha < 90). |
required |
tip
|
float or array - like
|
Distance in milliarcseconds from the disk's centre back to the apex along the axis (the ring at \(r = 0\) lies at \(-\mathrm{tip}\)). |
0.0
|
virgil.models.PowerLawHeight
Bases: _Height
A flared surface: \(h = h_{\rm ref} (r / r_{\rm ref})^\psi\).
Provisional
May change in any 0.4.x release without a deprecation cycle.
Positive heights shift towards position angle pa + 90 on the sky
(see Cone); a negative h_ref puts the surface
on the other side. A top surface lifted towards the observer shifts the
apparent ring towards the far side, so when pa + 90 is the near side
of the disk it has h_ref < 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
h_ref
|
float or array - like
|
Height at |
required |
r_ref
|
float or array - like
|
Reference radius in milliarcseconds (positive). |
required |
psi
|
float or array - like
|
Flaring index (default 1, a cone through the centre). |
1.0
|
Gaussian-process priors
virgil.models.RadialGP
Bases: _RadialGPBase, _RadialProfile
Non-parametric radial profile: the exponential of a Gaussian process.
Provisional
May change in any 0.4.x release without a deprecation cycle.
\(I_0(r) = \exp g(r)\). One whitened latent z per Gauss-Legendre node of
\([r_{\rm in}, r_{\rm out}]\) (n_r of them), \(g = \mu + \sigma L z\),
interpolated linearly in \(r\). The visibility is normalized, so leave mu
at 0. Without the exponential it is
RadialGPFunction. Priors (z
standard normal, sigma and ell log-uniform via
gp_priors; MAP biases the scales),
draws and the meaning of ell: Model
notes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_in
|
float
|
Radii in mas of the first and last node. |
required |
r_out
|
float
|
Radii in mas of the first and last node. |
required |
sigma
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
ell
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
mu
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
z
|
(array - like, shape(n_r))
|
Whitened latents (default 0); set when the profile is built into a disk. |
None
|
nu
|
optional
|
Matérn smoothness in {0.5, 1.5, 2.5, inf} (default 1.5; |
1.5
|
jitter
|
optional
|
Matérn smoothness in {0.5, 1.5, 2.5, inf} (default 1.5; |
1.5
|
Examples:
>>> profile = RadialGP(r_in=0.5, r_out=12.0, sigma=1.5, ell=2.0)
>>> disk = MultipoleDisk(profile, inc=30.0, n_r=24)
>>> disk.profile.z.shape
(24,)
draws(key, n=1, r=None, positive=False)
n draws from the prior at the radii r (the nodes by default).
Draws \(g = \mu + \sigma L z\) with \(z \sim N(0, I)\) at the current
mu, sigma, ell; with positive, \(\exp g\) (the
profile). Shape (n,) + shape(r). Use them to show the prior beside
the posterior.
nodes()
The nodes in milliarcseconds.
virgil.models.RadialGPFunction
Bases: _RadialGPBase, _RadialFunction
A Gaussian process in the radius, as a function (no exponential).
Provisional
May change in any 0.4.x release without a deprecation cycle.
For the spectral_index of a
MultipoleDisk or a coefficient of
Harmonics; for a non-negative profile use
RadialGP. Values at n equally spaced nodes
are \(g = \mu + \sigma L z\) with whitened latents z (a standard-normal
prior is the GP prior), interpolated linearly (constant beyond). Priors and
ell are as for RadialGP.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_in
|
float or None
|
Radii in mas of the first and last node; both or neither (default the disk's profile range). |
None
|
r_out
|
float or None
|
Radii in mas of the first and last node; both or neither (default the disk's profile range). |
None
|
sigma
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
ell
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
mu
|
float
|
Standard deviation of \(g\), correlation length in mas, and mean of \(g\) (defaults 1, 1, 0). |
1.0
|
z
|
optional
|
Whitened latents, shape (n,) (default 0; its size is the number of
nodes), and the number of nodes when |
None
|
n
|
optional
|
Whitened latents, shape (n,) (default 0; its size is the number of
nodes), and the number of nodes when |
None
|
nu
|
optional
|
Matérn smoothness in {0.5, 1.5, 2.5, inf} (default 1.5) and relative jitter on the correlation diagonal (default 1e-6). Both static. |
1.5
|
jitter
|
optional
|
Matérn smoothness in {0.5, 1.5, 2.5, inf} (default 1.5) and relative jitter on the correlation diagonal (default 1e-6). Both static. |
1.5
|
Examples:
>>> alpha = RadialGPFunction(sigma=0.5, ell=4.0, n=12)
>>> alpha.z.shape
(12,)
draws(key, n=1, r=None, positive=False)
n draws from the prior at the radii r (the nodes by default).
Draws \(g = \mu + \sigma L z\) with \(z \sim N(0, I)\) at the current
mu, sigma, ell; with positive, \(\exp g\) (the
profile). Shape (n,) + shape(r). Use them to show the prior beside
the posterior.
nodes()
The nodes in milliarcseconds.
virgil.models.MultipoleKernel
Bases: Base
Matérn-kernel prior over the harmonics of a MultipoleDisk.
Provisional
May change in any 0.4.x release without a deprecation cycle.
A Matérn kernel in radius and azimuth over the azimuthal-harmonic
coefficients of a MultipoleDisk. Pass it
to Harmonics as prior=. Each order \(m = 1
\dots M\) is an independent
RadialGPFunction with radial length
ell_r; the variance falls with order as a periodic Matérn spectral
density of azimuthal length ell_theta (Model
notes). The mean is a uniform ring. Whitened
latents z have shape (2, M, n) (disk.harmonics.z,
standard-normal prior); log-uniform priors on the scales:
gp_priors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ell_r
|
float
|
Correlation length in the radius (mas), and in the azimuth (mas along
the ring at |
required |
ell_theta
|
float
|
Correlation length in the radius (mas), and in the azimuth (mas along
the ring at |
required |
sigma
|
float
|
Standard deviation of the first-order coefficients (default 0.3). |
0.3
|
r_in
|
float or None
|
Range of the radial processes (default the disk's profile extent) and
the radius converting |
None
|
r_out
|
float or None
|
Range of the radial processes (default the disk's profile extent) and
the radius converting |
None
|
r_ref
|
float or None
|
Range of the radial processes (default the disk's profile extent) and
the radius converting |
None
|
n
|
optional
|
Number of radial nodes (default 16), and Matérn smoothness in radius and azimuth in {0.5, 1.5, 2.5, inf} (default 1.5). All static. |
_GP_NODES
|
nu_r
|
optional
|
Number of radial nodes (default 16), and Matérn smoothness in radius and azimuth in {0.5, 1.5, 2.5, inf} (default 1.5). All static. |
_GP_NODES
|
nu_theta
|
optional
|
Number of radial nodes (default 16), and Matérn smoothness in radius and azimuth in {0.5, 1.5, 2.5, inf} (default 1.5). All static. |
_GP_NODES
|
Examples:
>>> prior = MultipoleKernel(ell_r=3.0, ell_theta=4.0, sigma=0.4)
>>> harmonics = Harmonics(degree=2, prior=prior)
>>> ring = GaussianRing(6.0, 1.5)
>>> disk = MultipoleDisk(ring, harmonics=harmonics, n_r=32)
>>> disk.harmonics.z.shape
(2, 2, 16)
spectrum(degree)
S(m) / S(1) for m = 1 .. degree: the variance of the
order-m coefficients relative to the first order's.
draws(key, degree, n=1, r=None)
n draws of the coefficients from the prior at the radii r
(the nodes by default): shape (n, 2, degree) + shape(r).
virgil.models.gp_priors(model, sigma=None, ell=None, ell_theta=None)
Priors for a scene's Gaussian-process parameters, for fit.
Provisional
May change in any 0.4.x release without a deprecation cycle.
For the Gaussian-process parts of a scene's
MultipoleDisks, for fit and
numpyro_model. Returns a dict from parameter path to prior for every
RadialGP profile,
RadialGPFunction (a harmonics
coefficient or the spectral index) and
MultipoleKernel in model (a disk, a
System or a rotated source). The whitened latents
z get independent standard-normal priors (the GP prior itself).
sigma (process standard deviations, kernel amplitude), ell (radial
correlation lengths) and ell_theta (the kernel's azimuthal length),
given as bounds (low, high), get log-uniform priors, so the prior and
the Laplace evidence are proper; left None the hyperparameters are
fixed at the model's values and not in the dict. Add priors for the other
free parameters yourself.
Examples:
>>> import numpyro.distributions as dist
>>> disk = MultipoleDisk(RadialGP(0.5, 12.0), n_r=24)
>>> scene = System(star=PointSource(), disk=disk)
>>> priors = gp_priors(scene, sigma=(0.1, 3.0), ell=(0.5, 8.0))
>>> sorted(priors)
['disk.profile.ell', 'disk.profile.sigma', 'disk.profile.z']