Skip to main content

Star detection, WCS fitting, and hinted/blind plate solving for astrophotography

Project description

seiza (Python)

Python bindings for seiza: star detection, WCS fitting, and hinted/blind plate solving for astrophotography, implemented in Rust. Solves typical frames in a fraction of a second.

pip install seiza

Binary wheels cover Linux (x86_64, aarch64), macOS (universal2), and Windows (x64); each is a single abi3 wheel for every CPython from 3.9 up. Type stubs are included, and solving releases the GIL.

Solve an image

import numpy as np
import seiza

# One-time: download the verified solver catalogs into the shared cache.
paths = seiza.fetch_catalogs()  # lightweight Tycho-2 set
catalog = seiza.StarCatalog.open(paths["stars-lite-tycho2.bin"])

# Detect stars in a 2D float32 (or uint8) luma array.
stars = seiza.detect(image_array)

# Hinted solve: approximate center and pixel scale. sip_order=3 also fits
# SIP distortion polynomials when enough matched stars support them.
solution = seiza.solve(
    stars, catalog, width, height,
    ra=150.1, dec=35.2, scale_arcsec_px=2.5, sip_order=3,
)
print(solution)                 # center, scale, matches, RMS
print(solution.rotation_deg, solution.flipped)
ra, dec = solution.wcs.pixel_to_world(100.0, 200.0)

open takes a file, a directory (the right catalog inside is picked — the deepest star catalog wins), or nothing at all. With no argument the standard places are searched: SEIZA_STAR_DATA / SEIZA_BLIND_INDEX, files next to the program, and the seiza setup directories (SEIZA_CATALOG_DIR). These are the same rules as the CLI's --data:

catalog = seiza.StarCatalog.open("data")   # directory
catalog = seiza.StarCatalog.open()         # after seiza setup

Stars can also be plain (x, y, flux) tuples from any other detector — the solver only needs positions and relative brightness:

solution = seiza.solve([(x1, y1, f1), (x2, y2, f2), ...], catalog, w, h,
                       ra=..., dec=..., scale_arcsec_px=...)

Blind solve

No position hint, only a plausible scale range. Uses the prebuilt whole-sky pattern index and the deep Gaia catalog:

paths = seiza.fetch_catalogs(["stars-deep-gaia17.bin", "blind-gaia16.idx"])
catalog = seiza.StarCatalog.open(paths["stars-deep-gaia17.bin"])
index = seiza.BlindIndex.open(paths["blind-gaia16.idx"])
solution = seiza.solve_blind(stars, catalog, index, width, height,
                             min_scale_arcsec_px=0.5, max_scale_arcsec_px=15.0)

For faint fields, the optional stars-deep-gaia20.bin catalog reaches Gaia G≤20 (about 9 GB). It is intentionally not included in fetch_catalogs("all"), so request it explicitly with the same G≤16 blind index:

paths = seiza.fetch_catalogs(["stars-deep-gaia20.bin", "blind-gaia16.idx"])
catalog = seiza.StarCatalog.open(paths["stars-deep-gaia20.bin"])
index = seiza.BlindIndex.open(paths["blind-gaia16.idx"])

FITS WCS output

Solutions convert directly to FITS WCS keywords (1-indexed CRPIX, TAN or TAN-SIP projection, CD matrix, and the complete A_p_q/B_p_q/AP_p_q/ BP_p_q set when distortion was fitted):

cards = solution.fits_header_cards()   # dict of keyword -> value
text = solution.fits_header_text()     # 80-column cards ending with END

The header text form is suitable for header-injection APIs — for example Siril's sirilpy scripting interface (set_image_header), which makes a seiza solve usable from a Siril Python script.

Predicted satellite tracks

