Source code for jwst.imprint.imprint_step

from stdatamodels.jwst import datamodels

from jwst.background import subtract_images
from jwst.stpipe import Step

__all__ = ["ImprintStep"]


[docs] class ImprintStep(Step): """ Remove NIRSpec MSA imprint structure from an exposure. The imprint structure is removed by subtracting a separate imprint (a.k.a. leakcal) exposure. """ class_alias = "imprint" spec = """ """ # noqa: E501
[docs] def process(self, input_data, imprint): """ Subtract an imprint image from the input data. If a single imprint image is provided, it is directly subtracted without further checks. If multiple imprint images are provided, the background target flag (`meta.dither.observation.bkgdtarg`) is checked for a match to the input data. If there is a single imprint image matching the input data's background flag, then it is directly subtracted without further checks. If there are multiple imprint images that match the input data's background flag, then the imprint is checked for an observation ID (`meta.observation.observation_number`) and dither position index (`meta.dither.position_number`). If there is a match, then the matching imprint image is subtracted from the input data. If there is no match, then the step is skipped for the input data. Parameters ---------- input_data : DataModel or str Input exposure to be corrected. imprint : list of str or DataModel Imprint exposures associated with the input. Returns ------- DataModel The imprint subtracted exposure. """ # Open the input science image and get its dither pattern position number input_model = datamodels.open(input_data) pos_no = input_model.meta.dither.position_number obs_no = input_model.meta.observation.observation_number is_bkgd = input_model.meta.observation.bkgdtarg # Check all the imprints to see if there is a direct match for the input imprint_models = [] match_model = None for imprint_exp in imprint: imprint_model = datamodels.open(imprint_exp) imprint_pos_no = imprint_model.meta.dither.position_number imprint_obs_no = imprint_model.meta.observation.observation_number imprint_bkg = imprint_model.meta.observation.bkgdtarg if len(imprint) == 1: # Exactly one imprint provided: use it. match_model = datamodels.open(imprint[0]) imprint_models.append(match_model) elif is_bkgd != imprint_bkg: # More than one imprint and imprint does not match input's # background status. Don't consider it further. imprint_model.close() else: # Keep the open model for further checks imprint_models.append(imprint_model) # Check if there is a direct match to the current # observation and dither position. if pos_no == imprint_pos_no and obs_no == imprint_obs_no: match_model = imprint_model break # Check for a single imprint intended for use with all dither positions. if match_model is None and len(imprint_models) == 1: # No direct match found - use the only one available. match_model = imprint_models[0] # Copy the input image to the output result = input_model.copy() if match_model is not None: # Subtract the matching imprint image self.log.info( f"Subtracting imprint image {match_model.meta.filename} " f"from {input_model.meta.filename}" ) result = subtract_images.subtract(input_model, match_model) # Update the step status and close the imprint model result.meta.cal_step.imprint = "COMPLETE" else: self.log.warning(f"No matching imprint image found for {input_model.meta.filename}") self.log.warning("Step will be skipped") result.meta.cal_step.imprint = "SKIPPED" # Close any open imprint models for model in imprint_models: model.close() # Close the input model input_model.close() return result