Metadata-Version: 2.4
Name: grismagic
Version: 0.1.1
Summary: Grism configuration readers and trace/dispersion utilities
Author-email: Example Author <author@mpia.de>
License: BSD 3-Clause License
        
        Copyright (c) 2024,  Max Planck Institute for Astronomy
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        1. Redistributions of source code must retain the above copyright notice, this
           list of conditions and the following disclaimer.
        
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
        
        3. Neither the name of the copyright holder nor the names of its
           contributors may be used to endorse or promote products derived from
           this software without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        
Project-URL: Bug Tracker, https://github.com/mpi-astronomy/grismagic/issues
Project-URL: Source Code, https://github.com/mpi-astronomy/grismagic
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: asdf
Requires-Dist: jax
Provides-Extra: roman
Requires-Dist: pyyaml; extra == "roman"
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx-automodapi; extra == "docs"
Requires-Dist: numpydoc; extra == "docs"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: flake8; extra == "test"
Requires-Dist: flake8-pyproject; extra == "test"
Requires-Dist: jwst; extra == "test"
Requires-Dist: grismconf; extra == "test"
Dynamic: license-file

# grismagic

Grism configuration readers and trace/dispersion utilities for slitless spectroscopy simulations.

Provides a unified Python interface for reading grism configuration files across multiple formats (aXe, GRISMCONF, JWST CRDS), computing grism traces, and dispersing 2D spatial images onto a detector using JAX.

## Modules

### `grismagic.readers`

Low-level readers for four grism configuration formats:

| Class | Format | Instruments |
|---|---|---|
| `aXeConfReader` | aXe `.conf` text files | HST WFC3, ACS, NIRISS |
| `EuclidaXeConfReader` | Euclid NISP aXeSIM `.conf` files | Euclid NISP (RGS000, RGS180) |
| `GRISMCONFReader` | GRISMCONF `.conf` text files | JWST NIRCam, NIRISS |
| `CRDSReader` | JWST CRDS `specwcs` `.asdf` files | JWST NIRCam, NIRISS |

The aXe readers expose `get_beam_trace(x, y, dx, beam)` → `(dy, wavelength)` in the conf frame. `GRISMCONFReader` and `CRDSReader` expose `DISPX`, `DISPY`, `DISPL` and their inverses.

Note: `EuclidaXeConfReader` is currently experimental. It overrides `get_beam_trace` to correct the DLDP sign convention so it reflects and adds `get_det_trace(x_det, y_det, dx_conf, beam)` --> `(x_trace, y_trace, wavelength)`, which handles the conf-->detector coordinate transpose and empirical position offsets. 

### `grismagic.traces`

`GrismTrace` wraps any reader with a consistent API:

```python
from grismagic.traces import GrismTrace
import numpy as np

# Load from any supported format
tr = GrismTrace.from_axe("WFC3.G141.conf")
tr = GrismTrace.from_grismconf("NIRCAM_F444W_modA_R.conf")
tr = GrismTrace.from_crds("jwst_nircam_specwcs_0136.asdf")
tr = GrismTrace.from_file("any_supported_file")  # auto-detects format

# Available spectral orders
print(tr.orders)  # e.g. ['A', 'B'] for aXe, ['+1', '0', '-1'] for GRISMCONF

# Trace at pixel offsets dx from source at (x, y)
dx = np.arange(*tr.dx_range("A"))  # valid pixel range for this order
x_trace, y_trace, lam = tr.get_trace(507., 507., order="A", dx=dx)

# Trace at specific wavelengths
x_trace, y_trace = tr.get_trace_at_wavelength(507., 507., order="A",
                                               lam=np.linspace(8000, 17000, 200))

# Multiple sources at once
x_traces, y_traces, lams = tr.get_traces(xs, ys, order="A", dx=dx)

# Remove an order
tr.remove_beam("B")
```

Wavelength units follow the native format convention: **Angstrom** for aXe and GRISMCONF, **micron** for CRDS.

### `grismagic.disperse`

JAX-based disperser. Convolves a 2D spatial image with a 1D spectrum and scatters the flux onto an output detector using bilinear interpolation.

```python
import jax
import jax.numpy as jnp
from grismagic.traces import GrismTrace
from grismagic.disperse import disperse_obj, disperse_galaxies

tr = GrismTrace.from_axe("WFC3.G141.conf")
dx = jnp.arange(*tr.dx_range("A"))
x_trace, y_trace, lam = tr.get_trace(507., 507., "A", dx)

# Sample spectrum at trace wavelengths
sens = jnp.interp(lam, spec_wave, spec_flux)

# Disperse a single galaxy
output = jnp.zeros((1014, 1014))
output = disperse_obj(galaxy_image, 507., 507., x_trace, y_trace, sens, output)

# JIT compile for repeated calls
disperse_jit = jax.jit(disperse_obj, static_argnames=("chunk_size",))

# Disperse multiple galaxies onto a single detector
output = disperse_galaxies(images, x_srcs, y_srcs, x_traces, y_traces,
                           sensitivities, output_shape=(1014, 1014))
```

The disperser uses the shift-invariant trace approximation (same as grizli): the trace computed at the source center is translated by each spatial pixel's offset. For extended objects where field-dependent trace variations across the source extent matter, compute per-pixel traces with `GrismTrace.get_traces`.

## Installation

```bash
pip install -e .
```

For development (no test suite yet):

```bash
pip install -e ".[test]"
```

## Dependencies

- `numpy`
- `jax` — required for `grismagic.disperse`
- `asdf` — required for CRDS `.asdf` readers

## Acknowledgements

This package was built using the [MPIA Python Package Template](https://github.com/mpi-astronomy/mpia-python-template) [![DOI](https://zenodo.org/badge/472725375.svg)](https://zenodo.org/badge/latestdoi/472725375).
