Regularized image reconstruction for radio interferometry — simulate an array, state χ² + regularizers, reconstruct on CPU or GPU. Not a black-box CLEAN.
Pyralysis is a Python library (Dask, optional CuPy) for simulation, gridding, and image reconstruction. You compose the objective; there is no hidden imager. It complements CASA / WSClean (CLEAN-style imaging) and tools like ehtim (VLBI RML): here the focus is composable χ² + regularizers at array / cluster scale.
Who it’s for. Researchers who want an explicit objective and GPU or Dask scaling —
not a drop-in tclean.
I/O & arrays. Measurement Set · FITS · Zarr · bundled VLA/ALMA configs · natural / uniform / robust weights · closure phase & amplitude · CPU or CuPy.
Guides: Read the Docs · website: clirai.gitlab.io. If you use Pyralysis in a paper, please cite it.
You can
Simulate an observation
VLA, ALMA, or a custom antenna config; parametric or FITS sky models; thermal noise and gain injectors.
ALMA C-9, Band 6 (230 GHz), 2 h with thermal noise: a protoplanetary disk (Planck brightness, T ∝ r−1/2, optically thick core, gaps and rings) built from 80 DiskSource rings, plus three background sources — sky, uv coverage, and the real part of the visibilities against deprojected uv distance.
Simulation ·
examples/scripts/simulation_components.py
Make a dirty map and PSF
Natural, uniform, or robust weights, then a dirty image and dirty beam.
Visibility weights ·
Gridding ·
examples/scripts/dirtymapper_components.py
Reconstruct a model
State χ² plus L1, TSV, or other regularizers; solve with FISTA, L-BFGS, or SDMM. The figures below are MFISTA (monotone FISTA) on χ² + L1 from zeros, natural weights, on the GPU (CuPy).
Dirty image → MFISTA reconstruction (Jy/pixel) → residual. Same ALMA disk simulation as above; square-root stretch.
MFISTA (monotone FISTA) iterates from a zero start.
Regenerate the gallery with python docs/scripts/generate_readme_figures.py.
Optimization ·
FISTA ·
examples/scripts/optimization_components.py
Image with closures, on GPU, or on a cluster
Closure-phase / closure-amplitude terms; the same stack on CuPy or a Dask cluster; read and write Measurement Sets, Zarr, and FITS.
Closures · Array backends · Pipelines · I/O
Notebooks without installing: Binder. How the pieces fit together: composability, flexibility, extensibility, adaptability.
Install
Python 3.11–3.13. The SKA extra index is required for a few dependencies.
pip install --extra-index-url https://artefact.skao.int/repository/pypi-internal/simple pyralysis[all]
GPU: micromamba create -f envs/cuda13.yml (Maxwell/Pascal/Volta: envs/cuda12.yml, Kepler: envs/cuda11.yml; see envs/README.md). Details: installation.
Minimal example
Simulate a 1 Jy point source at phase center, add thermal noise, natural-weight, and
form a dirty image. With geometry matched to the array (cellsize ≈ beam/3.5), the
dirty peak is ≈ 1 Jy/beam.
from importlib.resources import files
from astropy import units as u
from pyralysis.io.antenna_config_io import AntennaConfigurationIo
from pyralysis.simulation import Simulator
from pyralysis.models.sky import PointSource
from pyralysis.injectors import ThermalNoiseInjector
from pyralysis.transformers.weighting_schemes import Natural
from pyralysis.transformers import DirtyMapper
# Bundled VLA-C antenna table (same idea as a CASA .cfg)
cfg = files("pyralysis.simulation") / "antenna_configs" / "vla.c.cfg"
interferometer = AntennaConfigurationIo(input_name=str(cfg)).read()
# Pointing, band, and dump time for a short continuum observation
interferometer.configure_observation(
min_frequency=1e9 * u.Hz, max_frequency=1.1e9 * u.Hz, frequency_step=1e7 * u.Hz,
right_ascension="12h00m00s", declination="45d00m00s",
integration_time=10 * u.s, observation_time="1h",
)
# Unresolved source on-axis; intensity in Jy at the reference frequency
source = PointSource(
reference_intensity=1.0 * u.Jy, sky_position="12h00m00s 45d00m00s",
reference_frequency=1e9 * u.Hz,
)
# Visibilities → in-memory Dataset (Measurement Set–like); then SEFD-style noise
dataset = Simulator(interferometer=interferometer, sources=source).simulate(create_dataset=True)
dataset = ThermalNoiseInjector(system_temperature=50, integration_time=10, channel_bandwidth=1e6).apply(dataset)
# Pixel scale from theoretical resolution (~synthesized beam / 3.5)
imsize, cellsize = 128, dataset.theo_resolution / 3.5
Natural(imsize=imsize, cellsize=cellsize, input_data=dataset).transform() # imaging weights
dataset.calculate_psf() # dirty beam / PSF for the weighted uv coverage
dirty, _beam = DirtyMapper(
input_data=dataset, imsize=imsize, cellsize=cellsize, stokes=["I"]
).transform() # dirty image (Jy/beam) and beam; peak ≈ 1 for this setup
Reconstruction (χ² + L1, FISTA, GPU) is the same composition as the figures — optimization, quickstart.
Citation
Please cite the software (DOI — all versions) and, when relevant, the overview paper:
Cárcamo et al., URSI GASS 2026 — Pyralysis: An Open-Source Framework for Big Data Radio Interferometry.
@software{carcamo2021pyralysis,
author = {Cárcamo, Miguel and Guidotti, Valeria and Casassus, Simon
and Rannou, Fernando and Román, Pablo},
title = {Pyralysis},
year = {2026},
publisher = {Zenodo},
version = {3.1.0},
doi = {10.5281/zenodo.23541172},
url = {https://doi.org/10.5281/zenodo.23541172}
}
Stars, forks, and download charts live on the project activity page.
Links
Docs · API · Examples · Website · Contributing · Changelog · Issues
GPL-3.0-only — see LICENSE. Contact: miguel.carcamo@usach.cl
Metadata
Release files for pyralysis 3.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 | Provenance | Actions |
|---|---|---|---|---|
| pyralysis-3.2.1.tar.gz | 18.7 MB | Without provenance | Details for pyralysis-3.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyralysis-3.2.1-py3-none-any.whl | Python 3 | none | any | Details for pyralysis-3.2.1-py3-none-any.whl |
Total release size: 20.1 MB
Release files / pyralysis-3.2.1.tar.gz
| Download URL | pyralysis-3.2.1.tar.gz |
|---|---|
| Size | 18.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7562adc36dcbbb5d7288d92cccd46b6ce3172d16035f39695bce0ca8008c219a
|
|
BLAKE2b-256 checksum How to use checksums |
eb873d675a46038a9c70f818b7cfac98c22973ea99a297281c097f117f532141
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|
Release files / pyralysis-3.2.1-py3-none-any.whl
| Download URL | pyralysis-3.2.1-py3-none-any.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2abd3116264acca4bbc84993886514c7e407f2cdb938962dbb9c64021759bbf3
|
|
BLAKE2b-256 checksum How to use checksums |
9015120890e077bd6a84e958a5f0a0e2fa32050a07d6c2a7dd7c603ccefc6a85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|
Security for pyralysis 3.2.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.