Metadata-Version: 2.4
Name: ngcs
Version: 0.1.0
Summary: Quick and simple access to clean images of NGC galaxies (SGA-2020 catalog, Legacy Surveys / Pan-STARRS cutouts, Gaia star removal)
Author-email: Mickael Rigault <mickael.rigault@cnrs.fr>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/MickaelRigault/ngcs
Keywords: astronomy,astrophysics,galaxies
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26
Requires-Dist: scipy
Requires-Dist: astropy
Requires-Dist: pandas
Requires-Dist: pyarrow
Requires-Dist: requests
Provides-Extra: plot
Requires-Dist: matplotlib; extra == "plot"
Provides-Extra: tests
Requires-Dist: pytest; extra == "tests"
Requires-Dist: coverage; extra == "tests"
Requires-Dist: matplotlib; extra == "tests"
Provides-Extra: docs
Requires-Dist: matplotlib; extra == "docs"
Requires-Dist: myst-nb; extra == "docs"
Requires-Dist: sphinx>=7.2; extra == "docs"
Requires-Dist: sphinx-book-theme; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Requires-Dist: sphinx-design; extra == "docs"
Dynamic: license-file

# ngcs
Quick and simple way to access NGC galaxy images with python.

For any of the 4221 NGC galaxies of the [Siena Galaxy Atlas 2020](https://www.legacysurvey.org/sga/sga2020/)
(SGA-2020), `ngcs` gives:
- its **metadata**: position, redshift, size (at the 26 mag/arcsec² isophote), g, r, z magnitudes and colours;
- its **image** from the DESI Legacy Surveys (DR10) or Pan-STARRS1, in nanomaggies per pixel, with its WCS;
- the same image **without the foreground stars** (Gaia DR3), masked and filled;
- the **galaxy alone**: stars removed, sky subtracted, nothing around (0 outside the galaxy), cropped and centred:
  e.g. to simulate the galaxy at another redshift.

## Installation

```bash
pip install -e .            # numpy, scipy, astropy, pandas, pyarrow, requests
pip install -e ".[plot]"    # + matplotlib, for the show() methods
```

## Usage

```python
import ngcs

galimg = ngcs.GalaxyImage.from_name("NGC 6643")      # 'NGC6643', 'ngc 6643', or 'M74' (resolved by Sesame)
image = galimg.get_image()                           # the Legacy Surveys cutout (an ngcs.Image)
image_nostars = galimg.get_image(rm_stars="auto")    # without the Gaia stars
galaxy = galimg.get_galaxy()                         # the galaxy alone
metadata = galimg.get_metadata()                     # name, ra, dec, redshift, sma, diameter, mag_g/r/z, g-r...

galaxy.data, galaxy.pixel_scale, galaxy.meta["center_pixel"]   # array [nmgy/pixel], arcsec, (x, y)
galimg.show()                                        # diagnostic plot
```

An `ngcs.Image` holds `data` (2d, or a (nbands, ny, nx) cube), `wcs`, `bands`, `pixel_scale` and `meta`, and
has `band()`, `magnitude()`, `show()`, `to_fits()` and `Image.from_fits()`.

### Options

```python
ngcs.GalaxyImage.from_name("NGC 6643", survey="panstarrs", bands="gri", margin=2)  # field = margin x D26
galimg.get_image(rm_stars="sky")                      # fill the stars with a fake sky
galimg.get_image(rm_stars="interpolate")              # ... or by interpolation
galimg.get_image(rm_stars="auto", radius_scale=1.5)   # larger star masks
galimg.get_galaxy(isophote=25)                        # tighter galaxy [AB mag/arcsec²]
ngcs.GalaxyImage.from_image("my_image.fits", metadata={"ra": ..., "dec": ..., "sma": ...})  # any image
ngcs.get_catalog()                                    # the whole catalog (pandas.DataFrame)
```

| `rm_stars` | the star holes are filled with |
|---|---|
| `"auto"` (default) | interpolation + sky noise on the galaxy, a fake sky (large-scale background + noise) elsewhere |
| `"sky"` | a fake sky everywhere (in `get_galaxy`, the holes inside the galaxy are always interpolated) |
| `"interpolate"` | Gaussian interpolation from the surroundings |

| `survey` | pixel | notes |
|---|---|---|
| `"legacysurvey"` (default) | 0.262" | deeper, good sky subtraction around large galaxies; max 3000 pixels (coarser beyond) |
| `"panstarrs"` | 0.25" | faster; one sky cell (NaN beyond its edge, filled); poorer sky around large galaxies |

## How it works

- **Stars**: the Gaia DR3 sources (VizieR TAP) with a parallax or proper motion detected at more than 5 sigma: the
  HII regions, clusters and nucleus of the galaxy are also Gaia sources, but they do not move. Each star is masked
  within a radius growing with its brightness (2.5" at G = 18, x 10^0.1 per magnitude, between 2" and 25"), grown to
  the connected pixels more than 3 sky sigma away from the local background (halos, spikes, bleed trails).
- **Galaxy alone**: the connected region around the galaxy centre brighter than 26 mag/arcsec² (r band, smoothed),
  holes filled, grown by 2", limited to an ellipse of 1.2 x the SGA size with the axis ratio and orientation of the
  galaxy (image moments).
- **Cache**: every download (cutouts, Gaia) is kept in `~/.cache/ngcs` (or `$NGCS_CACHE`): a second call is
  instantaneous. `ngcs.io.clear_cache()` empties it.

Faint stars (G ≳ 19) without a significant parallax or proper motion, and background galaxies seen through the disk,
stay in the images.

## Tests

```bash
pip install -e ".[tests]"
pytest                  # offline tests (synthetic images)
pytest --remote-data    # + the tests that download images and Gaia stars
```

## Credits

SGA-2020: Moustakas et al. 2023, ApJS 269, 3. Legacy Surveys: Dey et al. 2019. Pan-STARRS1: Chambers et al. 2016.
Gaia DR3: Gaia Collaboration, Vallenari et al. 2023.
