Metadata-Version: 2.5
Name: astro-ndslice
Version: 0.4
Summary: Convenience tools for slicing images & calculating offsets before combinations (focusing on converting astronomical FITS/IRAF and python conventions)
Project-URL: Source, https://github.com/ysBach/astro-ndslice
Project-URL: Tracker, https://github.com/ysBach/astro-ndslice/issues
Author-email: "Yoonsoo P. Bach" <ysbach20766@gmail.com>
License: BSD 3-Clause License
        
        Copyright (c) 2023, Yoonsoo P. Bach
        
        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.
License-File: LICENSE
Keywords: astronomy,data reduction,image analysis
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Education
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.10
Requires-Dist: numpy>=1.23
Provides-Extra: dev
Requires-Dist: astropy>=5.3.3; extra == 'dev'
Requires-Dist: isort; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: full
Requires-Dist: astropy>=5.3.3; extra == 'full'
Description-Content-Type: text/markdown

# astro-ndslice

[![DOI](https://zenodo.org/badge/601666411.svg)](https://zenodo.org/badge/latestdoi/601666411)

Slice NumPy arrays, convert FITS/IRAF sections, and align images by pixel offsets.

## Install

```bash
pip install astro-ndslice
```

Python >= 3.10.

For astronomers who need WCS/header offset helpers:

```bash
pip install "astro-ndslice[full]"
```

## Slice an image

```python
import numpy as np
from astro_ndslice import slicefy

data = np.arange(100).reshape(10, 10)
cutout = data[slicefy("[2:5,3:7]")]  # Same as data[2:7, 1:5].
trimmed = data[slicefy(1)]          # Trim one pixel from each edge - bezeling.
```

* **FITS sections** use **1-based, inclusive bounds in x, y order**.
* **NumPy** uses **0-based, exclusive stops in row, column order**.
* `slicefy()` assumes FITS strings
* `slice_from_string()` assumes Python strings unless you pass `fits_convention=True`.

## Align images

```python
import numpy as np
from astro_ndslice import offseted_shape, offsets2slice

images = [np.ones((3, 4)), np.full((2, 3), 2)]
shapes = [image.shape for image in images]  # NumPy axis order.
offsets = [(0, 0), (2, 1)]                # x, y offsets.
_, shape = offseted_shape(shapes, offsets)
indices = offsets2slice(shapes, offsets)
stack = np.full((len(images), *shape), np.nan)
for image, index in zip(images, indices):
    stack[index] = image
```

Both helpers round relative offsets to pixel positions. Use `method="inner"`
to find the region shared by every image; no shared pixels raises `ValueError`.

## Function guide

| Task | Functions |
| --- | --- |
| Normalize scalars and iterables | `is_list_like`, `listify`, `ndfy` |
| Parse sections and trim edges | `slicefy`, `slice_from_string`, `slice_to_string`, `bezel2slice` |
| Place images and find overlap | `regularize_offsets`, `offseted_shape`, `offsets2slice` |
| Read WCS or physical offsets | `calc_offset_wcs`, `calc_offset_physical` (requires Astropy) |

`calc_offset_physical()` corrects LTV translation terms
for LTM scaling in shared physical-coordinate units. For example,
`LTV1=6, LTM1_1=2` gives `3` along x; `ignore_ltm=True` gives the raw value `6`.
This preserves the LTV sign; differing LTM matrices require resampling for
image alignment.

See [CHANGELOG.md](CHANGELOG.md) for return-type changes and stricter validation.
For version bumps and PyPI publishing, see [RELEASING.md](RELEASING.md).
