Skip to main content

barycenter

Barycentric correction of X-ray event files, in pure Python.

Tests Code of Conduct License: MIT

A photon's arrival time at the spacecraft is not a useful clock. The spacecraft moves around the Earth, and the Earth around the Sun, so recorded arrival times wander by up to about 500 seconds over a year. Barycentring removes that: it reports each photon as it would have arrived at the solar system's centre of mass, which is very nearly inertial, so times can be compared between missions and across decades.

That is the job of HEASOFT barycorr, XMM-SAS barycen and CIAO axbary. barycenter does it with nothing installed but Python, agrees with each of those tools to better than 100 nanoseconds, and is not restricted to the ephemerides they happen to ship.

Install

pip install git+https://github.com/matteobachetti/barycenter.git

The optional speed extra installs numba, which makes the spacecraft-clock interpolation about six times faster. It changes no answer — the compiled and pure-numpy kernels are bit-identical — and only pays for its compilation time on very large files:

pip install "barycenter[speed] @ git+https://github.com/matteobachetti/barycenter.git"

Use it from the command line

You need the event file and the mission's orbit file, and a position on the sky:

barycenter nu30702012003A06_cl.evt nu30702012003A.attorb \
    --ra 148.9584 --dec 69.6794 --ephem DE440

The position can come from a pulsar parameter file instead, which saves copying coordinates by hand and also picks up the ephemeris the model was fitted with:

barycenter ni1013010101_0mpu7_cl.evt ni1013010101.orb --parfile Crab.par

The default engine takes the static RAJ/DECJ out of the model. If the source's proper motion or parallax matters, add --engine pint, which hands the whole timing model over and so applies them.

Several orbit files can be given at once, for an observation split across them, and --clockfile names a spacecraft clock file (NuSTAR's is fetched from the CALDB automatically if you do not). barycenter --help lists the rest; the options worth knowing about are --ephem, --engine and --dt.

Use it from Python

The whole command line is one function:

from barycenter import apply_barycenter_correction

outfile = apply_barycenter_correction(
    "nu30702012003A06_cl.evt",
    "nu30702012003A.attorb",
    outfile="bary.evt",
    ra=148.9584,
    dec=69.6794,
    ephem="DE440",
)

If you only want the correction itself — to apply to times you already hold, or to plot — ask for the function of mission elapsed time and call it:

from barycenter import get_barycentric_correction, read_orbit

orbit = "nu30702012003A.attorb"
correction = get_barycentric_correction(orbit, ra=148.9584, dec=69.6794, ephem="DE440")

met = read_orbit(orbit)["MET"].value  # the times the orbit file covers
barycentred = met + correction(met)  # correction is in seconds, about +309 here

The returned object is a cubic spline over the orbit file's own time span, so ask it only for times inside that span: outside it the spline extrapolates, quietly and badly. The command line checks this for you and warns.

Missions

Mission Orbit file Clock correction Agreement with the mission's own tool
NuSTAR nu<obsid>A.attorb nuCclock*.fits, fetched automatically +22 ns vs barycorr
RXTE orbit/FPorbit_* tdc.dat, bundled +25 ns vs barycorr
Swift auxil/sw<obsid>sao.fits swclockcor*.fits (the UTCF) +37 ns vs barycorr
XMM-Newton PPS *ORBTSR*.FTZ none needed −42 ns vs SAS barycen
Chandra primary/orbitf*_eph1.fits none needed +47 ns vs CIAO axbary
NICER ni<obsid>.orb none needed +53 ns vs barycorr, one-off check
IXPE, Fermi, SVOM see the docs none implemented orbit file read, never checked against a tool

The first five rows have a reference file committed to the repository, so continuous integration re-checks them on every change. The NICER figure comes from a single comparison against a barycorr run on a Crab observation too large to commit, and the last three missions have never been compared against an official tool at all — their orbit files are read correctly, which is a different claim.

XMM-Newton and Chandra are worth singling out: barycorr cannot do either mission, and axbary can only reach DE200 and DE405, so this is the only way to barycentre them against a modern ephemeris. On the Chandra test data DE405 is 79 µs away from DE440.

Per-mission instructions are in docs/missions.md, and adding a new mission is about five lines plus a reference file to check it against.

Accuracy

The target is 100 nanoseconds against each mission's own tool, and it is met on all five missions for which an official reference could be produced. Most of the residual scatter in the table above is not ours: a reference file stores times as 64-bit floats, which near a mission elapsed time of 5e8 seconds cannot express a difference finer than about 119 ns, so the tests add that floor to their tolerance.

Two engines compute the correction. The default, --engine native, uses astropy, ERFA and a JPL ephemeris directly, keeping every term as a small quantity so that it works identically on any platform. --engine pint routes the same job through PINT as an independent second opinion; the two agree to sub-nanosecond once the differing Shapiro-delay convention is accounted for. On Apple Silicon and Windows the PINT path is quantised at about 1.1 µs, because those platforms have no extended-precision float; the native engine is unaffected.

Documentation

Contributing

Bug reports and patches are welcome; see CONTRIBUTING.md and the Code of Conduct.

  • Copyright © 2025 Matteo Bachetti.
  • Free software distributed under the MIT License.

Metadata

Release files for barycenter 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for barycenter 1.0.0
File Size Uploaded
barycenter-1.0.0.tar.gz 85.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for barycenter 1.0.0
File Interpreter ABI Platform
barycenter-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 173.2 kB

Release files / barycenter-1.0.0.tar.gz

Download URL barycenter-1.0.0.tar.gz
Size 85.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e898470bf9d4000e287ae4f25153f0d06700d04b224617456cd976c294a44631
BLAKE2b-256 checksum
How to use checksums
bdace0b34d7ac80dc672e4647cca211723566fb649fe405a2cb82c742cfe5e03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 1, 2026.

Transparency log

Release files / barycenter-1.0.0-py3-none-any.whl

Download URL barycenter-1.0.0-py3-none-any.whl
Size 87.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f23c65894339d186ca7ae88c2ecc46d4851ee39c8d765e5d4d6b07edec78b072
BLAKE2b-256 checksum
How to use checksums
b1e8c62a19c41ca255c6ae9371488bb905aa575680206b8eaa28621a64c6f9a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 1, 2026.

Transparency log

Release history Release notifications | RSS feed

1.1.0

2 release files

This release

1.0.0 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page