Source code for sofia_redux.scan.custom.sofia.info.detector_array

# Licensed under a 3-clause BSD style license - see LICENSE.rst

from astropy import units, log
import numpy as np

from sofia_redux.scan.info.base import InfoBase
from sofia_redux.scan.utilities.utils import to_header_float
from sofia_redux.scan.coordinate_systems.coordinate_2d import Coordinate2D
from sofia_redux.scan.coordinate_systems.grid.grid_2d import Grid2D
from sofia_redux.scan.utilities.utils import insert_info_in_header

__all__ = ['SofiaDetectorArrayInfo']


[docs] class SofiaDetectorArrayInfo(InfoBase): subarrays = 0 def __init__(self): """ Initialize the SOFIA detector array information. Contains information on the generic detector array for SOFIA instruments. All SOFIA detectors are given a boresight index, a grid (type assigned from FITS header information), and pixel size information. """ super().__init__() self.detector_name = None self.detector_size_string = None self.pixel_size = np.nan * units.Unit('arcsec') self.subarray_size = None self.boresight_index = Coordinate2D() self.grid = None @property def log_id(self): """ Return the string log ID for the info. The log ID is used to extract certain information from table data. Returns ------- str """ return 'sofscan/array'
[docs] def apply_configuration(self): """ Update detector array information with FITS header information. Updates the detector information by taking the following keywords from the FITS header:: DETECTOR - The name of the detector (str) DETSIZE - The size of the detector (str) PIXSCAL - The pixel size on the sky (arcsec) SUBARRNO - The number of subarrays (int) SIBS_X - The position of the boresight in the x-direction (pixels) SIBS_Y - The position of the boresight in the y-direction (pixels) CTYPE1/CTYPE2 - If both are present, determines the grid (str) Returns ------- None """ options = self.options if options is None: return self.detector_name = options.get_string("DETECTOR") self.detector_size_string = options.get_string("DETSIZE") self.pixel_size = options.get_float("PIXSCAL") * units.Unit('arcsec') subarrays = options.get_int("SUBARRNO", default=0) self.subarray_size = [] if subarrays > 0: for i in range(subarrays): key = f'SUBARR{str(i + 1).zfill(2)}' value = options.get_string(key) self.subarray_size.append(value) else: self.subarray_size = [] self.boresight_index.x = options.get_float("SIBS_X") self.boresight_index.y = options.get_float("SIBS_Y") header = self.configuration.fits.header if 'CTYPE1' in header and 'CTYPE2' in header: try: self.grid = Grid2D.from_header(header, alt='') except Exception as err: log.warning(f"Could not read detector array " f"grid system: {err}") self.grid = None else: self.grid = None
[docs] def edit_header(self, header): """ Edit an image header with available information. Parameters ---------- header : astropy.fits.Header The FITS header to apply. Returns ------- None """ info = [('COMMENT', "<------ SOFIA Array Data ------>"), ('DETECTOR', self.detector_name, 'Detector name.'), ('DETSIZE', self.detector_size_string, 'Detector size.'), ('PIXSCAL', (to_header_float(self.pixel_size, 'arcsec')), '(arcsec) pixel size on sky.')] if 0 < self.subarrays == len(self.subarray_size): info.append(('SUBARRNO', self.subarrays, 'Number of subarrays.')) for subarray in range(self.subarrays): value = self.subarray_size[subarray] if value is not None: key = f'SUBARR{str(subarray).zfill(2)}' comment = f'Subarray {subarray} location and size.' info.append((key, value, comment)) if self.boresight_index is None: sx, sy = np.nan, np.nan else: sx, sy = self.boresight_index.coordinates info.append(('SIBS_X', to_header_float(sx), '(pixel) boresight pixel x.')) info.append(('SIBS_Y', to_header_float(sy), '(pixel) boresight pixel y.')) insert_info_in_header(header, info, delete_special=True) if self.grid is not None: self.grid.edit_header(header)
[docs] def get_table_entry(self, name): """ Given a name, return the parameter stored in the information object. Note that names do not exactly match to attribute names. Parameters ---------- name : str Returns ------- value """ if name == 'sibsx': return self.boresight_index.x elif name == 'sibsy': return self.boresight_index.y else: return super().get_table_entry(name)