Source code for obstools.fix_ldt_header

# -*- coding: utf-8 -*-
#
#  This file is part of LDTObserverTools.
#
#   This Source Code Form is subject to the terms of the Mozilla Public
#   License, v. 2.0. If a copy of the MPL was not distributed with this
#   file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#  Created on 17-Oct-2022
#
#  @author: tbowers

"""FITS File Utility Module

LDTObserverTools contains python ports of various LDT Observer Tools

Lowell Discovery Telescope (Lowell Observatory: Flagstaff, AZ)
https://lowell.edu

This file contains FITS Header utility routines.
"""

# Built-In Libraries
import argparse
import pathlib
import typing

# 3rd-Party Libraries
import astropy.time
import ccdproc
import numpy as np

# Local Libraries
from obstools import utils

# CONSTANTS


[docs] def fix_ldt_header( files: str | pathlib.Path | list, keyword: str, new_value: typing.Any, rimas_exp: bool = False, ): """Change FITS header keywords Sometimes at the telescope, incorrect or incomplete information is placed into the FITS header. This routine is a simple wrapper around CCDPROC functions for easily making changes to these keywords. Parameters ---------- files : :obj:`str` or :obj:`~pathlib.Path` or :obj:`list` The file(s) for which to update FITS keywords keyword : :obj:`str` FITS keyword to update new_value : :obj:`~typing.Any` New value for the FITS keyword rimas_exp : :obj:`bool`, optional Fix RIMAS exposure time keywords for data prior to mid-March 2026 """ if isinstance(files, list): files = [pathlib.Path(f).resolve() for f in files] else: files = [pathlib.Path(files).resolve()] # Build the IFC icl = ccdproc.ImageFileCollection(filenames=files) if rimas_exp: fix_old_rimas(icl) return for hdr in icl.headers(overwrite=True): # Attempt to get numerical values as numbers, not strings try: hdr[keyword] = float(new_value) except ValueError: hdr[keyword] = new_value
[docs] def fix_old_rimas(icl: ccdproc.ImageFileCollection): """Fix older RIMAS exposure time keywords _extended_summary_ Parameters ---------- icl : :obj:`~ccdproc.ImageFileCollection` The Image File Collection object containing the files to be changed """ for hdr in icl.headers(overwrite=True): # Check that the file is old enough mjd = astropy.time.Time(hdr["DATE"]).mjd cutoff = 61114.0 # 2026-03-15T00:00:00 if mjd > cutoff: print("ERROR: Newer RIMAS file formatl cannot update exposure times!") # Compute the new values and update the keywords and comments tot_exptime = hdr["EXPTIME"] frtime = hdr["FRTIME"] hdr["EXPTIME"] = ( np.round(tot_exptime, 2), "[s] exposure time of all frames incl. pedestal", ) hdr["EXPTIMEE"] = ( np.round(tot_exptime - frtime, 2), "[s] effective exposure time of reduced frame", )
# Command Line Script Infrastructure (borrowed from PypeIt) ==================#
[docs] class FixLdtHeader(utils.ScriptBase): """Script class for ``fix_ldt_header`` tool Script structure borrowed from :class:`pypeit.scripts.scriptbase.ScriptBase`. """
[docs] @classmethod def get_parser( cls, description: str = None, width: int = None, formatter: argparse.HelpFormatter = argparse.ArgumentDefaultsHelpFormatter, ): """Construct the command-line argument parser. Parameters ---------- description : :obj:`str`, optional A short description of the purpose of the script. width : :obj:`int`, optional Restrict the width of the formatted help output to be no longer than this number of characters, if possible given the help formatter. If None, the width is the same as the terminal width. formatter : :obj:`~argparse.HelpFormatter` Class used to format the help output. Returns ------- :obj:`~argparse.ArgumentParser` Command-line interpreter. """ # Step 1: Check for the bypass flag only temp_parser = argparse.ArgumentParser(add_help=False) temp_parser.add_argument("--rimas_exp", action="store_true") args, _ = temp_parser.parse_known_args() parser = super().get_parser( description="Fix a keyword in LDT FITS headers", width=width ) parser.add_argument( "file", action="store", type=str, nargs="+", help="File(s) on which to operate", ) # Step 2: Define full parser based on flag presence if not args.rimas_exp: parser.add_argument( "keyword", action="store", type=str, help="FITS keyword to change" ) parser.add_argument( "new_value", action="store", type=str, help="New header keyword value to insert", ) parser.add_argument( "--rimas_exp", action="store_true", help="Fix older RIMAS exposure time keywords", ) return parser
[docs] @staticmethod def main(args): """Main Driver Simple function that calls the fixer. """ # Giddy up! fix_ldt_header( files=args.file, keyword=getattr(args, "keyword", None), new_value=getattr(args, "new_value", None), rimas_exp=getattr(args, "rimas_exp", False), )