After a solve, predict which satellites crossed the image while the shutter was open. Predictions come from orbital elements — they are never pixel detections. The exposure must be one continuous shutter-open interval (not a stack's total integration) and needs an observer location:

sats = seiza.SatelliteCatalog.fetch_celestrak()   # cached; ~2h refresh floor
# or offline / historical: seiza.SatelliteCatalog.open("elements.json")

result = sats.tracks_in_footprint(
    solution.wcs, width, height,
    start="2026-07-19T06:12:00Z",     # Unix seconds, RFC 3339, or tz-aware datetime
    duration_s=120.0,
    latitude=42.466, longitude=-71.1516, altitude_m=150.0,
)
for track in result.tracks:           # highest elevation first
    print(track.label, track.max_elevation_deg, track.clipped_segments)

Element records older than seven days are reported in result.stale_elements and skipped rather than silently extrapolated (max_element_age_s=None overrides). CelesTrak rate-limits repeated downloads: keep reusing one cache directory, and check sats.cache_state and sats.warning after fetch_celestrak().

Notes

  • Solving and detection release the GIL; other Python threads keep running.
  • Catalog files are memory-mapped and SHA-256 verified at download time; fetch_catalogs caches under the platform cache directory (override with cache_dir= or SEIZA_CACHE_DIR).
  • seiza.StarCatalog.from_stars([...]) builds a small in-memory catalog for tests and synthetic fields.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seiza-0.11.2.tar.gz (212.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

seiza-0.11.2-cp39-abi3-win_amd64.whl (2.4 MB view details)

Uploaded CPython 3.9+Windows x86-64

seiza-0.11.2-cp39-abi3-manylinux_2_28_aarch64.whl (2.4 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

seiza-0.11.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

seiza-0.11.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (4.5 MB view details)

Uploaded CPython 3.9+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file seiza-0.11.2.tar.gz.

File metadata

  • Download URL: seiza-0.11.2.tar.gz
  • Upload date:
  • Size: 212.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for seiza-0.11.2.tar.gz
Algorithm Hash digest
SHA256 3aed844c83756af769f552cf02717af4b2c05ab8f05d42b7937cdc083092e3ba
MD5 85d88eadc834ac5bc79d46b6df392f83
BLAKE2b-256 d11ebf5024976f30554fd73eea5d5f5a5f4aeab0e2c45aae52004d7285b6e60e

See more details on using hashes here.

Provenance

The following attestation bundles were made for seiza-0.11.2.tar.gz:

Publisher: python-wheels.yml on theatrus/seiza

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seiza-0.11.2-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: seiza-0.11.2-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.4 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for seiza-0.11.2-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 dec76103f8e876279b7d5adb45e964d10a35ae3c340535bfc9ac3e53d26ee849
MD5 cce6a145f49ef747e3fb4e7a98abc797
BLAKE2b-256 300628d7f3d13f0f3e779569e2ae6fa4875ba7fab8a6ec7217eb21993a144f3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for seiza-0.11.2-cp39-abi3-win_amd64.whl:

Publisher: python-wheels.yml on theatrus/seiza

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seiza-0.11.2-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for seiza-0.11.2-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8cf17f4029d1fd8d6ed5ee1b0c251600624f90e7a388dcbcd149e81fb06ff455
MD5 126dc6cf5c9b7e9b15576b7227246056
BLAKE2b-256 165b1fc7e16e9bf3e5b348d57a889a3412b08893ef456f8c6b6ebd09a8981836

See more details on using hashes here.

Provenance

The following attestation bundles were made for seiza-0.11.2-cp39-abi3-manylinux_2_28_aarch64.whl:

Publisher: python-wheels.yml on theatrus/seiza

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seiza-0.11.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for seiza-0.11.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 813d5c046d05066e5bac8a2c1851e9799ec99f26333ee5103be7e408632d8789
MD5 8581b55213ec6fbcfd8bcfa4a3c91aff
BLAKE2b-256 920077e3bf791580af95ffbf5815535ceda31a3a32966cc8d1fafdef7a76501d

See more details on using hashes here.

Provenance

The following attestation bundles were made for seiza-0.11.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: python-wheels.yml on theatrus/seiza

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seiza-0.11.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for seiza-0.11.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 7c68125aca4a3dda003b6ffcd3a45bb884ce3bef3e5293ea32de8ed703194edb
MD5 3fb30cecf64ba2e5ee4138609c7644a2
BLAKE2b-256 c1ab98f6e7f968afb2e3e31cf792290d491366806d2635b36b2b39d4245aa14b

See more details on using hashes here.

Provenance

The following attestation bundles were made for seiza-0.11.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: python-wheels.yml on theatrus/seiza

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page