jnkepler
A differentiable N-body model for multi-planet systems.
jnkepler is a Python package for modeling photometric and radial velocity data of multi-planet systems via N-body integration. Built with JAX, it leverages automatic differentiation for efficient computation of model gradients. This enables seamless integration with gradient-based optimizers and Hamiltonian Monte Carlo methods, including the No-U-Turn Sampler (NUTS) in NumPyro. The package is particularly suited for efficiently sampling from multi-planet posteriors involving a large number of parameters and strong degeneracy.
Subpackages
- jnkepler.jaxttv: A differentiable N-body model for analyzing transit timing variations (TTVs) and radial velocities (RVs) of multi-planet systems.
- jnkepler.nbodytransit: A differentiable photodynamical model.
jaxoplanetneeds to be installed for using this package. - jnkepler.nbodyrv: A differentiable RV model taking into account mutual interactions between planets.
See readthedocs for more details.
Installation
pip install jnkepler
CPU performance note
jnkepler is primarily intended for CPU execution and supports recent JAX/jaxlib releases (tested through 0.12.0.1). With both JAX and jaxlib >=0.12, the default settings provide good CPU performance.
For older versions, use the matching XLA_FLAGS setting below to avoid an XLA CPU performance regression. Apply it before importing JAX, jnkepler, NumPyro, or any other library that imports JAX. In notebooks, restart the kernel first if these libraries have already been imported.
JAX/jaxlib 0.7–0.11: increase the small-while-loop threshold
export XLA_FLAGS="--xla_backend_extra_options=xla_cpu_small_while_loop_byte_threshold=65536"
Or in Python:
import os
os.environ["XLA_FLAGS"] = (
"--xla_backend_extra_options="
"xla_cpu_small_while_loop_byte_threshold=65536"
)
import jax
import jnkepler
JAX/jaxlib 0.4.32–0.6.x: use the legacy CPU runtime
export XLA_FLAGS="--xla_cpu_use_thunk_runtime=false"
Or in Python:
import os
os.environ["XLA_FLAGS"] = "--xla_cpu_use_thunk_runtime=false"
import jax
import jnkepler
When upgrading from 0.6.x to 0.7–0.11, replace the legacy runtime flag with the threshold setting above. Once both JAX and jaxlib are >=0.12, remove these workaround settings.
See also issue #30 for jnkepler benchmarks and version comparisons, and OpenXLA issue #50040 for the upstream XLA CPU performance issue and fix.
Note on the transit-finding algorithm (since v0.2.5)
In JaxTTV.get_transit_times_obs, the default transit-time solver is now "fast". This method is optimized for efficient evaluation near the observed transit times, which is typically sufficient for inference because models far from the data have very low likelihood. For models that are substantially offset from the observed transit times, however, the fast method can be less accurate than the Newton-based method. Use transit_time_method="newton" when robust accuracy is needed in that regime.
For this reason, when using the fast method in NUTS, initialize the sampler from a good solution, such as a least-squares optimum as in the example notebooks, rather than from a diffuse or poor initial guess. If multimodality is a major concern, consider a preliminary grid/global search before running NUTS, rather than relying on NUTS alone to discover all modes.
Examples
Start with the step-by-step tutorials: fit transit times, write a NumPyro model, and initialize, tune, and diagnose NUTS. For non-transiting planets, RVs, photodynamics, and pure Keplerian calculations, see Models and extensions.
The examples/ directory contains the notebooks listed below. See the example notebook guide for their scope and requirements.
-
minimal example:
examples/minimal_example.ipynb- computing transit times and RVs
- plotting TTVs
- adding a non-transiting planet
-
TTV modeling (normal likelihood):
examples/kep51_ttv_normal.ipynb- posterior sampling with NUTS
- reproducing the result in Libby-Roberts et al. (2020)
-
TTV modeling (Student's t likelihood):
examples/v1298tau_ttv_student.ipynb: reproducing the analysis in Livingston et al. (2026)examples/trappist-1_ttv_student.ipynb: reproducing the analysis in Agol et al. (2021)
-
Photodynamical modeling:
examples/kep51_photodynamics_gp.ipynb- SVI optimization & posterior sampling with NUTS
- noise modeling using Gaussian Process with
tinygp
Applications
- TOI-1136: TTV modeling of 6-planets in a resonance chain [paper]
- TOI-2015: Joint TTV & RV modeling of a two-planet system [paper]
- Kepler-51: Four-planet modeling including JWST data [paper] [repository]
- K2-19: TTVs confirm 3:2 resonance [paper]
- TOI-4495: Photodynamical modeling of a pair of near-resonant sub-Neptunes [paper] [repository]
- V1298 Tau: Four low-density planets transiting a young star [paper] [repository]; see also
examples/v1298tau_ttv_student.ipynbin this repo - TOI-2076: TTV modeling of a young, near-resonant planetary system [paper]
- TOI-791: TTV masses of two extremely low-density, Jupiter-sized planets [paper]
- TOI-3686: Photodynamical and RV modeling of a hot Jupiter and sub-Neptune in a 2:1 mean-motion resonance [paper]
References
If you use jnkepler in your research, please consider citing the references below.
- Masuda et al. (2024), A Fourth Planet in the Kepler-51 System Revealed by Transit Timing Variations, AJ 168, 294
- Masuda (2025), jnkepler: Differentiable N-body model for multi-planet systems, Astrophysics Source Code Library, ascl:2505.006.
Metadata
Release files for jnkepler 0.2.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| jnkepler-0.2.10.tar.gz | 46.2 MB | With provenance | Details for jnkepler-0.2.10.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| jnkepler-0.2.10-py3-none-any.whl | Python 3 | none | any | Details for jnkepler-0.2.10-py3-none-any.whl |
Total release size: 46.5 MB
Release files / jnkepler-0.2.10.tar.gz
| Download URL | jnkepler-0.2.10.tar.gz |
|---|---|
| Size | 46.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fae200370614b1f3282573174c04d6c5686b48b4f5811537eef42e2dd802c800
|
|
BLAKE2b-256 checksum How to use checksums |
99603f2a2e1ef9baa220ae64896ce67eea856301a2ea8dc24f1d5586dbbc4fa0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / jnkepler-0.2.10-py3-none-any.whl
| Download URL | jnkepler-0.2.10-py3-none-any.whl |
|---|---|
| Size | 248.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1a2e9cdd92175ee38d51e2ae68e0c0797a28a792cfc4d222ece0c06853d1dc7f
|
|
BLAKE2b-256 checksum How to use checksums |
3fd53c81bbf2e240a4a8b2d4d617d53b22e1ff59255a0f34d6f2daa20c9fc9c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logSecurity for jnkepler 0.2.10
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for jnkepler-0.2.10.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.