Metadata-Version: 2.4
Name: pyralysis
Version: 3.0.0
Summary: PYthon Radio Astronomy anaLYSis and Image Synthesis
Author-email: Miguel Cárcamo <miguel.carcamo@usach.cl>
Maintainer-email: Miguel Cárcamo <miguel.carcamo@usach.cl>
License-Expression: GPL-3.0-only
Project-URL: Documentation, https://pyralysis.readthedocs.io/
Project-URL: Issues, https://gitlab.com/clirai/pyralysis/-/issues
Project-URL: Repository, https://gitlab.com/clirai/pyralysis
Project-URL: Source, https://gitlab.com/clirai/pyralysis
Keywords: radio,radio-interferometry,interferometry,radioastronomy,imaging,deconvolution,calibration,CASA,ALMA,SKA,visibility,synthesis,python,astronomy,science,data-analysis,signal-processing,high-performance-computing,simulation,image-reconstruction,radio-telescope,big data,big-data,big computing,compressed sensing,gridding,optimization
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: astropy==6.1.7
Requires-Dist: autopep8==2.2.0
Requires-Dist: dafits==2.0.0
Requires-Dist: dask==2024.10.0
Requires-Dist: dask-ms>=0.2.32
Requires-Dist: distributed==2024.10.0
Requires-Dist: matplotlib==3.10.8
Requires-Dist: more-itertools==10.2.0
Requires-Dist: multimethod==1.11.2
Requires-Dist: numba>=0.59.1
Requires-Dist: numcodecs==0.15.1
Requires-Dist: numpy<2.4.0,>=2.0.0
Requires-Dist: psutil==6.1.1
Requires-Dist: python-casacore==3.7.1
Requires-Dist: radio-beam==0.3.7
Requires-Dist: scipy==1.15.0
Requires-Dist: ska-ost-array-config==5.0.0
Requires-Dist: snakeviz==2.2.0
Requires-Dist: spectral-cube==0.6.5
Requires-Dist: xarray==2025.8.0
Requires-Dist: zarr<3.2,>=3.0.0
Provides-Extra: all
Requires-Dist: pyfftw; extra == "all"
Requires-Dist: cmcrameri; extra == "all"
Requires-Dist: ipykernel; extra == "all"
Requires-Dist: seaborn; extra == "all"
Requires-Dist: six==1.17.0; extra == "all"
Requires-Dist: pytest==9.0.2; extra == "all"
Requires-Dist: pytest-cov==7.1.0; extra == "all"
Requires-Dist: pytest-xdist==3.8.0; extra == "all"
Provides-Extra: arcae
Requires-Dist: arcae>=0.5.4; extra == "arcae"
Provides-Extra: cupy
Requires-Dist: cupy-cuda13x<15,>=14.0; extra == "cupy"
Provides-Extra: cupy12
Requires-Dist: cupy-cuda12x<15,>=13.2; extra == "cupy12"
Provides-Extra: cupy13
Requires-Dist: cupy-cuda13x<15,>=14.0; extra == "cupy13"
Provides-Extra: dev
Requires-Dist: tox>=4.21.0; extra == "dev"
Requires-Dist: tox-uv>=1.11.0; extra == "dev"
Provides-Extra: notebook
Requires-Dist: cmcrameri; extra == "notebook"
Requires-Dist: ipykernel; extra == "notebook"
Requires-Dist: seaborn; extra == "notebook"
Provides-Extra: pyfftw
Requires-Dist: pyfftw; extra == "pyfftw"
Provides-Extra: slurm
Requires-Dist: dask-jobqueue>=0.9.0; extra == "slurm"
Provides-Extra: test
Requires-Dist: six==1.17.0; extra == "test"
Requires-Dist: pytest==9.0.2; extra == "test"
Requires-Dist: pytest-cov==7.1.0; extra == "test"
Requires-Dist: pytest-xdist==3.8.0; extra == "test"
Dynamic: license-file

<div align="center">

<img src="https://gitlab.com/miguelcarcamov/pyralysis/-/wikis/uploads/fd40975ce0601b5c52a3cf8b92f385a5/Pyralisis-25.png" height="220" alt="Pyralysis logo">

# Pyralysis

**PYthon Radio Astronomy anaLYSis and Image Synthesis**

*Regularized image reconstruction for radio interferometry — simulate an array,
state χ² + regularizers, reconstruct on CPU or GPU. Not a black-box CLEAN.*

[![Pipeline Status](https://gitlab.com/clirai/pyralysis/badges/development/pipeline.svg)](https://gitlab.com/clirai/pyralysis/-/pipelines?ref=development)
[![codecov](https://codecov.io/gl/clirai/pyralysis/branch/development/graph/badge.svg?token=MVFAA1YKC7)](https://codecov.io/gl/clirai/pyralysis)
[![PyPI Version](https://img.shields.io/pypi/v/pyralysis)](https://pypi.org/project/pyralysis)
[![Documentation Status](https://readthedocs.org/projects/pyralysis/badge/)](https://pyralysis.readthedocs.io/)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/clirai%2Fpyralysis/release?urlpath=lab%2Ftree%2Fexamples%2Fnotebooks)
[![License](https://img.shields.io/static/v1?label=License&message=GPL-3.0-only&color=blue)](https://www.gnu.org/licenses/gpl-3.0)

</div>

Pyralysis is a Python library (Dask, optional CuPy) for **simulation**, **gridding**,
and **image reconstruction**. You compose the objective; there is no hidden imager.
Guides: **[Read the Docs](https://pyralysis.readthedocs.io/)**.

## You can

### Simulate an observation

VLA, ALMA, or a custom antenna config; parametric or FITS sky models; thermal noise
and gain injectors.

<p align="center">
  <img src="docs/source/_static/readme/readme_simulate.png" alt="Sky model, ALMA uv coverage, and visibility amplitudes" width="100%">
</p>
<p align="center"><em>ALMA Band 6 (230 GHz) Cycle 9.8: Rayleigh–Jeans disk (core + four rings) and three compact sources — sky, uv coverage, visibility amplitudes.</em></p>

[Simulation](https://pyralysis.readthedocs.io/simulation.html) ·
`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](https://pyralysis.readthedocs.io/visibility_weights.html) ·
[Gridding](https://pyralysis.readthedocs.io/gridding.html) ·
`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 FISTA on χ² + L1 from zeros, natural weights.

<p align="center">
  <img src="docs/source/_static/readme/readme_reconstruct.png" alt="Dirty image, FISTA model, and residual" width="100%">
</p>
<p align="center"><em>Dirty image → FISTA model (Jy/pixel) → residual. Same ALMA disk simulation as above.</em></p>
<p align="center">
  <img src="docs/source/_static/readme/readme_fista.gif" alt="FISTA iterates from a zero starting image" width="85%">
</p>
<p align="center"><em>Iterates from a zero start.</em></p>

Regenerate the gallery with `python docs/scripts/generate_readme_figures.py`.
[Optimization](https://pyralysis.readthedocs.io/optimization.html) ·
[FISTA](https://pyralysis.readthedocs.io/compressed_sensing.html) ·
`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](https://pyralysis.readthedocs.io/closures.html) ·
[Array backends](https://pyralysis.readthedocs.io/array_backend.html) ·
[Pipelines](https://pyralysis.readthedocs.io/pipelines_distributed.html) ·
[I/O](https://pyralysis.readthedocs.io/io_operations.html)

Notebooks without installing: [Binder](https://mybinder.org/v2/gl/clirai%2Fpyralysis/release?urlpath=lab%2Ftree%2Fexamples%2Fnotebooks).
How the pieces fit together:
[composability](https://pyralysis.readthedocs.io/composability.html),
[flexibility](https://pyralysis.readthedocs.io/flexibility.html),
[extensibility](https://pyralysis.readthedocs.io/extensibility.html),
[adaptability](https://pyralysis.readthedocs.io/adaptability.html).

## Install

Python 3.11–3.13. The SKA extra index is required for a few dependencies.

```bash
pip install --extra-index-url https://artefact.skao.int/repository/pypi-internal/simple pyralysis[all]
```

GPU: `micromamba create -f environment_cuda13.yml` (Pascal: `environment_cuda12.yml`), then `pip install -e .`. Details: [installation](https://pyralysis.readthedocs.io/installation.html).

## Minimal example

Simulate a point source, add thermal noise, make a natural-weighted dirty image:

```python
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

cfg = files("pyralysis.simulation") / "antenna_configs" / "vla.c.cfg"
interferometer = AntennaConfigurationIo(input_name=str(cfg)).read()
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",
)
source = PointSource(
    reference_intensity=1.0 * u.Jy, sky_position="12h00m00s 45d00m00s",
    reference_frequency=1e9 * u.Hz,
)
dataset = Simulator(interferometer=interferometer, sources=source).simulate(create_dataset=True)
dataset = ThermalNoiseInjector(system_temperature=50, integration_time=10, channel_bandwidth=1e6).apply(dataset)

imsize, cellsize = 128, dataset.theo_resolution / 3.5
Natural(imsize=imsize, cellsize=cellsize, input_data=dataset).transform()
dataset.calculate_psf()
dirty, _beam = DirtyMapper(input_data=dataset, imsize=imsize, cellsize=cellsize, stokes=["I"]).transform()
```

Reconstruction (χ² + L1, FISTA, GPU) is the same composition as the figures —
[optimization](https://pyralysis.readthedocs.io/optimization.html),
[quickstart](https://pyralysis.readthedocs.io/quickstart.html).

## Links

[Docs](https://pyralysis.readthedocs.io/) ·
[API](https://pyralysis.readthedocs.io/autoapi/index.html) ·
[Examples](https://pyralysis.readthedocs.io/examples.html) ·
[Contributing](CONTRIBUTING.md) ·
[Changelog](CHANGELOG.md) ·
[Issues](https://gitlab.com/clirai/pyralysis/-/issues)

```bibtex
@software{carcamo2021pyralysis,
  author = {Miguel Cárcamo},
  title = {Pyralysis: A Python framework for radio interferometric imaging and simulation},
  year = {2021},
  url = {https://gitlab.com/clirai/pyralysis},
  note = {https://pyralysis.readthedocs.io/}
}
```

GPL-3.0-only — see `LICENSE`. Contact: [miguel.carcamo@usach.cl](mailto:miguel.carcamo@usach.cl)
