Metadata-Version: 2.4
Name: unisky
Version: 0.3.2
Summary: Turn heterogeneous astronomical survey data into an interactive, WCS-aware web map
Author-email: Mingyu Li <lmytime@hotmail.com>
License-Expression: BSD-3-Clause
License-File: LICENSE
Keywords: astronomy,fits,gravitational-lensing,hst,jwst,survey,tiles,viewer,visualization,wcs
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.11
Requires-Dist: astropy>=8.0
Requires-Dist: click>=8.1
Requires-Dist: fastapi>=0.110
Requires-Dist: numpy>=1.24
Requires-Dist: pillow>=10.0
Requires-Dist: pydantic>=2.5
Requires-Dist: pyyaml>=6.0
Requires-Dist: regions>=0.8
Requires-Dist: reproject>=0.13
Requires-Dist: scikit-image>=0.21
Requires-Dist: uvicorn[standard]>=0.27
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

<p align="center">
  <a href="https://unisky.cc"><img src="https://unisky.cc/assets/favicon.svg" width="96" alt="UniSky"></a>
</p>

<h1 align="center">UniSky</h1>

<p align="center"><strong>Tiles that carry data, not pictures.</strong></p>

<p align="center">Turn heterogeneous astronomical survey data into an interactive, WCS-aware web map.</p>

<p align="center">
  <a href="https://pypi.org/project/unisky/"><img src="https://img.shields.io/pypi/v/unisky" alt="PyPI version"></a>
  <a href="https://pypi.org/project/unisky/"><img src="https://img.shields.io/pypi/pyversions/unisky" alt="Python versions"></a>
  <a href="https://github.com/lmytime/UniSky/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-BSD--3--Clause-green" alt="License: BSD-3-Clause"></a>
</p>

<p align="center">
  <a href="https://unisky.cc">unisky.cc</a> ·
  <a href="https://unisky.cc/docs.html">Documentation</a> ·
  <a href="https://unisky.cc/paper.pdf">Technical report</a> ·
  <a href="https://github.com/lmytime/UniSky">Source</a> ·
  <a href="https://github.com/lmytime/UniSky/blob/main/CHANGELOG.md">Changelog</a>
</p>

<p align="center">
  <a href="https://unisky.cc/assets/08-lens.jpg"><img src="https://unisky.cc/assets/08-lens.jpg" width="820" alt="Abell 2744 in UniSky: critical curves and caustics from the UNCOVER lens model over a JWST/NIRCam colour image, with the observed multiple images marked and the Lensing panel open"></a>
</p>
<p align="center"><em>Abell 2744. Critical curves and caustics from the UNCOVER lens model at z<sub>s</sub> = 3, over a JWST/NIRCam colour image with the observed multiple images marked.</em></p>

UniSky puts FITS images on any WCS, colour composites, catalogues, contours, DS9 regions, footprints and strong-lensing models on one map, in the spirit of the DESI Legacy Survey viewer and as a more capable replacement for FitsMap. A build is a folder of static files; serve it from one machine or from object storage.

## Install

Python 3.11 or newer.

```sh
pip install unisky
```

## Quickstart

No local data and no checkout are needed. Save this as `abell2744.yaml`: three DESI Legacy Survey DR11 bands and the Tractor catalogue for Abell 2744, downloaded on the first build (about 16 MB, about half a minute) and cached afterwards.

```yaml
field:
  name: Abell 2744
  grid: {ra0: 3.5862, dec0: -30.4003, scale_arcsec: 0.262, width: 1100, height: 1100}

layers:
  - id: g
    type: image
    title: DESI-LS g
    source: {survey: legacy, release: dr11, band: g, ra: 3.5862, dec: -30.4003, width_arcmin: 5}
  - id: r
    type: image
    title: DESI-LS r
    source: {survey: legacy, release: dr11, band: r, ra: 3.5862, dec: -30.4003, width_arcmin: 5}
  - id: z
    type: image
    title: DESI-LS z
    source: {survey: legacy, release: dr11, band: z, ra: 3.5862, dec: -30.4003, width_arcmin: 5}
  - id: grz
    type: composite
    title: grz
    channels: {r: z, g: r, b: g}
    visible: true
  - id: tractor
    type: catalog
    title: Tractor sources
    source: {survey: legacy, release: dr11, ra: 3.5862, dec: -30.4003, width_arcmin: 5, columns: [mag_r]}
    popup: [ra, dec, mag_r]
```

```sh
unisky build abell2744.yaml -o site/ && unisky serve site/
```

Then open <http://127.0.0.1:8000/>. Eight layer types, each one entry in the config: `image`, `composite`, `catalog`, `contour`, `region`, `prerendered`, `footprint` and `lensmodel`. The [configuration reference](https://unisky.cc/docs.html#config) has the rest.

## Commands

```
unisky build config.yaml -o site/     # ingest data, write a self-contained site
unisky serve site/                    # static files + the science API
unisky add config.yaml -o site/ ID    # build one more layer into a built site
unisky remove -o site/ ID             # take one back out
unisky capabilities site/             # show or set what a deployment offers (--no-cutout, --static)
unisky refresh site/                  # new viewer + content versions; no tile rebuilt
```

Each is described in the [command-line reference](https://unisky.cc/docs.html#cli).

## What it does

- **Data tiles.** Image tiles are quantised 16-bit data, not pictures: black and white point, stretch function (linear, sqrt, log, asinh, power) and colormap change instantly in the browser, with no refetch and no server. The Stretch window draws a histogram of the decoded tiles, with draggable black and white marks.
- **Any WCS in, one map out.** Images on TAN, SIN, CAR and other grids are reprojected onto one gnomonic display grid, for display only; science operations use the native pixels.
- **Native-grid cutouts.** The cutout API returns FITS whose pixels are bit-identical to the source, with a correctly shifted WCS.
- **Catalogues.** Configurable popups, a joined second table, markers coloured by any column and hover highlight. `search:` columns make sources findable from the go-to box, and the Sources window (T) filters, sorts and steps through the catalogue with the arrow keys, with a preview stamp on hover.
- **Vector overlays.** Contours with sigma-scaled levels traced in the native pixel grid, DS9 region files and footprints.
- **Strong lensing, live.** Critical curves and caustics with a source-redshift slider, magnification at the cursor, counter-image prediction with time delays when the model carries a potential, and κ and μ as map layers (glafic-convention models).
- **Composite RGB.** Each channel is one band or a weighted sum, combined per channel or by Lupton's rule, in the same grammar the viewer's RGB panel reads and prints: a composite designed in the browser pastes into the config.
- **Remote data.** Legacy Survey cutouts, HiPS and TAP catalogues are downloaded and cached, so a config can name no local file at all.
- **Incremental builds.** Add or remove layers of a built site without touching the rest; the display grid is reused exactly, and a conflicting config is refused with the fix spelled out.
- **Deployment.** One machine with uvicorn and nginx, or static object storage (Cloudflare R2) with `/api` through a tunnel. A site declares which of cutout and lensing it offers and the viewer hides what a deployment cannot serve. Tile and overlay URLs are keyed by content, so a rebuilt layer reaches browsers that cached the old one.
- **In the browser.** Permalinks in the URL hash, so a view is a link; coordinate readout; a go-to box that takes decimal or sexagesimal; uploads of your own regions and catalogues; optional basic auth; and a phone layout at 720 px and narrower in which every panel is a bottom sheet.

## Documentation

- [Reference](https://unisky.cc/docs.html): [install](https://unisky.cc/docs.html#install) · [quickstart](https://unisky.cc/docs.html#quickstart) · [how it works](https://unisky.cc/docs.html#concepts) · [configuration](https://unisky.cc/docs.html#config) · [layer types](https://unisky.cc/docs.html#layers) · [the viewer](https://unisky.cc/docs.html#viewer) · [command line](https://unisky.cc/docs.html#cli) · [HTTP API](https://unisky.cc/docs.html#api) · [permalinks](https://unisky.cc/docs.html#permalinks) · [the data tile](https://unisky.cc/docs.html#tiles) · [the display grid](https://unisky.cc/docs.html#grid) · [lensing engine](https://unisky.cc/docs.html#lensing) · [remote data](https://unisky.cc/docs.html#remote) · [add and remove](https://unisky.cc/docs.html#incremental) · [deployment](https://unisky.cc/docs.html#deploy) · [troubleshooting](https://unisky.cc/docs.html#troubleshooting)
- Notes in the repository: [parallel builds and progress](https://github.com/lmytime/UniSky/blob/main/docs/build.md) · [deployment](https://github.com/lmytime/UniSky/blob/main/docs/deploy.md) · [incremental builds](https://github.com/lmytime/UniSky/blob/main/docs/incremental.md) · [reprojection](https://github.com/lmytime/UniSky/blob/main/docs/reprojection.md) · [remote data](https://github.com/lmytime/UniSky/blob/main/docs/remote-data.md) · [composites](https://github.com/lmytime/UniSky/blob/main/docs/composites.md) · [prerendered images](https://github.com/lmytime/UniSky/blob/main/docs/prerendered.md) · [alignment](https://github.com/lmytime/UniSky/blob/main/docs/alignment.md) · [lens-model normalisation](https://github.com/lmytime/UniSky/blob/main/docs/lensing-normalization.md) · [uploads](https://github.com/lmytime/UniSky/blob/main/docs/uploads.md) · [development and testing](https://github.com/lmytime/UniSky/blob/main/docs/development.md) · [the viewer bundle](https://github.com/lmytime/UniSky/blob/main/docs/frontend-bundle.md) · [upgrading from AnyMap](https://github.com/lmytime/UniSky/blob/main/docs/upgrading-from-anymap.md)
- [Technical report](https://unisky.cc/paper.pdf): the tile format and its error characteristics, the display grid, the lensing engine and the incremental build model.
- [Changelog](https://github.com/lmytime/UniSky/blob/main/CHANGELOG.md).

## License

BSD-3-Clause, see [LICENSE](https://github.com/lmytime/UniSky/blob/main/LICENSE). Written by Mingyu Li.
