seestar-photometry
Time-domain photometry from ZWO Seestar smart-telescope stacks, calibrated onto Gaia DR3 synthetic Johnson V.
Built from two working pipelines — a δ-Scuti light curve of MW Cam (P = 0.1294 d, a ~23 mmag scatter floor) and a Type II supernova in NGC 3310 — generalised so the same recipe applies to a new target with a short driver script and no code edits.
The recipe:
- load a stack (either FITS layout — native Seestar or CrowdSky);
- detect sources with SEP and size a circular aperture per frame and per band from the curve of growth;
- solve a per-frame WCS and cache it beside the FITS — the on-board WCS is off by ~1 arcmin and unusable for photometry;
- cross-match a once-cached Gaia mosaic carrying synthetic JKC V;
- fit
V = m_inst + ZP + k·(B−R)on the green plane; - forced-aperture photometry at fixed sky positions, so no series ever goes ragged;
- per-frame ensemble zero point from N comparison stars, each referenced to its own catalogue magnitude.
Install
uv sync --extra dev
Python ≥ 3.11. Core deps are astropy, astroquery, numpy, scipy, sep;
matplotlib is the plot extra (the measurement path runs headless).
For plate solving, either install ASTAP (local,
offline, the default) or set ASTROMETRY_KEY for astrometry.net.
Quickstart
from seestar_photometry import Project, Target, LocalTree, pipeline, lightcurves, report
proj = Project(
target = Target("MW Cam", ra=186.6821, dec=81.474),
source = LocalTree(roots=[r"D:\data\MW Cam s50\stacks"]),
work_dir = r"D:\work\mwcam",
)
pipeline.solve_all(proj) # .wcs sidecars, idempotent
frames = pipeline.build_frame_table(proj, diagnostics=3) # frames.ecsv + figures
stars, meas = pipeline.build_measurements(proj) # stars.ecsv + measurements.ecsv
comps = lightcurves.select_comparisons(stars, dmag=1.0, colour_tol=0.3,
max_sep_arcmin=15)
lc = lightcurves.differential_lightcurve(
meas, lightcurves.target_id_of(stars), comps, band="G"
)
report.lightcurve_report(lc, stars, meas, comps, proj.diagnostics_dir)
print(f"{len(lc)} epochs, scatter {lc.meta['scatter'] * 1000:.0f} mmag")
All three stages are resumable — interrupt and re-run, they pick up where they stopped. Run them in order: stages 2 and 3 read the cached WCS and never solve.
See examples/ for complete drivers, including a supernova with host-galaxy
subtraction and a template for a new dataset.
Outputs
Everything derived lands in work_dir (never in the data tree, never in FITS headers).
The one exception is the per-frame .wcs sidecar, which lives beside its frame because
it is expensive to recompute and useful to every project touching that frame.
| File | What it is |
|---|---|
frames.ecsv |
one row per frame: zero point, colour term, scatter, PSF, sky, depth limits |
stars.ecsv |
one row per catalogue source measured, with separation from the target |
measurements.ecsv |
the long table: one row per (source, frame, band) |
diagnostics/*.png |
the figure sets below |
Diagnostics
Pass diagnostics= to a pipeline stage, or call report.* directly. Three sets:
- Per frame — curve of growth with the chosen aperture marked, per-band FWHM and its chromatic ratios, the zero-point relation and colour-term fit, residuals against magnitude / SNR / radius, a residual map over the frame, the background triptych, detections with apertures drawn on, and the cross-match separation histogram.
- Per dataset — zero point and conditions over time,
rmsandchi2_reddistributions against the photometric-grade cut, depth against exposure with the √t law overlaid and against its condition drivers, calibration coverage, and a one-page contact sheet. - Per light curve — finder chart, each comparison's own differential curve (the single most informative check — a variable or blended comparison shows up immediately, sorted worst-first), the ensemble zero point with its star-to-star spread, achieved scatter against comparison brightness, periodogram, and phase fold.
Documentation
docs/ holds the decision records — why each numerical choice is what it is, with
the measurements behind it. Start with docs/photometry-design.md.
CLAUDE.md holds the conventions to follow when changing code.
Tests
uv run pytest
Fully offline: synthetic frames with injected Gaussian PSFs of known flux, in both FITS layouts, so the tests assert recovery of a known zero point, colour term, aperture and period rather than merely that the code runs.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seestar_photometry-0.2.0.tar.gz.
File metadata
- Download URL: seestar_photometry-0.2.0.tar.gz
- Upload date:
- Size: 172.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6018c16b5f73d9fee12408eba1d331a203a43822cb8e52b79e79312abb390d79
|
|
| MD5 |
e22851d102199f8467288ccb836ea697
|
|
| BLAKE2b-256 |
b9527bab6a6298e1b820176c74f7d8935aa0e2f0a991a95f146260f3775c612f
|
File details
Details for the file seestar_photometry-0.2.0-py3-none-any.whl.
File metadata
- Download URL: seestar_photometry-0.2.0-py3-none-any.whl
- Upload date:
- Size: 103.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11a1ba403675a2a831ad13420193a8f2248b37bc4bfbe772d8bdc9aa751ab29d
|
|
| MD5 |
09f3d2b56c6e9242cb1eaeb06984fb2a
|
|
| BLAKE2b-256 |
35fe92aab6ae33dea0efa99ccc26c7e840fcc46d90696b58e2e0f1f6d0150131
|