Source code for pypeit.core.framematch

"""
Routines for matching frames to certain types or each other.

.. include:: ../include/links.rst
"""
# TODO -- Move this out of core?

from collections import OrderedDict

import numpy as np

from pypeit import log
from pypeit import PypeItError
from pypeit.bitmask import BitMask

[docs] class FrameTypeBitMask(BitMask): """ Define a bitmask to set the frame types. Frame types can be arc, bias, dark, pinhole, pixelflat, science, standard, or trace. """ def __init__(self): # TODO JFH: We need a background image type frame_types = OrderedDict([ ('align', 'Trace constant spatial positions along the slit'), ('arc', 'Arc lamp observation used for wavelength calibration'), ('bias', 'Bias readout for detector bias subtraction'), ('dark', 'Shuttered exposure to measure dark current'), ('pinhole', 'Pinhole observation used for tracing slit centers'), ('pixelflat', 'Flat-field exposure used for pixel-to-pixel response'), ('illumflat', 'Flat-field exposure used for illumination flat'), ('lampoffflats', 'Flat-field exposure with lamps off used to remove ' 'persistence from lamp on flat exposures and/or thermal emission ' 'from the telescope and dome'), ('slitless_pixflat', 'Flat-field exposure without slitmask used for pixel-to-pixel response'), ('scattlight', 'Frame (ideally with lots of counts) used to determine the scattered light model'), ('science', 'On-sky observation of a primary target'), ('standard', 'On-sky observation of a flux calibrator'), ('trace', 'High-count exposure used to trace slit positions'), ('tilt', 'Exposure used to trace the tilt in the wavelength solution'), ('sky', 'On-sky observation of the sky used for background subtraction'), ]) super(FrameTypeBitMask, self).__init__(list(frame_types.keys()), descr=list(frame_types.values()))
[docs] def type_names(self, type_bits, join=True): """ Use the type bits to get the type names for each frame. .. todo:: - This should probably be a general function in :class:`pypeit.bitmask.BitMask` Args: type_bits (int, list, `numpy.ndarray`_): The bit mask for each frame. bitmask (:class:`pypeit.bitmask.BitMask`, optional): The bit mask used to pull out the bit names. Uses :class:`FrameTypeBitMask` by default. join (:obj:`bool`, optional): Instead of providing a list of type names for items with multiple bits tripped, joint the list into a single, comma-separated string. Returns: list: List of the frame types for each frame. Each frame can have multiple types, meaning the 2nd axis is not necessarily the same length for all frames. """ _type_bits = np.atleast_1d(type_bits) out = [] for b in _type_bits: n = self.flagged_bits(b) if len(n) == 0: n = ['None'] out += [','.join(n)] if join else [n] return out[0] if isinstance(type_bits, np.integer) else out
[docs] def valid_frametype(frametype, quiet=False, raise_error=False): """ Confirm the provided frame type is known to ``PypeIt``. Args: frametype (:obj:`str`): The frame type name. quiet (:obj:`bool`, optional): Suppress output raise_error (:obj:`bool`, optional): Instead of issuing a warning, raise an exception. Returns: :obj:`bool`: Flag that the frametype name is valid. """ good_frametype = frametype in FrameTypeBitMask().keys() if not good_frametype: message = f'{frametype} is not a valid PypeIt frame type.' if not quiet and not raise_error: log.warning(message) elif raise_error: raise PypeItError(message) return good_frametype
[docs] def check_frame_exptime(exptime, exprng): """ Check that the exposure time is within the provided range. Args: exptime (`numpy.ndarray`_): Exposure times to check; allowed to be None. exprng (array-like): An array with the minimum and maximum exposure. The limits are *exclusive* and a limit of None means there is no limit. Returns: `numpy.ndarray`_: A boolean array that is True for all times within the provided range. The value is False for any exposure time that is None or outside the provided range. Raises: ValueError: Raised if the length of `exprng` is not 2. """ # Instantiate with all true indx = exptime != None if exprng is None: # No range specified return indx if len(exprng) != 2: # Range not correctly input raise ValueError('exprng must have two elements.') if exprng[0] is not None: indx[indx] &= (exptime[indx] > exprng[0]) if exprng[1] is not None: indx[indx] &= (exptime[indx] <= exprng[1]) return indx