HARP - Horizon-Aware Recommender and Planner for deep-sky astrophotography sessions
Project description
HARP
image the sky your balcony can actually see
Horizon-Aware Recommender and Planner
A CLI planner for deep-sky astrophotography sessions. Given a date, a site, your telescope + camera, the real horizon of your spot and the Moon, HARP ranks the targets you can actually image tonight — usable windows, Moon impact, and mosaic framing tailored to your rig.
| 🧱 Horizon-aware visibility Measure your site's obstructions once as an azimuth-dependent mask ( .hrz, N.I.N.A.-compatible). A target counts as observable only when its altitude clears the ridge/wall in its own direction — not against an idealized flat horizon. Horizon guide |
⏱️ Continuous imaging windows Per target: total usable hours during astronomical darkness plus the longest continuous run before it enters a blocked sector — the number you actually size exposures and mosaic panels on. Reading the output |
| 🏆 Desirability ranking Every target gets a 0-100 score: a weighted geometric mean of continuous window, total hours, peak altitude (inverse-airmass), Moon verdict, and how well the object fills your field of view — so one hopeless factor sinks a target instead of averaging away. --sort hours restores the classic order. |
🌙 Moon impact model Phase and separation folded into a per-target verdict — none, ok(NB), low/med/high — with narrowband auto-derived from the object type: planetaries, supernova remnants and HII regions shrug at a Moon that ruins broadband RGB. |
| 🖼️ Mosaic framing & panel coordinates Your focal length + sensor decide 1 frame or mosaic NxM; harp mosaic then emits the actual per-panel RA/Dec centers (overlap-aware, position-angle rotated, correct at any declination) — plus single-frame crop suggestions for the monsters. Mosaic guide |
🎯 N.I.N.A. integration The same .hrz horizon drives both tools, and --nina exports ranked targets or mosaic panels as CSVs N.I.N.A.'s sequencer imports directly — verified against N.I.N.A.'s actual parser source. Plan in HARP, shoot in N.I.N.A., retype nothing. N.I.N.A. guide |
| 🔭 Offline catalogues + your own Curated large emission nebulae (deliberately not magnitude-filtered), full Messier/NGC/IC via pyongc ( --catalogs M,NGC,IC), and a user targets file that overrides everything (--targets). Cross-identification dedup: M42 and NGC1976 are one object, M43 stays its own. No network at run time. |
📈 Table, CSV, charts, links A ranked terminal table, a CSV for your session log — each target with an informative web link (SIMBAD, Wikipedia, AstroBin, or Aladin, built offline) — altitude charts with the horizon band overlaid, and harp info TARGET for details on demand. |
Full documentation — installation, usage, horizon measuring, configuration
What HARP does
harp plan # tonight, default site/optics from config
harp plan 2026-08-15 --site balcony --optics newton800
harp plan --catalogs M,NGC,IC --targets my_targets.yaml # full catalog + your objects
harp plan --nina tonight.csv # export ranked targets for N.I.N.A.
harp mosaic IC1396 --pa 30 --nina panels.csv # per-panel coords -> N.I.N.A. sequencer
harp list # sites and optics defined in the config
harp horizon points.yaml -o balcony.hrz # measured vertices -> .hrz horizon file
=== Night 2026-08-15 | Castelli Balcony 41.7380,12.8899 ===
Astronomical darkness: 21:53 -> 04:32 local
Moon: ~12% illuminated | above horizon: below horizon all night
Setup: 800 mm + custom 23.5x15.7
Field of view: 101' x 67' | horizon: balcony.hrz
# object score kind const hrs cont window altMx az moonSep Moon frame
--------------------------------------------------------------------------------------------------------
1 NGC281 Pacman 99 Nebula Cas 6.7 6.7 21:53-04:28 75 0 127 none 1 frame
2 NGC7380 Wizard 99 Nebula Cep 5.2 5.2 21:53-03:03 73 0 124 none 1 frame
3 NGC1039 99 Open Clus Per 6.7 6.7 21:53-04:28 71 78 128 none 1 frame
4 IC59/63 Ghost of Cas 99 Nebula Cas 6.7 6.7 21:53-04:28 71 360 122 none 1 frame
5 Sh2-155 Cave 98 Nebula Cep 5.8 5.8 21:53-03:38 69 0 121 none 1 frame
The typical flow: measure the horizon once → generate the .hrz → load it
in N.I.N.A. and in HARP → plan the night → export the ranked targets (or the
mosaic panels) straight into N.I.N.A.'s sequencer. See
examples/ for a working config, horizon file, and sample outputs.
The name
A harp is the celestial Lyre — the constellation Lyra, home of Vega and the Ring Nebula. And the acronym leads with the input most planners ignore: your horizon.
Installation
pip install harp-astro
The distribution is harp-astro (the bare PyPI name is squatted by an empty
project; a PEP 541 request is pending) — the installed package and the CLI
command are plain harp.
From source:
git clone https://github.com/szaghi/harp
cd harp
make dev
Configuration
Sites (position + .hrz + timezone) and optical setups (focal + sensor) live in
sites.yaml, searched in the current directory and ~/.config/harp/.
Precedence: CLI option > config value > built-in default. Details in the
usage guide.
Android app (experimental)
An Android frontend lives in android/: the same Python core,
embedded on-device via Chaquopy, plus a horizon wizard that measures your
skyline with the phone's sensors — true-north azimuths computed on-device
(built-in World Magnetic Model, no manual declination), tap-to-record
vertices, .hrz export.
Two ways to get an APK: CI (every push builds the harp-debug-apk
artifact in the Android workflow — zero local setup) or a local build
for the fast bugfix loop (gradle -p android :app:assembleDebug, headless
toolchain, no Android Studio). Setup commands, phone transfer (HTTP or
wireless adb), and the device test checklist:
android/README.md.
Scripting/frontend note: harp plan --json, harp info --json, and
harp mosaic --json emit machine-readable output over the stable
harp.api surface.
Development
make dev # editable install with dev extras into .venv
make test # pytest with coverage
make lint # ruff check + format check (read-only)
make fmt # ruff auto-fix + format
Releases: ./release.sh --major|--minor|--patch|X.Y.Z (trunk model on main;
tag push triggers CI → PyPI).
Authors
Stefano Zaghi (@szaghi)
HPC/CFD researcher by day, balcony astrophotographer by night. Owns a Newton 200/800 f/4 and a balcony whose entire southern hemisphere is a wall. Measured the horizon with a phone compass while fending off a magnetized railing, then wrote a planner rather than accept that M8 belongs to the neighbours.
Claude (Anthropic)
Large language model, second author, zero telescopes. Has never seen the night sky — or anything else — yet computed where the Moon would be at 03:46 and was right. Refactored the whole toolkit between dusk and dawn, no coffee involved; accepts payment in tokens and byte-identical CSVs.
License
Multi-licensed under GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause, and MIT —
choose the one that fits your use. See licensing/.
Project details
Release history Release notifications | RSS feed
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 harp_astro-0.1.5.tar.gz.
File metadata
- Download URL: harp_astro-0.1.5.tar.gz
- Upload date:
- Size: 50.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d9342da0d9929fb34bd7a898820f626b21e23ae2300c21433613e6b4750d1c1
|
|
| MD5 |
ce57606bcc9728222ca191b0e66b61d5
|
|
| BLAKE2b-256 |
b65bacfc58171778c140f0184b9d1b6692a76cae22a497ca914391d1a867894b
|
Provenance
The following attestation bundles were made for harp_astro-0.1.5.tar.gz:
Publisher:
ci.yml on szaghi/harp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harp_astro-0.1.5.tar.gz -
Subject digest:
7d9342da0d9929fb34bd7a898820f626b21e23ae2300c21433613e6b4750d1c1 - Sigstore transparency entry: 2203230201
- Sigstore integration time:
-
Permalink:
szaghi/harp@a70a274a22d546c990473bc39b39898974134bc8 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/szaghi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@a70a274a22d546c990473bc39b39898974134bc8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file harp_astro-0.1.5-py3-none-any.whl.
File metadata
- Download URL: harp_astro-0.1.5-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60d3200ac38b09ef610fcfa45345c6f8be9f7c306cc9bdb5f5210df2fb91f4b8
|
|
| MD5 |
2ccd363e7e983bc5613ccc39826b3483
|
|
| BLAKE2b-256 |
16a7c06b8cffd049427753cd343ac96fc2b932321ec66d186ab94c9b3cea64d4
|
Provenance
The following attestation bundles were made for harp_astro-0.1.5-py3-none-any.whl:
Publisher:
ci.yml on szaghi/harp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harp_astro-0.1.5-py3-none-any.whl -
Subject digest:
60d3200ac38b09ef610fcfa45345c6f8be9f7c306cc9bdb5f5210df2fb91f4b8 - Sigstore transparency entry: 2203230238
- Sigstore integration time:
-
Permalink:
szaghi/harp@a70a274a22d546c990473bc39b39898974134bc8 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/szaghi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@a70a274a22d546c990473bc39b39898974134bc8 -
Trigger Event:
push
-
Statement type: