Source code for mirar.pipelines.lmi.load_lmi_image

"""
Module for loading raw LMI images and ensuring they have the correct format
"""

# pylint: disable=duplicate-code

import logging
from pathlib import Path

import astropy
import numpy as np
from astropy.coordinates import Angle
from astropy.time import Time

from mirar.data import Image
from mirar.io import open_fits, open_raw_image
from mirar.paths import (
    BASE_NAME_KEY,
    COADD_KEY,
    GAIN_KEY,
    OBSCLASS_KEY,
    PROC_FAIL_KEY,
    PROC_HISTORY_KEY,
    SATURATE_KEY,
    TARGET_KEY,
    TIME_KEY,
)
from mirar.pipelines.lmi.config.constants import (
    LMI_FILTERS,
    LMI_GAIN,
    LMI_NONLINEAR_LEVEL,
)

logger = logging.getLogger(__name__)


[docs] def load_raw_lmi_fits(path: str | Path) -> tuple[np.array, astropy.io.fits.Header]: """ Function to load a raw LMI image :param path: path of file :return: data and header of image """ data, header = open_fits(path) if GAIN_KEY not in header.keys(): header[GAIN_KEY] = LMI_GAIN header[BASE_NAME_KEY] = ".".join(header[BASE_NAME_KEY].split(".")[-2:]) header["FILTER"] = header["FILTER1"].lower().strip().split("-")[-1] assert header["FILTER"] in LMI_FILTERS, f"Filter {header['FILTER']} not recognised" # Set up for forced photometry ra = Angle(f"{header['OBSRA']} hours").degree header["OBJRA"] = ra if ":" not in str(header["CRVAL1"]): header["CRVAL1"] = Angle(header["CRVAL1"], unit="deg").hourangle dec = Angle(f"{header['OBSDEC']} degrees").degree header["OBJDEC"] = dec # FIXME # header["OBJRA"], header["OBJDEC"] = 126.058614, 0.693279 # header["CRVAL1"], header["CRVAL2"] = "00:00:00.00", "00:00:00.00" del header["RA"] del header["DEC"] header["DETCOADD"] = 1 if SATURATE_KEY not in header: header[SATURATE_KEY] = LMI_NONLINEAR_LEVEL * header["DETCOADD"] if header["OBSTYPE"].lower() in ["pointing", "focus", "dark", "bias", "flat"]: header[OBSCLASS_KEY] = header["OBSTYPE"].lower() header["OBJECT"] = header["OBSTYPE"].lower() elif header["OBSTYPE"] == "DOME FLAT": header[OBSCLASS_KEY] = "flat" header["OBJECT"] = "flat" else: header[OBSCLASS_KEY] = "science" for key in ["focus", "flat", "bias"]: if key in Path(path).name.lower(): header[OBSCLASS_KEY] = key header[TARGET_KEY] = header["OBJECT"] if header[TARGET_KEY] in ["", "UNKNOWN"]: try: header[TARGET_KEY] = header["SCITARG"] header["OBJECT"] = header["SCITARG"] except KeyError: pass t = Time(header["DATE-OBS"]) header[TIME_KEY] = t.isot header["MJD-OBS"] = t.mjd if COADD_KEY not in header.keys(): logger.debug(f"No {COADD_KEY} entry. Setting coadds to 1.") header[COADD_KEY] = 1 header[PROC_HISTORY_KEY] = "" header[PROC_FAIL_KEY] = "" data = data.astype(np.float64) del header["BZERO"], header["BSCALE"] trimsec_x, trimsec_y = header["TRIMSEC"].strip("[]").split(",") data = data[ int(trimsec_x.split(":")[0]) : int(trimsec_x.split(":")[1]), int(trimsec_y.split(":")[0]) : int(trimsec_y.split(":")[1]), ] del header["TRIMSEC"] # Delete all WCS crap for key in header.keys(): if ("WCS" in header.comments[key]) & ("CRVAL" not in key): del header[key] elif (key[:2] in ["CR", "CT", "CD"]) & ("CRVAL" not in key): del header[key] data[data == 0.0] = np.nan return data, header
[docs] def load_raw_lmi_image(path: str | Path) -> Image: """ Function to load a raw LMI image :param path: Path to the raw image :return: Image object """ return open_raw_image(path, load_raw_lmi_fits)