Source code for sofia_redux.scan.custom.sofia.info.telescope
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import numpy as np
from astropy import units
from astropy.time import Time
from sofia_redux.scan.utilities.bracketed_values import BracketedValues
from sofia_redux.scan.info.telescope import TelescopeInfo
from sofia_redux.scan.coordinate_systems.equatorial_coordinates import \
EquatorialCoordinates
from sofia_redux.scan.coordinate_systems.epoch.epoch import J2000, Epoch
from sofia_redux.scan.utilities.utils import (
to_header_float, insert_info_in_header)
__all__ = ['SofiaTelescopeInfo']
degree = units.Unit('degree')
um = units.Unit('um')
hourangle = units.Unit('hourangle')
[docs]
class SofiaTelescopeInfo(TelescopeInfo):
telescope_diameter = 2.5 * units.Unit('m')
def __init__(self):
"""
Initialize the SOFIA telescope information.
Contains information on the SOFIA specific telescope parameters such as
zenith angle, boresight coordinates, and tracking status.
"""
super().__init__()
self.telescope = "SOFIA 2.5m"
self.tel_config = None
self.vpa = np.nan * degree
self.last_rewind = None
self.focus_t = BracketedValues(np.nan * um,
np.nan * um)
self.rel_elevation = np.nan * degree
self.cross_elevation = np.nan * degree
self.line_of_sight_angle = np.nan * degree
self.tascu_status = None
self.fbc_status = None
self.zenith_angle = BracketedValues(np.nan * degree,
np.nan * degree)
self.tracking_mode = None
self.has_tracking_error = False
self.is_tracking = False
self.epoch = J2000
self.boresight_equatorial = EquatorialCoordinates(
np.full(2, np.nan), unit='degree', epoch=self.epoch)
self.requested_equatorial = self.boresight_equatorial.copy()
[docs]
def apply_configuration(self):
"""
Update telescope information with FITS header information.
Updates the information by taking the following keywords from the
FITS header::
TELESCOP - The observatory name (str)
TELVPA - The boresight position angle (degrees)
LASTREW - The UTC time of last telescope rewind (str)
FOCUS_ST - The focus T value at start (um)
FOCUS_EN - The focus T value at end (um)
TELEL - The telescope elevation in cavity (degrees)
TELXEL - The telescope cross elevation in cavity (degrees)
TELLOS - The telescope line-of-sight angle in cavity (degrees)
TSC-STAT - The TASCU system status at end (str)
FBC-STAT - The flexible body compensation system status at end (str)
ZA_START - The zenith angle at start (degrees)
ZA_END - The zenith angle at end (degrees)
TRACMODE - The SOFIA tracking mode (str)
TRACERR - Whether there was a tracking error in the scan (bool)
TELCONF - The telescope configuration (str)
EQUINOX - The coordinate epoch (year)
TELEQUI - The boresight epoch (year)
TELRA - The boresight RA (hourangle)
TELDEC - The boresight DEC (degrees)
OBSRA - The requested RA (hourangle)
OBSDEC - The requested DEC (degrees)
Returns
-------
None
"""
options = self.options
if options is None:
return
self.telescope = options.get_string("TELESCOP", default=self.telescope)
self.vpa = options.get_float("TELVPA") * degree
self.last_rewind = options.get_string("LASTREW")
self.focus_t.start = options.get_float("FOCUS_ST") * um
self.focus_t.end = options.get_float("FOCUS_EN") * um
self.rel_elevation = options.get_float("TELEL") * degree
self.cross_elevation = options.get_float("TELXEL") * degree
self.line_of_sight_angle = options.get_float("TELLOS") * degree
self.tascu_status = options.get_string("TSC-STAT")
self.fbc_status = options.get_string("FBC-STAT")
self.zenith_angle.start = options.get_float("ZA_START") * degree
self.zenith_angle.end = options.get_float("ZA_END") * degree
self.tracking_mode = options.get_string("TRACMODE")
self.has_tracking_error = options.get_bool("TRACERR")
self.is_tracking = str(self.tracking_mode).strip().upper() != 'OFF'
self.tel_config = options.get_string('TELCONF')
if "EQUINOX" in options:
self.epoch = Epoch(equinox=options.get_float("EQUINOX"))
self.requested_equatorial = EquatorialCoordinates(
np.full(2, np.nan), epoch=self.epoch, unit='degree')
boresight_epoch = options.get_string('TELEQUI', default=None)
if (boresight_epoch is None
or (isinstance(boresight_epoch, str)
and boresight_epoch.lower().startswith('unk'))):
boresight_epoch = self.epoch
else:
boresight_epoch = Epoch(equinox=boresight_epoch)
self.boresight_equatorial = EquatorialCoordinates(
np.full(2, np.nan), epoch=boresight_epoch, unit='degree')
if "TELRA" in options and "TELDEC" in options:
self.boresight_equatorial.ra = options.get_hms_time(
'TELRA', angle=True)
self.boresight_equatorial.dec = options.get_dms_angle('TELDEC')
if 'OBSRA' in options and 'OBSDEC' in options:
self.requested_equatorial.ra = options.get_hms_time(
'OBSRA', angle=True)
self.requested_equatorial.dec = options.get_dms_angle('OBSDEC')
[docs]
@staticmethod
def get_telescope_name():
"""
Return the telescope name.
Returns
-------
name : str
"""
return "SOFIA"
[docs]
def get_table_entry(self, name):
"""
Return a parameter value for the given name.
Parameters
----------
name : str
The name of the parameter to retrieve.
Returns
-------
value
"""
if name == 'focus':
return self.focus_t.midpoint.to('um')
elif name == 'bra':
return self.boresight_equatorial.ra.to('hourangle')
elif name == 'bdec':
return self.boresight_equatorial.dec.to('degree')
elif name == 'rra':
return self.requested_equatorial.ra.to('hourangle')
elif name == 'rdec':
return self.requested_equatorial.dec.to('degree')
elif name == 'epoch':
return str(self.epoch)
elif name == 'vpa':
return self.vpa.to('degree')
elif name == 'za':
return self.zenith_angle.midpoint.to('degree')
elif name == 'los':
return self.line_of_sight_angle.to('degree')
elif name == 'el':
return self.rel_elevation.to('degree')
elif name == 'xel':
return self.cross_elevation.to('degree')
elif name == 'trkerr':
return self.has_tracking_error
elif name == 'trkmode':
return self.tracking_mode
elif name == 'cfg':
return self.tel_config
elif name == 'fbc':
return self.fbc_status
elif name == 'rew':
return self.last_rewind
else:
return super().get_table_entry(name)