pizzetti
Fast limb-darkened transit light curves, with an elementary series and a proven error bound.
pizzetti computes exoplanet (and exomoon) transit light curves through the same interface as
batman. Code written for batman runs unchanged after a
one-line change:
import pizzetti as batman
Why it is fast
Since Mandel & Agol (2002), transit codes have evaluated complete elliptic integrals of all three
kinds, or integrated the stellar disk numerically, at every point of the light curve. pizzetti
does not need any of that for the main part of a transit.
While the planet is entirely inside the stellar disk, between second and third contact, the flux
has an elementary form: sqrt(1 - z²) times a polynomial in 1/(1 - z²). Its coefficients
depend only on the radius ratio, so they are computed once per light curve. Each in-transit point
then costs one square root, one division and a dozen multiply–adds. There are no branches, no
iterations and no special cases.
| elliptic-integral solution | pizzetti interior series | |
|---|---|---|
| square roots + divisions per point | ~14 | 2 |
| time per point (vectorised, numba) | 10.8 ns | 0.97 ns |
For an Earth-sized planet crossing a Sun-like star, the series covers 96–98 % of the in-transit points (central transit: 98 %; averaged over impact parameters: 96 %). The few points that touch the stellar limb use an exact, vectorised Mandel & Agol solver (uniform, linear and quadratic laws) or, for the other laws, power series about first and second contact with coefficients computed once per light curve (accurate to ~1e-15, 15-22x faster per sample than quadrature, radius ratios up to ~0.2). Short light curves and larger occulters use a Green's-theorem quadrature with a Gauss–Jacobi rule for the endpoint singularity at the limb (~1e-16).
Proven correctness
- The error bound is proven, not estimated. All terms of the series have the same sign, which gives a closed-form bound on the truncation error. The bound increases monotonically along the transit chord, so a single cut per light curve guarantees the requested accuracy. The default is 10⁻⁹ of the stellar flux, i.e. 0.001 ppm.
- It is verified against a 40-digit reference. Every law agrees with an independent mpmath quadrature to 2 × 10⁻⁹, including points within 10⁻¹⁵ of the contact points, at z = 0 and at z = rp.
- It is more accurate than batman. For the power-2 and nonlinear laws batman's adaptive
integration leaves errors of ~10⁻⁷ even at its tightest setting;
pizzettistays below 10⁻⁹. Kepler's equation is solved to 10⁻¹⁵ instead of 10⁻⁷. - The limb can be proven too. With
limb="proven"the contact expansions are split into pieces whose degrees are chosen so that their flux error is also proven to be belowseries_tol(radius ratios up to ~0.2 at 10⁻⁹, ~0.15 at 10⁻¹²). The proof costs 5–60 ms of set-up per light curve, so it is opt-in;occult(..., return_certified=True)reports which samples it covers. The default (limb="fast") uses the same expansions at fixed order with an estimated error of ~10⁻¹⁵.
Inference
Same posterior, less time. Two synthetic data sets were fitted with emcee, once with batman and once with pizzetti, with identical likelihoods, starting positions and random numbers (examples/inference, paper Section 6.4):
| hot Jupiter, TESS 2-min, quadratic law | super-Earth, Kepler 1-min, power-2 law | |
|---|---|---|
| largest difference of the posterior medians | 0.08 σ | 0.04 σ |
| model error over the posterior, batman / pizzetti | 9 × 10⁻⁹ / 7 × 10⁻¹⁰ | 1.9 × 10⁻⁶ / 5 × 10⁻¹⁰ |
| one likelihood evaluation, batman / pizzetti | 0.130 / 0.029 ms (4.5×) | 1.10 / 0.57 ms (1.9×) |
| 2000-step emcee run, batman / pizzetti | 9.8 / 3.0 s | 67 / 34 s |
The posteriors agree within their Monte Carlo noise. To come close to pizzetti's accuracy for the
power-2 law, batman needs max_err=0.01, at 6.1 ms per evaluation (still off by 4 × 10⁻⁸). The
Julia version computes the gradient of either likelihood with respect to all seven parameters in
about ten likelihood evaluations (julia/).
Notebooks: drop-in replacement in an emcee fit, power-2 super-Earth.
Speed against batman
Single thread, 10⁵ points, about 30 % of them in transit (benchmarks/benchmark.py, Intel Xeon
2.8 GHz, numba 0.68). "Full" means that every call also recomputes the orbit, as in a fit.
| law | rp | batman | pizzetti | speed-up | batman (full) | pizzetti (full) | speed-up |
|---|---|---|---|---|---|---|---|
| quadratic | 0.0092 | 2.42 ms | 0.15 ms | 17× | 5.96 ms | 0.40 ms | 15× |
| quadratic | 0.1 | 3.01 ms | 0.32 ms | 9.5× | 6.57 ms | 0.61 ms | 11× |
| nonlinear | 0.0092 | 3.13 ms | 1.07 ms | 2.9× | 6.69 ms | 1.41 ms | 4.8× |
| nonlinear | 0.1 | 57.1 ms | 2.73 ms | 21× | 67.4 ms | 3.87 ms | 17× |
| power2 | 0.0092 | 2.00 ms | 0.83 ms | 2.4× | 5.25 ms | 1.16 ms | 4.5× |
| power2 | 0.1 | 35.9 ms | 1.77 ms | 20× | 39.7 ms | 2.13 ms | 19× |
For the quadratic law, pizzetti skips blocks of samples that are entirely off the star (separation
≥ 1 + rp, flux exactly 1) without evaluating the series. This matters most for long light curves
with a small transit duty cycle: with 3 % of the points in transit
(python benchmarks/benchmark.py --half-width 2.5) the quadratic flux takes 0.09 ms (rp = 0.0092)
and 0.11 ms (rp = 0.1) for 10⁵ points, 7× and 6.5× faster than batman, and 2.7× and 2.4× faster than
before the block skipping.
batman's numerical laws (nonlinear, power2) run at its default tolerance of 1 ppm; pizzetti's errors stay below 10⁻⁹. In a complete emcee fit the likelihood is 1.9–4.5 times faster (examples/inference).
Installation
pip install pizzetti # recommended
pip install git+https://github.com/hippke/pizzetti # latest dev build
Requirements: Python ≥ 3.9, NumPy, numba. The first call compiles the kernels (a few seconds); they are cached on disk afterwards.
Usage
import pizzetti
import numpy as np
import matplotlib.pyplot as plt
params = pizzetti.TransitParams()
params.t0 = 0.0 # time of inferior conjunction
params.per = 3.0 # orbital period
params.rp = 0.1 # planet radius (stellar radii)
params.a = 15.0 # semi-major axis (stellar radii)
params.inc = 88.0 # inclination (degrees)
params.ecc = 0.0 # eccentricity
params.w = 90.0 # argument of periapse (degrees)
params.u = [0.4, 0.25] # limb-darkening coefficients
params.limb_dark = "quadratic"
t = np.linspace(-0.1, 0.1, 10_000)
m = pizzetti.TransitModel(params, t)
flux = m.light_curve(params)
plt.plot(t, flux)
plt.xlabel("Time from mid-transit (days)")
plt.ylabel("Relative flux")
plt.show()
The low-level function works on separations directly:
z = np.linspace(0, 1.2, 1000) # projected separation (stellar radii)
f = pizzetti.occult(z, 0.1, [0.4, 0.25], "quadratic")
z_c = pizzetti.series_cut(0.1, "quadratic", [0.4, 0.25]) # series used for z <= z_c
batman features supported
TransitParamsandTransitModelwith the same attributes and methods:light_curve,get_t_periastron,get_t_secondary,get_t_conjunction,get_true_anomalyandcalc_err.- Limb-darkening laws:
uniform,linear,quadratic,squareroot,nonlinear(four-parameter) andpower2. - Circular and eccentric orbits, supersampling (
supersample_factor,exp_time), secondary eclipses (transittype="secondary",fp,t_secondary) and inverse transits (rp < 0). - Not supported: the
logarithmic,exponentialandcustomlaws. They are not sums of powers of μ, sopizzettiraisesNotImplementedErrorfor them.
Examples and inference
examples/ has notebooks that fit synthetic TESS- and Kepler-like light curves with emcee,
once with batman and once with pizzetti (same likelihood, starting points and random numbers). The posteriors
agree within their Monte Carlo noise; the likelihood evaluations are 2.4x (quadratic law, hot Jupiter) and
1.4x (power-2 law, super-Earth) faster, and pizzetti's model error over the posterior is below 1e-9, against
9e-9 and 1.9e-6 for batman. See examples/inference for the full runs.
Julia
julia/ contains Pizzetti.jl, a Julia implementation of the same methods with
ForwardDiff support (exact derivatives of the flux from the paper's Section 5.4), BigFloat evaluation,
rigorous interval enclosures, and Limbdark.jl's transit_poly interface.
Documentation
The full documentation, covering the method, the accuracy proofs and checks, the benchmarks and
the API, is on Read the Docs and in docs/.
The name pizzetti
The series is the two-dimensional form of the mean-value expansion of Paolo Pizzetti (1860–1918). He gave the mean of a function over a sphere as a series of its iterated Laplacians, with an exact remainder (Rend. Lincei 18, 1909). Pizzetti was an Italian geodesist and mathematician; geodesists still use the Somigliana–Pizzetti formula for normal gravity on the reference ellipsoid. A century later, his formula turns the transit of a planet into a polynomial.
Citing
If you use pizzetti, please cite the accompanying paper (in preparation) and Mandel & Agol
(2002). See CITATION.cff.
Metadata
Release files for pizzetti 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pizzetti-0.2.1.tar.gz | 63.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pizzetti-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 122.0 kB
Release files / pizzetti-0.2.1.tar.gz
| Download URL | pizzetti-0.2.1.tar.gz |
|---|---|
| Size | 63.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2d8c313c2c3a8f84bcf12b92841fd2cfd5b8b2bb4463ab689b8a6f58b22f3af
|
|
BLAKE2b-256 checksum How to use checksums |
cbff4c243bdfa7efcf48499a5396ae570a66f9dca4c734b39576918571985942
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|
Release files / pizzetti-0.2.1-py3-none-any.whl
| Download URL | pizzetti-0.2.1-py3-none-any.whl |
|---|---|
| Size | 58.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fd07938437d0d7f4b683f1fe5f1b3c53be08bb0c553e8f044ef497ac9f70ff59
|
|
BLAKE2b-256 checksum How to use checksums |
61e757a6b44e7ac1fcd699b21ebbab0d9279af8c7ba08236101c7daff5b63dce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|