Frequently Asked Questions (FAQ)
================================

Welcome! Here are answers to the most common questions about Pyralysis. If you're new, check out the :doc:`quickstart` guide first!

---

General Questions
-----------------

**Q1: What is Pyralysis and what is it used for?**
A: Pyralysis is an open-source Python library for **radio astronomy imaging, simulation, and optimization**. It provides tools for **gridding, degridding, visibility estimation, and image reconstruction** using **regularized maximum likelihood (RML) methods** and **gradient-based optimization**.

.. note::
   If you already use CASA or similar packages: **imaging**, **image formation**,
   **image synthesis**, **reconstruction**, and **image optimization** all refer to
   forming an image from visibilities. Pyralysis docs mix these terms; they mean the
   same broad task (see :doc:`glossary`).

.. tip::
   Pyralysis is designed for both beginners and advanced users. Its modular, object-oriented design makes it easy to extend and customize.

**Q2: How does Pyralysis compare to other radio interferometric imaging software?**
A: Pyralysis differs from traditional radio interferometric imaging software in several key ways:

- **Beyond CLEAN:** Implements RML-based optimization, not just heuristic greedy algorithms.
- **Modern Design:** Object-oriented, modular, and easy to extend.
- **Open Source:** Fully transparent and community-driven.
- **Scalable:** Modular design for **software extensibility**, and Dask-based workflows for **large visibility datasets** and next-generation arrays.

.. note::
   Pyralysis leverages Dask, Zarr, Numba, and (soon) CuPy for high-performance, scalable computing.

---

Installation and Setup
----------------------

**Q3: How can I install Pyralysis?**
A: See the :doc:`installation` guide for step-by-step instructions. **Stable releases** are published on `PyPI <https://pypi.org/project/pyralysis/>`__; use GitLab or an editable checkout for the latest unreleased changes.

**Q4: What are the system requirements for Pyralysis?**
A: Python 3.11–3.12 and a set of scientific Python libraries (see installation guide).

**Q5: How do I enable GPU acceleration in Pyralysis?**
A: GPU support is under development. Stay tuned!

---

Using Pyralysis
---------------

**Q6: How do I load visibilities (MS or Zarr)?**
A: **Measurement Set** — use :class:`~pyralysis.io.DaskMS`:

.. code-block:: python

   from pyralysis.io import DaskMS
   dataset = DaskMS(input_name="/path/to/data.ms").read()

**Zarr** (e.g. exported simulation or pipeline output) — use :class:`~pyralysis.io.ZarrDataset`:

.. code-block:: python

   from pyralysis.io import ZarrDataset
   dataset = ZarrDataset(input_name="/path/to/dataset.zarr").read()

See also :doc:`io_operations`.

**Q7: How do I quickly create a synthetic dataset?**
A: Follow the minimal example in :ref:`creating-dataset`. It shows how to set up the array, configure observation settings, define a simple point source, and run the simulator.

**Q7b: How do I set the output Measurement Set name when simulating?**
A: Simulation and writing are two steps. ``Simulator.simulate()`` only builds an
in-memory :class:`~pyralysis.base.dataset.Dataset` — there is no simulator
argument for the MS path. Set the name with :class:`~pyralysis.io.daskms.DaskMS`:

.. code-block:: python

   from pyralysis.io import DaskMS

   ms_io = DaskMS(output_name="my_observation.ms")
   ms_io.write(dataset=dataset, tables="ALL")

See :ref:`creating-dataset` and :doc:`io_operations`.

**Q8: How do I image (reconstruct) from visibilities with optimization?**
A: Define an objective function, select a line search, and run an optimizer — this is
**imaging** / **image reconstruction** in Pyralysis. See :doc:`usage` for a full example.
For a higher-level pattern, see :doc:`examples` (``optimization_components`` /
``optimization_pipeline`` scripts).

**Q9: How do I form a dirty image or dirty beam without an optimizer?**
A: Use :class:`~pyralysis.transformers.dirty_mapper.DirtyMapper` to grid visibilities to the dirty image and synthesized beam. See :doc:`gridding` and the ``dirtymapper_components`` / ``dirtymapper_pipeline`` scripts in :doc:`examples`.

**Q10: What is the difference between ``*_components.py`` and ``*_pipeline.py`` examples?**
A: **Components** scripts build classes explicitly so you can see wiring and customize behavior. **Pipeline** scripts use context + steps (e.g. :class:`~pyralysis.pipelines.imager.pipeline.ImagerPipeline`) for shorter, reproducible workflows. See :doc:`examples`.

---

Optimization and Line Search
----------------------------

**Q11: Why does Pyralysis use derivative-free line search methods?**
A: To avoid expensive gradient recomputation on large datasets. See :doc:`optimization` for details.

---

Data storage, weighting, and I/O
--------------------------------

**Q12: How do I save reconstructed images to disk?**
A: Pyralysis supports FITS and Zarr formats. See :doc:`usage` and :doc:`io_operations` for examples.

**Q13: What is the advantage of using Zarr over FITS for data cubes?**
A: Zarr is chunked and cloud-friendly: parallel reads/writes, easier integration with Dask, and scalable storage for large image cubes. FITS remains the standard for interchange of single astronomical images with rich headers.

**Q14: If I change visibility weighting (uniform, robust, or radial), do I need to refresh the dataset PSF?**
A: Yes, if you use the **analytical** PSF on the :class:`~pyralysis.base.dataset.Dataset` (e.g. FITS ``BMAJ``/``BMIN``/``BPA`` or model restoration with ``dataset.psf``). Those moments follow **imaging weights**; after you rewrite ``IMAGING_WEIGHT_SPECTRUM``, call ``dataset.calculate_psf()`` so the beam matches the weighted data. The default :class:`~pyralysis.pipelines.imager.steps.ApplyVisibilityWeighting` step applies ``uniform`` / ``robust`` / ``radial`` and refreshes the PSF; ``natural`` is a no-op on a freshly loaded MS (imaging weights already match ``WEIGHT``). The optimization CLI can use a different ``--restore-weighting`` than ``--weighting`` so residual gridding and the restoring beam need not match the optimization weights. Gridding with :class:`~pyralysis.transformers.dirty_mapper.DirtyMapper` uses the same imaging weights for both the dirty image and the dirty beam.

---

Didn't find your answer?
------------------------
.. note::
   - Check the full documentation: https://pyralysis.readthedocs.io/
   - Open an issue: https://gitlab.com/clirai/pyralysis/-/issues
   - Contact: miguel.carcamo@usach.cl

----

:doc:`quickstart` | :doc:`usage`
