NICER constraints#
NICER (Neutron star Interior Composition Explorer) is a NASA X-ray telescope on the International Space Station that measures X-ray pulse profiles from millisecond pulsars. By modelling the anisotropic X-ray emission from hot spots on the neutron star surface, NICER constrains the stellar mass and radius simultaneously, providing direct input for equation-of-state inference.
JESTER currently supports four pulsars observed by NICER:
PSR J0030+0451
PSR J0437-4715
PSR J0614-3329
PSR J0740+6620
The figure below shows the mass-radius posteriors for one representative analysis per pulsar, with filled contours at the 68% and 90% credible intervals. Below, we provide more details on the datasets that are available for each pulsar.
(Source code, png, hires.png, pdf)
Mass-radius posteriors from NICER for the four supported pulsars. Filled contours show the 68% (darker) and 90% (lighter) credible intervals from kernel density estimation of the published posterior samples. One representative analysis is plotted per pulsar.#
Likelihood#
For each pulsar, JESTER uses a normalizing flow trained on the published M-R posterior samples. The flow learns the joint density \(p(M, R \mid \text{data})\) for a given analysis group and hotspot model.
When evaluating the likelihood for a candidate EOS, the computation proceeds as follows. At initialization, a fixed set of \(N\) masses \(M^{(i)}\) is drawn once from the marginal mass distribution of the flow. For each EOS evaluation, the radius \(R_\mathrm{EOS}(M^{(i)})\) is obtained by linear interpolation along the EOS M-R curve at each pre-sampled mass. The per-group log-likelihood is
evaluated numerically as \(\mathrm{logsumexp}_i\!\left(\log p_\mathrm{flow}^{(i)}\right) - \log N\). If multiple analysis groups are used (e.g. Amsterdam and Maryland for PSR J0030+0451), the final log-likelihood averages over groups in the same way as the above equation.
Mass samples that exceed \(M_\mathrm{TOV}\) receive a large negative penalty, if enabled by the user.
The pre-sampling at initialization fixes the mass grid for the entire run, which ensures deterministic and smooth likelihood evaluations — important for sampler convergence.
The default implementation is NICERLikelihood (flow-based).
A legacy NICERKDELikelihood based on kernel density estimation of the raw posterior samples is also available for comparison.
Data#
Mass-radius posterior samples for all supported pulsars are stored as compressed NumPy
archives (.npz) under jesterTOV/inference/data/NICER/. Each file contains
radius (km), mass (solar masses), and a metadata dictionary with the
pulsar name, analysis group, hotspot model, Zenodo record URL, and paper reference.
The raw Zenodo archives (which can be several gigabytes) are downloaded into
jesterTOV/inference/data/NICER/zenodo_data/ (gitignored). Only the lightweight
extracted .npz files are version-controlled.
Download script: jesterTOV/inference/data/NICER/download_nicer.py
This single script handles the full pipeline — downloading Zenodo archives, extracting
mass-radius samples from raw text files and tar archives, and downsampling large
posteriors to at most 100,000 samples. It requires the zenodo-get package:
uv pip install zenodo-get
uv run python jesterTOV/inference/data/NICER/download_nicer.py
Warning
Downloading the raw Zenodo archives can take a significant amount of time. Several
records contain full posterior chains that are multiple gigabytes in size. Make sure
you have sufficient disk space and a stable internet connection before running the
script. The processed .npz files (the only outputs you need for inference) are
already version-controlled in the repository, so you only need to run this script
if you want to reproduce the extraction from scratch.
Zenodo record identifiers and paper metadata are maintained in
jesterTOV/inference/data/NICER/zenodo_downloader.py.
PSR J0030+0451#
First millisecond pulsar observed by NICER with sufficient quality for mass-radius inference, analyzed independently by the Amsterdam (X-PSI) and Maryland groups from the same 2017-2018 NICER data.
Amsterdam group — Riley et al. 2019 (Zenodo 3524457)
Five hotspot geometries are available:
J00300451_amsterdam_ST_S_NICER_only_Riley2019.npz— ST symmetricJ00300451_amsterdam_ST_U_NICER_only_Riley2019.npz— ST unrestrictedJ00300451_amsterdam_CDT_U_NICER_only_Riley2019.npz— CDT unrestrictedJ00300451_amsterdam_ST_EST_NICER_only_Riley2019.npz— ST+ESTJ00300451_amsterdam_ST_PST_NICER_only_Riley2019.npz— ST+PST (recommended)
Maryland group — Miller et al. 2019 (Zenodo 3473464)
Two hotspot geometries × two prior choices:
J00300451_maryland_2spot_NICER_only_RM.npz— 2-spot, restricted-model priorJ00300451_maryland_2spot_NICER_only_full.npz— 2-spot, full priorJ00300451_maryland_3spot_NICER_only_RM.npz— 3-spot, restricted-model priorJ00300451_maryland_3spot_NICER_only_full.npz— 3-spot, full prior
PSR J0437−4715#
The nearest and brightest millisecond pulsar, observed with NICER only.
Amsterdam group — Choudhury et al. 2024 (Zenodo 13766753)
Headline result using CST+PDT hotspot model with 3C50 background:
J04374715_amsterdam_CST_PDT_NICER_only_Choudhury2024.npz
PSR J0614−3329#
A 1.4 solar-mass edge-on pulsar observed with NICER only.
Amsterdam group — Dittmann et al. 2025 (Zenodo 17380576)
Headline result using ST+PDT hotspot model:
J06143329_amsterdam_ST_PDT_NICER_only_Dittmann2025.npz
PSR J0740+6620#
The most massive millisecond pulsar with a precise radio timing mass, providing high-density EOS constraints. Analyzed jointly with XMM-Newton data.
Amsterdam group — Salmi et al. 2024 (Zenodo 10519473)
Most recent analysis using gamma hotspot model with NICER+XMM-Newton data:
J07406620_amsterdam_gamma_NICERXMM_equal_weights_recent.npz
Maryland group — Miller et al. 2021 (Zenodo 4670689)
Three dataset combinations x two prior choices:
J07406620_maryland_unknown_NICER_only_RM.npzJ07406620_maryland_unknown_NICER_only_full.npzJ07406620_maryland_unknown_NICERXMM_RM.npzJ07406620_maryland_unknown_NICERXMM_full.npzJ07406620_maryland_unknown_NICERXMM_relative_RM.npzJ07406620_maryland_unknown_NICERXMM_relative_full.npz
“NICER+XMM” indicates joint analysis; “relative” includes relative calibration between instruments; “RM” uses a restricted-model prior.
Loading the data#
Each .npz file can be loaded directly:
import numpy as np
data = np.load("NICER/J07406620_amsterdam_gamma_NICERXMM_equal_weights_recent.npz",
allow_pickle=True)
radius = data["radius"] # km, shape: (n_samples,)
mass = data["mass"] # solar masses
meta = data["metadata"].item() # dict: psr, group, zenodo_record, paper, …
In normal usage the likelihood classes load the data automatically based on your YAML configuration.