Source code for kspecdr.extract.make_red

"""
Reduction Routines for KSPEC.

This module implements the reduction of extracted spectra (making RED files from EX files),
converting the 2dfdr `MAKE_RED` subroutine.
"""

import logging
from typing import Dict, Any
import shutil
from pathlib import Path

from ..io.image import ImageFile

logger = logging.getLogger(__name__)


[docs] def make_red(args: Dict[str, Any]) -> None: """ Main driver for reduction process (EX -> RED). Replaces 2dfdr SUBROUTINE MAKE_RED. Processes from the supplied arguments determine what extraction files are to be made from which image files and call MAKE_EX_FROM_IM for each. (Docstring from Fortran seems copy-pasted/wrong there). Actual Description: Creates output red(uced) file by copying ex(tracted) file. Divides by fibre-flat-field if requested. Scrunches using input arc calibration file. Parameters ---------- args : dict Dictionary containing arguments: - EXTRAC_FILENAME: Input extracted filename - OUTPUT_FILENAME: Output reduced filename - FLAT_FILENAME: (Optional) Fiber flat field file - WAVEL_FILENAME: (Optional) Wavelength calibration file (Arc) """ ex_fname = args.get('EXTRAC_FILENAME') red_fname = args.get('OUTPUT_FILENAME') if not ex_fname or not red_fname: raise ValueError("Missing required filenames (EXTRAC or OUTPUT)") logger.info(f"Reducing {ex_fname} -> {red_fname}") # 1. Create output RED file by copying EX file # CALL TDFIO_CREATEBYCOPY(RED_ID,EX_FILENAME,RED_FILENAME,STATUS) shutil.copy2(ex_fname, red_fname) # Open the new file for updates with ImageFile(red_fname, mode='UPDATE') as red_file: # 2. Divide by fibre-flat-field if requested # CALL CMFSPEC_FLATFIELD(RED_ID,ARGS,STATUS) # We need to implement this or placeholder. # Check if flat field file is provided or arguments imply it. # 2dfdr usually uses 'FLAT_FILENAME' or similar. # Assuming args has it. # Since I haven't implemented `CMFSPEC_FLATFIELD`, I'll leave a placeholder/TODO. flat_fname = args.get('FLAT_FILENAME') if flat_fname: logger.info(f"Applying flat field {flat_fname}") # TODO: Implement flat fielding logic # read flat -> divide data and variance -> update history pass # 3. Scrunch using input arc calibration file # CALL SCRUNCH_FROM_ARC_CAL(RED_ID,ARGS,STATUS) # This sets 'SCRUNCH' header keyword to TRUE # Need WAVEL_FILENAME wavel_fname = args.get('WAVEL_FILENAME') if wavel_fname: logger.info(f"Scrunching using arc file {wavel_fname}") # TODO: Implement scrunch logic # For now, just set the header keyword red_file.add_history(f"Scrunched using {wavel_fname}") # Set SCRUNCH keyword if appropriate (logic depends on if scrunch actually happened) # For now, if we had wavel_file, we assume we would have scrunched. # Update Class? # 2dfdr MAKE_RED doesn't explicitly change class here, but MAKE_EX set it to MFS... # Usually reduced files might be 'MFS...' or similar. # If input was MFS... output is likely same. logger.info(f"Created reduced file: {red_fname}")