Created
March 25, 2026 23:32
-
-
Save cgobat/24f205a65b42217ddceddf6c52852dc7 to your computer and use it in GitHub Desktop.
Populate Celestron Origin FITS header metadata using info.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # | |
| # This script populates metadata in the headers of FITS files produced by a Celestron Origin | |
| # telescope, using information from an accompanying JSON file | |
| # | |
| # Author: @cgobat | |
| import json | |
| import argparse | |
| import numpy as np | |
| import datetime as dt | |
| from pathlib import Path | |
| from astropy.io import fits | |
| def update_header(fits_file: Path, info_json: Path) -> None: | |
| info = json.loads(info_json.read_bytes()) | |
| info = info.get("StackedInfo", {}) | |
| capture_time = dt.datetime.fromisoformat(info["dateTime"]) | |
| capture_time = capture_time.astimezone(dt.UTC) | |
| ra_rad, dec_rad = info["celestial"]["first"], info["celestial"]["second"] | |
| ra_deg, dec_deg = np.rad2deg(ra_rad), np.rad2deg(dec_rad) | |
| with fits.open(fits_file, mode="update") as f: | |
| h = f[0].header | |
| h["TELESCOP"] = ("Celestron Origin", "Telescope name") | |
| h["INSTRUME"] = ("Celestron Origin", "Instrument name") | |
| h["APERTURE"] = (152., "[mm] Aperture diameter") | |
| h["FOCALLEN"] = (335., "[mm] Focal length") | |
| h["BAYERPAT"] = (info["bayer"].upper(), "Bayer (CFA) pattern") | |
| h["FILTER"] = (info["filter"], "Filter name") | |
| h["CCD-TEMP"] = (info["captureParams"]["temperature"], "[degC] Sensor temperature") | |
| h["EXPOSURE"] = (info["captureParams"]["exposure"], "[s] Per-frame exposure time") | |
| h["BINNING"] = (info["captureParams"]["binning"], "Camera binning (1 for 1x1, 2 for 2x2)") | |
| h["ISO"] = (info["captureParams"]["iso"], "ISO (gain) setting") | |
| h["DATE-OBS"] = (capture_time.strftime("%Y-%m-%dT%H:%M:%S"), "UTC time of observation") | |
| h["OBJECT"] = (info["objectName"], "Target name") | |
| h["RA"] = (ra_deg, "[deg] Nominal right ascension") | |
| h["DEC"] = (dec_deg, "[deg] Nominal declination") | |
| h["LATITUDE"] = (info["gps"]["latitude"], "[deg] Site latitude") | |
| h["LONGITUD"] = (info["gps"]["longitude"], "[deg] Site longitude") | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("fits_files", nargs="+", type=Path, help="FITS file(s) to process/update") | |
| parser.add_argument("-i", "--info", required=True, type=Path, help="JSON file containing capture metadata") | |
| args = parser.parse_args() | |
| for file in args.fits_files: | |
| update_header(file, args.info) | |
| print(f"Updated {file}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment