Skip to content

Composition: System and building blocks

See the Composing Models tutorial for usage.

virgil.models.System

Bases: SourceModel

Flux-weighted mixture of named source models.

A scene with several parts, e.g. a star with a disk. The visibility is \(V = \sum_i f_i V_i / \sum_i f_i\) with f_i each component's flux; it is 1 at zero baseline, so only flux ratios are measurable: keep one reference (usually the star) at flux=1. Components are reached by name, as attributes and as zodiax paths (system.get("comp.flux"); set returns a new System). A System can be a component: flux is then the group's weight and dra/ddec move the group. Fluxes must be non-negative and not all zero, checked only for concrete values at build (traced code relies on priors and grid axes to keep them valid). See Composing models.

Parameters:

Name Type Description Default
components dict[str, SourceModel]

Components by name; keyword arguments are usually clearer.

None
flux float or array - like

Weight of the whole system when nested (default 1; no effect at top level) and its offset in mas (positive to the East and North).

1.0
dra float or array - like

Weight of the whole system when nested (default 1; no effect at top level) and its offset in mas (positive to the East and North).

1.0
ddec float or array - like

Weight of the whole system when nested (default 1; no effect at top level) and its offset in mas (positive to the East and North).

1.0
**named SourceModel

Components as keywords, e.g. star=PointSource(); names must be valid identifiers, not start with _ and not clash with a System attribute.

{}

Examples:

>>> comp = PointSource(dra=45.0, ddec=30.0, flux=0.01)
>>> binary = System(star=PointSource(), comp=comp)
>>> binary.comp
PointSource(flux=0.01, dra=45, ddec=30)

model(u, v, wavel)

virgil.models.smeared_model(model, u, v, wavel, bandwidth)

Complex visibilities with bandwidth smearing (boxcar channels).

A channel of full width \(\Delta\lambda\) multiplies each component's offset phasor by the real envelope \(\mathrm{sinc}(\pi\,\Delta\lambda\,(u\,\mathrm{dra} + v\,\mathrm{ddec})/\lambda^2)\) (\(u\), \(v\) in metres, offsets in radians), per component of a System before the weights are applied (offsets add down nested systems). First order: weights and shapes are taken at the channel centre and an extended component is smeared as if at its centre offset. Supported: System trees of Component shapes, Resolved, the binary models (smeared as their to_system()) and Rotated scenes of these (the baselines are rotated). Others, including Image and an OrbitalBinary (smear its at(mjd) snapshot, as OIData does), raise TypeError naming the model. OIData calls this when its bandwidth is set (read from EFF_BAND, or by with_bandwidth). See Bandwidth smearing.

Parameters:

Name Type Description Default
model System or Component
required
u array - like

Baselines and wavelengths in metres, as for model.model.

required
v array - like

Baselines and wavelengths in metres, as for model.model.

required
wavel array - like

Baselines and wavelengths in metres, as for model.model.

required
bandwidth array - like

Full channel width in metres, broadcast against u.

required

virgil.models.Component

Bases: SourceModel

Base class for single shapes with flux, dra and ddec.

A component on its own is normalized to unit flux. New shapes subclass it and implement _centred_cvis (the unit-flux visibility of the shape at the origin) and _centred_image (an un-normalized image at the origin); offsets and mixing are handled here.

Parameters:

Name Type Description Default
flux (float, array - like or Spectrum)

Weight relative to the other components of a System, or a spectrum from virgil.spectra (default 1). With the reference star at flux=1 a companion's flux is its companion/star flux ratio.

required
dra float or array - like

Offset of the centre in milliarcseconds, positive dra to the East and ddec to the North.

required
ddec float or array - like

Offset of the centre in milliarcseconds, positive dra to the East and ddec to the North.

required

virgil.models.PointSource

Bases: Component

Unresolved point source.

Parameters:

Name Type Description Default
flux optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
dra optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
ddec optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0

Examples:

>>> star = PointSource()
>>> companion = PointSource(flux=0.01, dra=45.0, ddec=30.0)

virgil.models.GaussianDisk

Bases: Component

Circular Gaussian brightness distribution.

Parameters:

Name Type Description Default
sigma float or array - like

Standard deviation of the Gaussian in milliarcseconds (FWHM = 2.3548 sigma, FWHM_PER_SIGMA).

required
flux optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
dra optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
ddec optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0

Examples:

>>> halo = GaussianDisk(sigma=8.0, flux=0.2)

virgil.models.EllipticalGaussian

Bases: Component

Elliptical Gaussian brightness distribution.

Parameters:

Name Type Description Default
fwhm float or array - like

Full width at half maximum along the major axis, in milliarcseconds.

required
ratio float or array - like

Minor-to-major axis ratio, in (0, 1]; 1 is a circular Gaussian.

1.0
pa float or array - like

Position angle of the major axis in degrees, North to East.

0.0
flux optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
dra optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
ddec optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0

Examples:

>>> plume = EllipticalGaussian(fwhm=30.0, ratio=0.5, pa=20.0, flux=2.0)

virgil.models.GaussianArc

Bases: Component

A ridge bent along a circular arc, e.g. a curved shock front.

A circle of radius about the centre of curvature (dra, ddec), blurred by a Gaussian of FWHM width and weighted along it by a von Mises function of position angle, brightest at pa; length is the FWHM of that weight as an arc length, for an arc short against its radius. A MultipoleDisk with a ThinRing profile: Model notes.

Parameters:

Name Type Description Default
radius float or array - like

Radius of curvature, FWHM across the arc, FWHM along it (mas), and position angle of the brightest point (degrees North to East).

required
width float or array - like

Radius of curvature, FWHM across the arc, FWHM along it (mas), and position angle of the brightest point (degrees North to East).

required
length float or array - like

Radius of curvature, FWHM across the arc, FWHM along it (mas), and position angle of the brightest point (degrees North to East).

required
pa float or array - like

Radius of curvature, FWHM across the arc, FWHM along it (mas), and position angle of the brightest point (degrees North to East).

required
flux optional

As for any Component; the offset is the centre of curvature.

1.0
dra optional

As for any Component; the offset is the centre of curvature.

1.0
ddec optional

As for any Component; the offset is the centre of curvature.

1.0
nodes int

Points sampling the arc, at least 2 (default 128; used by the image always, by the visibilities on the quadrature path only), and the highest von Mises harmonic (static; default from the starting radius and length, or 32 if traced).

128
degree int

Points sampling the arc, at least 2 (default 128; used by the image always, by the visibilities on the quadrature path only), and the highest von Mises harmonic (static; default from the starting radius and length, or 32 if traced).

128

Examples:

>>> shock = GaussianArc(radius=30.0, width=2.0, length=40.0, pa=270.0)

virgil.models.TruncatedCone

Bases: Component

A thin conical shell truncated near its apex, e.g. a dust cone.

The axis points towards position angle pa, tilted tilt degrees out of the sky plane, with half-opening angle alpha. Emission starts a slant distance s0 from the apex and falls as exp(-(s - s0) / length) across a Gaussian shell of FWHM width. A MultipoleDisk of rings: Model notes.

Parameters:

Name Type Description Default
tip float or array - like

Apex distance back along the axis from (dra, ddec); slant start of emission; e-folding length along the walls; shell FWHM; all in mas.

required
s0 float or array - like

Apex distance back along the axis from (dra, ddec); slant start of emission; e-folding length along the walls; shell FWHM; all in mas.

required
length float or array - like

Apex distance back along the axis from (dra, ddec); slant start of emission; e-folding length along the walls; shell FWHM; all in mas.

required
width float or array - like

Apex distance back along the axis from (dra, ddec); slant start of emission; e-folding length along the walls; shell FWHM; all in mas.

required
alpha float or array - like

Half-opening angle in degrees (0 < alpha < 90).

required
tilt float or array - like

Axis angle out of the sky plane (-90 to 90) and position angle the cone opens towards (North to East), both in degrees (default 0).

0.0
pa float or array - like

Axis angle out of the sky plane (-90 to 90) and position angle the cone opens towards (North to East), both in degrees (default 0).

0.0
ratio float or array - like

Axis ratio of the cross-section (default 1, circular).

1.0
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0
n_rings int

Gauss-Legendre rings along the walls, at least 2 (default 48); check convergence by doubling.

48
az_amps float or array - like

Cosine modulation amplitudes of the walls, first order up (sum(abs(az_amps)) <= 1 keeps the brightness non-negative; default none), and their azimuths in degrees in the ring plane (pa + 90 and pa - 90 are the walls at those position angles).

()
az_pas float or array - like

Cosine modulation amplitudes of the walls, first order up (sum(abs(az_amps)) <= 1 keeps the brightness non-negative; default none), and their azimuths in degrees in the ring plane (pa + 90 and pa - 90 are the walls at those position angles).

()

Examples:

>>> cone = TruncatedCone(
...     tip=5.0, alpha=30.0, s0=4.0, length=10.0, width=1.0
... )

virgil.models.UniformDisk

Bases: Component

Uniformly bright (tophat) circular disk, e.g. a resolved stellar photosphere.

Parameters:

Name Type Description Default
diam float or array - like

Angular diameter in milliarcseconds.

required
flux optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
dra optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0
ddec optional

Relative weight (or spectrum) and sky offset in milliarcseconds, as for any Component.

1.0

Examples:

>>> photosphere = UniformDisk(diam=3.0)

virgil.models.LimbDarkenedDisk

Bases: _LimbDarkenedDisk

Circular disk with polynomial limb darkening of order up to 22.

The brightness is \(I(\mu) / I(1) = 1 - \sum_{n=1}^{N} u_n (1 - \mu)^n\), with \(\mu = \sqrt{1 - (r / R)^2}\); u is the same as a jaxoplanet Surface's u (u=(u1,) linear, u=(u1, u2) quadratic, default () a uniform disk). For quadratic priors covering exactly the physical profiles use QuadraticLimbDarkenedDisk. The order is at most 22, as the Bessel functions needed are of order at most 12. The visibility is analytic (cvis_limb_darkened_disk).

Source: Quirrenbach et al. (1996), eq. 3, references; harmonix, Dholakia & Pope 2025.

Parameters:

Name Type Description Default
diam float or array - like

Limb-darkened angular diameter (of the stellar limb) in mas.

required
u sequence of float

Coefficients \(u_1, \ldots, u_N\), a 1D array of fixed length (the order, at most 22); default none. is_physical is false where the profile goes negative.

()
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

Examples:

>>> quadratic = LimbDarkenedDisk(3.0, u=[0.4, 0.25])

virgil.models.QuadraticLimbDarkenedDisk

Bases: _LimbDarkenedDisk

Circular disk with quadratic limb darkening in Kipping's \(q_1, q_2\).

The brightness is \(I(\mu) / I(1) = 1 - u_1 (1 - \mu) - u_2 (1 - \mu)^2\), with \(u_1 = 2 \sqrt{q_1}\, q_2\) and \(u_2 = \sqrt{q_1}\,(1 - 2 q_2)\). Every \((q_1, q_2)\) in the unit square gives a profile that is positive and decreases from the centre to the limb, and every such profile has one, so uniform priors on \([0, 1]\) are uninformative over exactly the physical laws. The visibility is analytic (cvis_limb_darkened_disk).

Source: Kipping (2013), eqs. 15-16, references.

Parameters:

Name Type Description Default
diam float or array - like

Limb-darkened angular diameter in mas.

required
q1 float or array - like

Kipping's coefficients, each in \([0, 1]\); \(q_1 = 0\) is a uniform disk. Start a fit inside the square, not on its edges: fit maps Uniform priors to unbounded variables, so the edges map to infinity (and \(\sqrt{q_1}\) has an infinite derivative at 0).

required
q2 float or array - like

Kipping's coefficients, each in \([0, 1]\); \(q_1 = 0\) is a uniform disk. Start a fit inside the square, not on its edges: fit maps Uniform priors to unbounded variables, so the edges map to infinity (and \(\sqrt{q_1}\) has an infinite derivative at 0).

required
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

Examples:

>>> import numpyro.distributions as dist
>>> star = QuadraticLimbDarkenedDisk(3.0, q1=0.4, q2=0.3)
>>> priors = {
...     "diam": dist.LogUniform(2.0, 4.0),  # a scale: log-uniform
...     "q1": dist.Uniform(0.0, 1.0),  # Kipping's uniform prior
...     "q2": dist.Uniform(0.0, 1.0),
... }
>>> star = QuadraticLimbDarkenedDisk.from_u(3.0, u1=0.4, u2=0.25)

from_u(diam, u1, u2, **kwargs) classmethod

Build from the usual \(u_1, u_2\) (Kipping 2013, eqs. 17-18).

virgil.models.SquareRootLimbDarkenedDisk

Bases: _LimbDarkenedDisk

Circular disk with square-root limb darkening in Kipping's \(q_1, q_2\).

The brightness is \(I(\mu) / I(1) = 1 - c (1 - \mu) - d (1 - \sqrt{\mu})\), which suits late-type stars in the near-infrared better than the quadratic law (van Hamme 1993), with \(c = \sqrt{q_1}\,(1 - 2 q_2)\) and \(d = 2 \sqrt{q_1}\, q_2\). As for QuadraticLimbDarkenedDisk, the unit square in \((q_1, q_2)\) is exactly the positive profiles that decrease towards the limb, so uniform priors on \([0, 1]\) are uninformative. The visibility is analytic (cvis_limb_darkened_disk).

Source: Díaz-Cordovés & Giménez (1992), references; Kipping (2013), eqs. 23-24 inverted.

Parameters:

Name Type Description Default
diam float or array - like

Limb-darkened angular diameter in mas.

required
q1 float or array - like

Kipping's coefficients, each in \([0, 1]\); \(q_1 = 0\) is a uniform disk. Start a fit inside the square, not on its edges: fit maps Uniform priors to unbounded variables, so the edges map to infinity (and \(\sqrt{q_1}\) has an infinite derivative at 0).

required
q2 float or array - like

Kipping's coefficients, each in \([0, 1]\); \(q_1 = 0\) is a uniform disk. Start a fit inside the square, not on its edges: fit maps Uniform priors to unbounded variables, so the edges map to infinity (and \(\sqrt{q_1}\) has an infinite derivative at 0).

required
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

Examples:

>>> star = SquareRootLimbDarkenedDisk(3.0, q1=0.5, q2=0.4)
>>> same = SquareRootLimbDarkenedDisk.from_cd(3.0, c=star.c, d=star.d)

from_cd(diam, c, d, **kwargs) classmethod

Build from the usual \(c, d\) (Kipping 2013, eqs. 23-24).

virgil.models.EllipticalLimbDarkenedDisk

Bases: _LimbDarkenedDisk

Limb-darkened disk with an elliptical outline, e.g. an oblate star.

A LimbDarkenedDisk compressed along its minor axis, with the profile \(I(\mu)/I(1) = 1 - \sum_n u_n (1 - \mu)^n\) following the outline (\(\mu = \sqrt{1 - \rho^2}\), \(\rho\) the elliptical radius). Unit flux on its own; the visibility is the circular disk's at frequencies stretched by ratio. A geometric ellipse, not gravity darkening (use GravityDarkenedStar).

Parameters:

Name Type Description Default
diam float or array - like

Angular diameter of the limb along the major axis, in mas.

required
ratio float or array - like

Minor-to-major axis ratio in (0, 1] (default 1) and position angle of the major axis in degrees North to East (default 0).

1.0
pa float or array - like

Minor-to-major axis ratio in (0, 1] (default 1) and position angle of the major axis in degrees North to East (default 0).

1.0
u sequence of float

Coefficients as in LimbDarkenedDisk (default uniform); is_physical is false where the profile goes negative.

()
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

Examples:

>>> star = EllipticalLimbDarkenedDisk(5.5, ratio=0.8, pa=30.0, u=[0.5])

virgil.models.GravityDarkenedStar

Bases: Component

Rapidly rotating star: Roche shape and gravity darkening (ELR11).

A rigidly rotating star with the oblate Roche shape and local bolometric flux following the effective gravity (no free exponent, no limb darkening), summed over the visible triangles of a surface mesh: see the tutorial and Model notes (chromatic mode, the mapping to the original parameters, accuracy of n_lat).

Source: Espinosa Lara & Rieutord (2011), via GDit, references.

Parameters:

Name Type Description Default
diam_eq float or array - like

Equatorial angular diameter in mas.

required
omega float or array - like

Angular velocity as a fraction of the critical rate, in [0, 1) (default 0).

0.0
inc float or array - like

Inclination in degrees, 0 pole-on to 90 equator-on (default 90), and position angle of the visible pole in degrees North through East (default 0).

90.0
pa float or array - like

Inclination in degrees, 0 pole-on to 90 equator-on (default 90), and position angle of the visible pole in degrees North through East (default 0).

90.0
flux optional

As for any Component; in chromatic mode flux must be a number, not a Spectrum.

1.0
dra optional

As for any Component; in chromatic mode flux must be a number, not a Spectrum.

1.0
ddec optional

As for any Component; in chromatic mode flux must be a number, not a Spectrum.

1.0
n_lat int

Latitude rings of the mesh (default 32, 2520 triangles); cost O(n_lat\(^2\)) per baseline, error falls as 1 / n_lat**2; check by doubling.

32
t_pole float or array - like

Polar effective temperature in kelvin (None, the default, is the grey model; a value switches on the chromatic Planck model) and the reference wavelength in metres (default 1.65e-6) where the spectrum is normalized to flux, shown by render.

None
wavel0 float or array - like

Polar effective temperature in kelvin (None, the default, is the grey model; a value switches on the chromatic Planck model) and the reference wavelength in metres (default 1.65e-6) where the spectrum is normalized to flux, shown by render.

None

Examples:

>>> star = GravityDarkenedStar(2.0, omega=0.8, inc=60.0, pa=30.0)
>>> v0 = star.model(np.zeros(1), np.zeros(1), 1.65e-6)
>>> round(float(np.abs(v0)[0]), 3)
1.0

plot_surface(ax=None, cmap='plasma')

Plot the visible surface, coloured by its local brightness.

That is the bolometric flux in grey mode, and the Planck intensity at wavel0 in chromatic mode. East is to the left and North up, as in plot_model; the offset dra, ddec is not applied. Returns the matplotlib collection.

virgil.models.ModulatedGaussianRim

Bases: Component

Azimuthally modulated, infinitely thin rim convolved with a Gaussian.

The rim is defined in its own plane, blurred by a Gaussian isotropic there, then inclined by inc and rotated to pa. az_pas are angles in that plane, not on-sky position angles (Model notes). Achromatic and star-free: add a PointSource in a System.

Parameters:

Name Type Description Default
diam float or array - like

Rim diameter, and Gaussian FWHM in the rim plane (fwhm along the projected major axis, fwhm * cos(inc) along the minor axis on the sky), in mas.

required
fwhm float or array - like

Rim diameter, and Gaussian FWHM in the rim plane (fwhm along the projected major axis, fwhm * cos(inc) along the minor axis on the sky), in mas.

required
inc float or array - like

Apparent inclination, and position angle of the projected major axis (North to East), in degrees.

required
pa float or array - like

Apparent inclination, and position angle of the projected major axis (North to East), in degrees.

required
az_amps float or array - like

Cosine modulation amplitudes, first order up (default none; sum(abs(az_amps)) <= 1 keeps the brightness non-negative), and their azimuths in degrees in the rim plane, in the sense of position angle with pa on the major axis.

()
az_pas float or array - like

Cosine modulation amplitudes, first order up (default none; sum(abs(az_amps)) <= 1 keeps the brightness non-negative), and their azimuths in degrees in the rim plane, in the sense of position angle with pa on the major axis.

()
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

Examples:

>>> rim = ModulatedGaussianRim(
...     diam=40.0, fwhm=4.0, inc=50.0, pa=30.0, az_amps=0.7, az_pas=120.0
... )

virgil.models.FlaredDisk

Bases: _PixelRendered

Flared, inclined scattered-light disk: a skewed Gaussian ring.

Abstract base with a forward-scattering peak on the near side; use FlaredDiskHG, FlaredDiskGaussian or FlaredDiskPowerLaw. No star or planets: compose them in a System. The visibilities are the exact Fourier transform of the brightness on a fixed npix x npix grid, which must cover the disk and resolve its inner edge (Model notes); it follows the empirical \(\sin i\) surface projection of Blakely et al. (2024), whereas MultipoleDisk with PowerLawHeight uses the exact \(\tan i\) thin-surface projection.

Source: Blakely et al. (2024), §III, references.

Parameters:

Name Type Description Default
radius float or array - like

Radius of peak brightness (before the skew moves it outwards) and radial FWHM, in mas; inclination, 0 (face-on) up to but not including 90, and position angle of the projected major axis (the near side is at pa + 90), in degrees.

required
fwhm float or array - like

Radius of peak brightness (before the skew moves it outwards) and radial FWHM, in mas; inclination, 0 (face-on) up to but not including 90, and position angle of the projected major axis (the near side is at pa + 90), in degrees.

required
inc float or array - like

Radius of peak brightness (before the skew moves it outwards) and radial FWHM, in mas; inclination, 0 (face-on) up to but not including 90, and position angle of the projected major axis (the near side is at pa + 90), in degrees.

required
pa float or array - like

Radius of peak brightness (before the skew moves it outwards) and radial FWHM, in mas; inclination, 0 (face-on) up to but not including 90, and position angle of the projected major axis (the near side is at pa + 90), in degrees.

required
npix (int, float)

Pixels on a side of the grid (even, so no pixel centre is on the star), and their size in mas.

required
pixel_scale_mas (int, float)

Pixels on a side of the grid (even, so no pixel centre is on the star), and their size in mas.

required
ft (auto, dft, nufft)

Transform for irregular uv points (see set_ft_defaults).

"auto"
rotation_deg grid or float

Position angle of the grid's "up" axis: "grid" (default) follows the data's uv lattice (exact two-sided matrix transform), else North up; a number fixes it.

'grid'
skew float or array - like

Inner-edge truncation (default 0), aspect ratio \(z/\rho\) at radius (default 0, flat), flaring index (1.25), axisymmetric brightness relative to the phase function (0).

0.0
aspect float or array - like

Inner-edge truncation (default 0), aspect ratio \(z/\rho\) at radius (default 0, flat), flaring index (1.25), axisymmetric brightness relative to the phase function (0).

0.0
flaring float or array - like

Inner-edge truncation (default 0), aspect ratio \(z/\rho\) at radius (default 0, flat), flaring index (1.25), axisymmetric brightness relative to the phase function (0).

0.0
symmetric float or array - like

Inner-edge truncation (default 0), aspect ratio \(z/\rho\) at radius (default 0, flat), flaring index (1.25), axisymmetric brightness relative to the phase function (0).

0.0
flux optional

As for any Component.

1.0
dra optional

As for any Component.

1.0
ddec optional

As for any Component.

1.0

virgil.models.FlaredDiskHG

Bases: FlaredDisk

FlaredDisk with a Henyey–Greenstein phase function.

\(f(\theta) = \dfrac{1 - g^2}{4\pi\,(1 + g^2 - 2g\cos\theta)^{3/2}}\) (Blakely et al. 2024, Eq. 6).

Parameters:

Name Type Description Default
g float or array - like

Asymmetry parameter, with -1 < g < 1: 0 is isotropic, positive values scatter forwards (peaking on the near side) and negative values backwards (peaking on the far side).

required
**geometry

The parameters of FlaredDisk.

{}

Examples:

>>> disk = FlaredDiskHG(
...     g=0.3, radius=440.0, fwhm=290.0, inc=52.0, pa=160.0,
...     npix=96, pixel_scale_mas=20.0, flux=0.05,
... )

virgil.models.FlaredDiskGaussian

Bases: FlaredDisk

FlaredDisk with a Gaussian phase function.

\(f(\theta) = \exp\left(-\theta^2 / 2\sigma_\theta^2\right)\), with \(\theta \in (-180°, 180°]\) (Blakely et al. 2024, Eq. 7).

Parameters:

Name Type Description Default
sigma_theta float or array - like

Azimuthal width in degrees.

required
**geometry

The parameters of FlaredDisk.

{}

virgil.models.FlaredDiskPowerLaw

Bases: FlaredDisk

FlaredDisk with a power-law phase function.

\(f(\theta) = \cos^N(\theta / 2)\), with \(\theta \in (-180°, 180°]\) (Blakely et al. 2024, Eq. 8), the best-fitting form for PDS 70.

Parameters:

Name Type Description Default
n float or array - like

Power \(N\); larger is more concentrated towards the near side.

required
**geometry

The parameters of FlaredDisk.

{}

virgil.models.Resolved

Bases: SourceModel

Fully resolved (over-resolved) flux, e.g. a large, diffuse envelope.

Its visibility is 0 on every non-zero baseline, so inside a System it only adds to the normalization, lowering every other component's visibility by the same factor. It cannot be rendered on its own, and a rendered System shows only its other components, renormalized to unit sum, so the transform of that image is model() divided by the unresolved flux fraction.

Parameters:

Name Type Description Default
flux (float, array - like or Spectrum)

Weight relative to the other components of a System (default 1), or a spectrum from virgil.spectra.

1.0

Examples:

>>> scene = System(star=PointSource(), background=Resolved(flux=0.1))

virgil.models.Rotated

Bases: SourceModel

A model rotated on the sky about the phase centre.

The rotation is by rotation_deg from North towards East, and the angle is an ordinary (fittable) parameter, unlike Image's rotation_deg, which only orients its pixel grid. Use it for a scene seen at several epochs, e.g. a spiral rotating between them (see fit with a model per dataset).

Parameters:

Name Type Description Default
source SourceModel

The model to rotate.

required
rotation_deg float

Position angle of the rotation, North towards East, in degrees.

required

Examples:

>>> north = System(a=GaussianDisk(1.0), b=GaussianDisk(1.0, ddec=10.0))
>>> east = System(a=GaussianDisk(1.0), b=GaussianDisk(1.0, dra=10.0))
>>> u, v = np.array([3.0, 5.0]), np.array([1.0, -2.0])
>>> rotated = Rotated(north, 90.0).model(u, v, 1e-6)
>>> bool(np.allclose(rotated, east.model(u, v, 1e-6), atol=1e-6))
True

source = source instance-attribute

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

time_dependent property

broadcast_in_time property

__init__(source, rotation_deg)

model(u, v, wavel)

resolved()

total_spectrum(wavel)

is_physical()

at(mjd, t_ref=0.0)

virgil.models.Attached

Bases: SourceModel

A component placed and oriented in the frame of a binary's orbit.

At each time the component moves to its anchor on the orbit and its angle attributes are set from angles of the binary frame (KeplerOrbit.frame). A companion is Attached(PointSource(flux), orbit); a disc around it in the orbital plane, brighter towards the primary, is Attached(ModulatedGaussianRim(...), orbit, bind={"pa": "node_pa", "inc": "apparent_inc", "az_pas": "towards_primary"}). Time-dependent, so evaluated through at; OIData.model uses each sample's time. Share one orbit between components via shared parameters in a model function (fit).

Parameters:

Name Type Description Default
component Component

The component (its dra, ddec and bound angles are set).

required
orbit KeplerOrbit

The orbit of the secondary about the primary (the scene's origin).

required
anchor (secondary, primary)

Where the component sits: the secondary (default), the primary, or this fraction of the way from primary to secondary (q / (1 + q) for the barycentre).

"secondary"
bind dict

{attribute: frame angle} from line_pa, towards_primary, line_tilt, node_pa, inc, apparent_inc. An az_pas binding is a sky position angle, converted to the rim angle after pa and inc are set.

None
offsets dict

{attribute: degrees} added to the bound angles (fittable); default zero.

None

at(mjd, t_ref=0.0)

virgil.models.OrbitalBinary

Bases: SourceModel

A primary and a point-source companion moving on a Keplerian orbit.

The time-dependent form of BinaryModelCartesian: at returns the BinaryModelCartesian with the companion at the orbit's sky position, so each snapshot keeps the fast binary path. The same scene as System(primary=PointSource(), companion=Attached(PointSource(flux), orbit)). The primary is the scene's origin and reference. Evaluate it with one snapshot per dataset or epoch through Epochs, or per sample by OIData.model.

Parameters:

Name Type Description Default
orbit KeplerOrbit

The companion's orbit about the primary (any orbit class with t_ref and _relative).

required
flux float

Companion/primary flux ratio.

required

Examples:

>>> from virgil.models import OrbitalBinary
>>> from virgil.orbits import KeplerOrbit
>>> orbit = KeplerOrbit(700.0, 0.0, 0.3, 50.0, 60.0, 120.0, 20.0,
...                     t_ref=60500.0)
>>> snap = OrbitalBinary(orbit, 0.1).at(60500.0)
>>> type(snap).__name__, round(float(snap.flux), 2)
('BinaryModelCartesian', 0.1)

at(mjd, t_ref=0.0)

Models are fitted through virgil.likelihood (build_model, loglike, numpyro_model).