Web-based interactive FITS triplet classifier for astronomical image labelling
Project description
Astro Swiper
Web-based interactive classifier for astronomical FITS image triplets. View science/difference/reference image triplets in a browser and classify them via keyboard shortcuts.
Installation
pip install astro-swiper
Running
1. From the command line
aswiper /path/to/fits/triplets/ # positional input dir, uses config.yaml in cwd
aswiper /path/to/fits/triplets/ -config my_cfg.yaml # explicit config path
aswiper --print-config # print path to the bundled default config template
Then open http://localhost:5000 in a browser.
Over SSH (no X11 needed):
ssh -L 5000:localhost:5000 user@host
# then open http://localhost:5000 locally
2. As a Python import
from astro_swiper import AstroSwiper
AstroSwiper('config.yaml').run()
3. With an inline config dict (no file needed)
from astro_swiper import AstroSwiper
AstroSwiper({
'input_dir': '/data/cutouts/',
'back_button': 'up',
'port': 5000,
'resume': True,
'overwrite': False,
'storage': {'backend': 'sqlite', 'db': 'classifications.db'},
'keybinds': {
'a': 'noise',
'e': 'streaks',
'd': 'dots',
'1': 'small',
'2': 'medium',
},
}).run()
4. With a custom triplet loader
If your files don't follow the default *scicutout / *subcutout / *refcutout naming convention, provide a triplet_loader function. It receives input_dir from the config (or None if omitted) and must return a list of [sub_path, sci_path, ref_path] triplets.
from astro_swiper import AstroSwiper
def my_loader(input_dir):
from pathlib import Path
triplets = []
for sci in sorted(Path(input_dir).glob('*_science.fits')):
base = str(sci).removesuffix('_science.fits')
sub, ref = base + '_difference.fits', base + '_template.fits'
if Path(sub).exists() and Path(ref).exists():
triplets.append([sub, str(sci), ref])
return triplets
AstroSwiper('config.yaml', triplet_loader=my_loader).run()
input_dir is optional in config when a loader is supplied.
Configuration
Get a copy of the default config to use as a starting point:
aswiper --print-config
cp $(aswiper --print-config) config.yaml
config.yaml reference
| Key | Default | Description |
|---|---|---|
input_dir |
(required) | Directory containing .fits or .fits.gz cutout triplets. Can be overridden by the CLI positional argument. |
back_button |
left |
Key that undoes the last classification |
port |
5000 |
Port the web server listens on |
resume |
true |
Skip already-classified triplets on startup |
overwrite |
false |
Wipe all saved classifications and start fresh |
storage.backend |
sqlite |
Storage format: sqlite, csv, or txt |
keybinds |
(required) | Map of key → label (or file path for txt backend) |
Storage backends
SQLite (recommended)
storage:
backend: sqlite
db: training_sets/classifications.db
Single file, atomic writes, safe against crashes. Query with pandas:
import sqlite3, pandas as pd
df = pd.read_sql(
"SELECT * FROM classifications",
sqlite3.connect("training_sets/classifications.db")
)
counts = df['label'].value_counts()
CSV
storage:
backend: csv
file: training_sets/classifications.csv
One row per triplet with columns sub_path, sci_path, ref_path, label.
import pandas as pd
df = pd.read_csv("training_sets/classifications.csv")
Txt (legacy)
storage:
backend: txt
already_classified: training_sets/already_classified.txt
One .txt file per category; keybind values must be file paths (not labels):
keybinds:
a: training_sets/noise.txt
c: training_sets/skips.txt
Each file contains triplet paths, three lines per entry (sub, sci, ref).
Input data format
Each triplet is three co-registered FITS cutout files sharing a common basename in a flat directory:
<basename>scicutout.fits[.gz]
<basename>subcutout.fits[.gz]
<basename>refcutout.fits[.gz]
Both .fits and .fits.gz are supported.
Controls
| Key | Action |
|---|---|
| (configured keybinds) | Classify current triplet |
back_button (default left) |
Undo last classification |
Shift+↑ |
Increase contrast (narrow display range) |
Shift+↓ |
Decrease contrast (widen display range) |
Shift+→ |
Increase brightness (shift range up) |
Shift+← |
Decrease brightness (shift range down) |
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 astro_swiper-0.1.10.tar.gz.
File metadata
- Download URL: astro_swiper-0.1.10.tar.gz
- Upload date:
- Size: 3.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d52e6c6177e11705b09f61a49e3ad4ad5cd459f54167f9011c2576bd9b94bd88
|
|
| MD5 |
bc699f539d68f0d15e3f7c8e776776e2
|
|
| BLAKE2b-256 |
af907e21c4417777d898af368073b228eaf7d912b29506320be0957f666f0329
|
Provenance
The following attestation bundles were made for astro_swiper-0.1.10.tar.gz:
Publisher:
publish.yml on BorderBenja05/astro_swiper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
astro_swiper-0.1.10.tar.gz -
Subject digest:
d52e6c6177e11705b09f61a49e3ad4ad5cd459f54167f9011c2576bd9b94bd88 - Sigstore transparency entry: 1181784838
- Sigstore integration time:
-
Permalink:
BorderBenja05/astro_swiper@5f81d23a12d14e5ad7cb22d65a33856de5e163db -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/BorderBenja05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5f81d23a12d14e5ad7cb22d65a33856de5e163db -
Trigger Event:
release
-
Statement type:
File details
Details for the file astro_swiper-0.1.10-py3-none-any.whl.
File metadata
- Download URL: astro_swiper-0.1.10-py3-none-any.whl
- Upload date:
- Size: 3.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75ed55b88ffba420041fd99c9a94f778e923c6b229a89694a8defde8ca31befa
|
|
| MD5 |
c0a9b4b98ef3e082ee66ebcfa9d6b147
|
|
| BLAKE2b-256 |
4afa1d57ebe660f93c51a17c66bc48f25559b3782fb702c02770858c71c15840
|
Provenance
The following attestation bundles were made for astro_swiper-0.1.10-py3-none-any.whl:
Publisher:
publish.yml on BorderBenja05/astro_swiper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
astro_swiper-0.1.10-py3-none-any.whl -
Subject digest:
75ed55b88ffba420041fd99c9a94f778e923c6b229a89694a8defde8ca31befa - Sigstore transparency entry: 1181784844
- Sigstore integration time:
-
Permalink:
BorderBenja05/astro_swiper@5f81d23a12d14e5ad7cb22d65a33856de5e163db -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/BorderBenja05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5f81d23a12d14e5ad7cb22d65a33856de5e163db -
Trigger Event:
release
-
Statement type: