Metadata-Version: 2.4
Name: telescope-sim
Version: 2.1.1
Summary: Composable, config-driven simulation of multi-aperture telescope PSFs, DMs, coronagraphs, and fiber coupling — built on HCIPy.
Author-email: Ian Cunnyngham <rums_revue_9i@icloud.com>
License: MIT License
        
        Copyright (c) 2026 Ian Cunnyngham / Morphoptic
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/icunnyngham/telescope-sim
Project-URL: Documentation, https://telescope-sim.readthedocs.io
Project-URL: Repository, https://github.com/icunnyngham/telescope-sim
Project-URL: Issues, https://github.com/icunnyngham/telescope-sim/issues
Keywords: astronomy,optics,telescope,psf,adaptive-optics,atmosphere,coronagraphy,hcipy,simulation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: hcipy>=0.6
Requires-Dist: pydantic>=2.0
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: ipykernel; extra == "dev"
Requires-Dist: ipywidgets; extra == "dev"
Provides-Extra: doc
Requires-Dist: sphinx>=7.0; extra == "doc"
Requires-Dist: sphinx_rtd_theme; extra == "doc"
Requires-Dist: nbsphinx; extra == "doc"
Requires-Dist: sphinx-automodapi; extra == "doc"
Requires-Dist: numpydoc; extra == "doc"
Requires-Dist: jupyter_client; extra == "doc"
Requires-Dist: nbclient; extra == "doc"
Requires-Dist: nbformat; extra == "doc"
Requires-Dist: nbconvert; extra == "doc"
Requires-Dist: ipykernel; extra == "doc"
Provides-Extra: fixtures
Requires-Dist: matplotlib; extra == "fixtures"
Requires-Dist: tqdm; extra == "fixtures"
Dynamic: license-file

# telescope-sim

[![CI](https://github.com/icunnyngham/telescope-sim/actions/workflows/testing.yml/badge.svg)](https://github.com/icunnyngham/telescope-sim/actions/workflows/testing.yml)
[![Docs](https://readthedocs.org/projects/telescope-sim/badge/?version=latest)](https://telescope-sim.readthedocs.io)
[![PyPI](https://img.shields.io/pypi/v/telescope-sim.svg)](https://pypi.org/project/telescope-sim/)
[![Python](https://img.shields.io/pypi/pyversions/telescope-sim.svg)](https://pypi.org/project/telescope-sim/)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

Composable, config-driven simulation of multi-aperture telescope PSFs, deformable
mirrors, coronagraphs, and fiber coupling — built on [HCIPy](https://hcipy.org).

`telescope-sim` provides a pluggable pipeline of optical stages (aperture,
correctors, coronagraph, focal plane, output taps, post-processing), a
YAML-driven configuration schema, and a fixture-based regression suite. Users
can register their own implementations of any stage without modifying the
package.

## Status

**v2.1.0.** The pipeline is wired end-to-end and reproduces 10
reference fixtures spanning segmented/mini-ELF apertures, custom-pupil
generators, Zernike-mode DMs, vortex and vector-vortex coronagraphs, angular
and physical focal planes, and multi-mode-fiber dual outputs.

### What's new since v2.0.0

- **Actuator-grid DM** — the `actuator_grid` corrector: an N×N
  influence-function deformable mirror (gaussian or xinetics actuator
  shapes) driven by raw per-actuator commands, with DM misalignment
  (rotation, mirrored command indexing) baked in at construction.
- **Atmosphere** — pass any HCIPy atmosphere (or any wf→wf callable) as
  `sim.sample(atmos=...)`. Atmospheres that expose `.phase_for(lam)` couple
  automatically into fit-role correctors for cancellation. The reference
  PSF is atmosphere-free by construction.
- **Detector noise** — the `noisy_detector` post-processor wraps HCIPy's
  `NoisyDetector` (read noise, dark current, flat-field, photon shot
  noise) with optional `int_phot_flux` photometry. Per-sample overrides
  via `sim.sample(output_overrides={...})`.
- **Extended-source convolution** — the `convolve_image` post-processor
  convolves the PSF with a caller-supplied scene. Composes with
  `noisy_detector` for noisy extended-source imaging.
- **Cumulative-OPD fit-role correctors** — `wavefront_role="fit"` with
  `fit_source="cumulative_phase_pre_self"` lets a DM auto-fit any upstream
  disturbance (atmosphere, imposed PTT, …) without bespoke wiring.
- **Strehl methods** — `strehl_method: peak | matched_filter`, with the
  matched-filter variant using a circular core mask of radius
  `strehl_core_rad`.
- **Extension tutorial** — `docs/tutorials/05_custom_components.ipynb`
  walks through writing your own `Corrector` and `PostProcessor` via the
  `@register(...)` registry.

## Quick start

```python
from telescope_sim import TelescopeSim
import numpy as np

# Bundled preset (mini-ELF, 15 segments, 2 filters)
sim = TelescopeSim.from_preset("elf_15seg")

# Or a custom YAML
sim = TelescopeSim.from_yaml("path/to/config.yaml")

# Sample at rest with Strehl ratios
out = sim.sample(meas_strehl=True)
out["images"]["psf"]      # (H, W, n_filters)
out["strehls"]            # {filter_name: ratio}

# Apply per-segment piston/tip/tilt actuations
ptt = np.random.normal(scale=0.1, size=(15, 3))
out = sim.sample(actuations={"segments": ptt}, meas_strehl=True)
```

See [docs/tutorials/](docs/tutorials) for runnable notebooks that exercise the
canonical mini-ELF, vortex coronagraph, custom-pupil + Zernike DM, and fiber
MMF paths.

## Architecture

The pipeline is a linear chain of pupil-plane stages (aperture → correctors →
optional coronagraph) followed by a controlled fan-out at the pupil → focal
boundary, where one or more named focal planes consume the same pupil-plane
wavefront. Each focal plane feeds one or more `OutputTap`s, whose outputs flow
through ordered post-processors. Every stage is a registered, pluggable
implementation of a small ABC. Configs are YAML, validated by pydantic v2.

```
[aperture] → [correctors: c1 → c2 → ... → cN] → [coronagraph?]
                                                    │
                                       ┌────────────┼────────────┐
                                       ▼            ▼            ▼
                                  focal plane  focal plane   focal plane
                                       │            │            │
                                     tap(s)       tap(s)       tap(s)
                                       │            │            │
                                    post-proc    post-proc    post-proc
```

Corrector roles (`actuate` / `impose` / `fit` plus a `target_strategy`) express
the patterns observed across years of research code: model-driven DMs, imposed
atmospheres, fit-residual training targets, and stacked combinations of those.
See [docs/concepts.rst](docs/concepts.rst) for the full discussion.

## Development

```bash
# Create dev environment
conda env create -f envs/env-dev.yaml
conda activate telescope-sim-dev

# If pip discovers a sibling hcipy/ clone (developers often keep one in
# ../external/hcipy/ for cross-reference), force-replace with the PyPI build:
pip uninstall -y hcipy && pip install "hcipy>=0.6"

# Install editable with dev extras
pip install -e ".[dev,doc]"

# Run tests
pytest                  # fast tests only
pytest --runslow        # includes the full fixture regression suite

# Build docs
cd docs && make html
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow.

## License

MIT — see [LICENSE](LICENSE).
