Skip to main content

limTOD

Time-Ordered Data simulator for single-dish (autocorrelation) radio intensity mapping — with a differentiable pure-JAX port.

📖 Documentation: https://limtod.readthedocs.io

limTOD simulates the time-ordered data (TOD) of a single-dish telescope scanning a HEALPix sky with an arbitrary (asymmetric) beam: the beam is rotated to each pointing in spherical-harmonic space and dotted with the sky, then combined with 1/f gain noise and white noise. The package also ships:

  • Map-makingHPW_mapmaking (high-pass + Wiener) and GLS_mapmaking (full 1/f + white noise covariance, ported from hydra-tod's iterative GLS);
  • limTOD.patchbeam — a MeerKLASS-optimal sky-TOD path that keeps narrow, finely-gridded beams on their native (l, m) grid and integrates disc-restricted sky patches (no harmonic rotation);
  • limTOD.uvbeam — adapters for pyuvdata UVBeam objects, feeding measured/simulated beams into either path;
  • limtod_jax — a pure-JAX, jit/vmap/grad-safe port of the sky→TOD chain, verified against the numpy implementation to ~1e-12 in float64. It powers the differentiable pipeline of replicant-telescope.

Latest changes: CHANGELOG.

Installation

pip install limTOD

The base install is deliberately lightweight (wheel-only: numpy, healpy, astropy, scipy, tqdm, mpmath — no compiler needed). Heavier dependencies are opt-in extras:

Extra Installs When you need it
[mpi] mpi4py MPI-parallel simulation (mpirun -n N ...). Without it limTOD runs serially; launching under mpirun without mpi4py fails loudly instead of silently duplicating work.
[gdsm] pygdsm The GDSM_sky_model sky function (Global Sky Model). Everything else works without it.
[jax] jax, s2fft The limtod_jax package (Python ≥ 3.11).
[uvbeam] pyuvdata limTOD.uvbeam: use pyuvdata UVBeam objects as beams (Python ≥ 3.11).
[parallel] joblib Parallel sample loop in limTOD.patchbeam (n_jobs != 1).
[full] all of the above The complete setup.
pip install "limTOD[full]"

From source: clone the repository and pip install -e ".[dev,full]" (runs the test suite over both the MPI-present and serial-fallback paths).

Quick start

Simulate multi-frequency TOD for a MeerKAT-like scan (sky model here needs [gdsm]; pass your own sky_func to go without):

from limTOD import TODSim, example_scan

simulator = TODSim(
    ant_latitude_deg=-30.7130, ant_longitude_deg=21.4430, ant_height_m=1054,
    beam_nside=256, sky_nside=256,
)
time_list, azimuth_list = example_scan()
tod, sky_tod, gain_noise = simulator.generate_TOD(
    freq_list=[950, 1000, 1050],          # MHz
    time_list=time_list,
    azimuth_deg_list=azimuth_list,
    elevation_deg=41.5,
)                                          # each (n_freq, n_time)

The same sky→TOD chain, differentiable in JAX ([jax] extra):

import jax; jax.config.update("jax_enable_x64", True)
import jax.numpy as jnp
import limtod_jax as ltj

sky_alm = ltj.map2alm_quad(sky_map, nside=nside, lmax=lmax)
psi, theta, phi = ltj.zyz_of_pointing(lst_deg, lat_deg, az_deg, el_deg, 0.0)
tod = ltj.generate_tod_sky(
    beam_alm, sky_alm, jnp.stack([psi, theta, phi], axis=-1), lmax=lmax,
)
grad = jax.grad(lambda b: ltj.generate_tod_sky(
    b, sky_alm, jnp.stack([psi, theta, phi], axis=-1), lmax=lmax).sum().real
)(beam_alm)                                # d(TOD sum)/d(beam alms)

Documentation

Full documentation: https://limtod.readthedocs.io

Page Contents
TOD simulation TODSim guide: inputs, outputs, noise model, MPI, troubleshooting
Map-making HPW_mapmaking (high-pass + Wiener) and GLS_mapmaking (full 1/f covariance)
Patch-beam path limTOD.patchbeam: disc-restricted (l, m) beam interpolation
UVBeam support pyuvdata beams as beam_func or patch beams
Theory & conventions Signal model, coordinate chain, Euler-angle conventions
API reference Generated from docstrings
limtod_jax The JAX port: usage, exactness contract, precision requirements

Worked notebooks: TOD simulation and map-making. Coordinate and beam-orientation conventions: Theory & conventions.

Citation

If you use limTOD in your research, please cite:

@ARTICLE{2026RASTI...5ag024Z,
       author = {{Zhang}, Zheng and {Bull}, Philip and {Santos}, Mario G. and {Nasirudin}, Ainulnabilah},
        title = "{Joint Bayesian calibration and map-making for intensity mapping experiments}",
      journal = {RAS Techniques and Instruments},
     keywords = {Data Methods, methods: data analysis, techniques: spectroscopic, radio lines: general, Instrumentation and Methods for Astrophysics},
         year = 2026,
        month = jan,
       volume = {5},
          eid = {rzag024},
        pages = {rzag024},
          doi = {10.1093/rasti/rzag024},
archivePrefix = {arXiv},
       eprint = {2509.10992},
 primaryClass = {astro-ph.IM},
       adsurl = {https://ui.adsabs.harvard.edu/abs/2026RASTI...5ag024Z},
      adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}

License and authorship

MIT License — see LICENSE.

limTOD is developed and maintained by Zheng Zhang (University of Manchester), with help and advice from members of the MeerKLASS and RHINO collaborations — including Phil Bull, Piyanat Kittiwisit, Geoff Murphy, and Mario Santos.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

limtod-1.5.2.tar.gz (102.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

limtod-1.5.2-py3-none-any.whl (85.8 kB view details)

Uploaded Python 3

File details

Details for the file limtod-1.5.2.tar.gz.

File metadata

  • Download URL: limtod-1.5.2.tar.gz
  • Upload date:
  • Size: 102.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for limtod-1.5.2.tar.gz
Algorithm Hash digest
SHA256 cd63052ca52142d156b7469f1d3b6f30c6142136215c478ad13ca29767b09606
MD5 17ef8a5dff2be507b5425f12c0eb9991
BLAKE2b-256 b1714f3cc09d6e0d088719a55cdd8bff343d4c933f59b40f8ac7a89d106ba976

See more details on using hashes here.

Provenance

The following attestation bundles were made for limtod-1.5.2.tar.gz:

Publisher: publish.yml on zzhang0123/limTOD

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file limtod-1.5.2-py3-none-any.whl.

File metadata

  • Download URL: limtod-1.5.2-py3-none-any.whl
  • Upload date:
  • Size: 85.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for limtod-1.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e135413bc96609d4f198b5584208338201cd2e47b2cb2033aa0fa2ff8b6b9d4a
MD5 e182d8d972754dd6886a13667d15ba5c
BLAKE2b-256 435cbe4fbfe569aede6bdae4a1134a39f89142cf96f0303fc3b45918fd3d5f74

See more details on using hashes here.

Provenance

The following attestation bundles were made for limtod-1.5.2-py3-none-any.whl:

Publisher: publish.yml on zzhang0123/limTOD

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page