Coverage for python/lsst/obs/lsst/translators/phosim.py : 59%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is currently part of obs_lsst but is written to allow it
2# to be migrated to the astro_metadata_translator package at a later date.
3#
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the LICENSE file in this directory for details of code ownership.
7#
8# Use of this source code is governed by a 3-clause BSD-style
9# license that can be found in the LICENSE file.
11"""Metadata translation code for LSSTCam PhoSim FITS headers"""
13__all__ = ("LsstCamPhoSimTranslator",)
15import logging
17import astropy.units as u
18import astropy.units.cds as cds
19from astropy.coordinates import Angle
21from astro_metadata_translator import cache_translation
22from astro_metadata_translator.translators.helpers import (
23 tracking_from_degree_headers,
24 altaz_from_degree_headers,
25)
27from .lsstsim import LsstSimTranslator
29log = logging.getLogger(__name__)
32class LsstCamPhoSimTranslator(LsstSimTranslator):
33 """Metadata translator for LSSTCam PhoSim data."""
35 name = "LSSTCam-PhoSim"
36 """Name of this translation class"""
38 _const_map = {
39 "instrument": "LSSTCam-PhoSim",
40 "boresight_rotation_coord": "sky",
41 "observation_type": "science",
42 "object": "UNKNOWN",
43 "relative_humidity": 40.0,
44 }
46 _trivial_map = {
47 "detector_group": "RAFTNAME",
48 "observation_id": "OBSID",
49 "science_program": "RUNNUM",
50 "exposure_id": "OBSID",
51 "visit_id": "OBSID",
52 "physical_filter": "FILTER",
53 "dark_time": ("DARKTIME", dict(unit=u.s)),
54 "exposure_time": ("EXPTIME", dict(unit=u.s)),
55 "temperature": ("TEMPERA", dict(unit=u.deg_C)),
56 "pressure": ("PRESS", dict(unit=cds.mmHg)),
57 "boresight_airmass": "AIRMASS",
58 "detector_name": "SENSNAME",
59 "detector_serial": "LSST_NUM",
60 }
62 cameraPolicyFile = "policy/phosim.yaml"
64 @classmethod
65 def can_translate(cls, header, filename=None):
66 """Indicate whether this translation class can translate the
67 supplied header.
69 There is no ``INSTRUME`` header in PhoSim data. Instead we use
70 the ``CREATOR`` header.
72 Parameters
73 ----------
74 header : `dict`-like
75 Header to convert to standardized form.
76 filename : `str`, optional
77 Name of file being translated.
79 Returns
80 -------
81 can : `bool`
82 `True` if the header is recognized by this class. `False`
83 otherwise.
84 """
85 # Generic PhoSim data does not have an INSTRUME header.
86 # If an INSTRUME header is present this translator class
87 # is not suitable.
88 if "INSTRUME" in header:
89 return False
90 else:
91 return cls.can_translate_with_options(
92 header, {"CREATOR": "PHOSIM", "TESTTYPE": "PHOSIM"}, filename=filename
93 )
95 @cache_translation
96 def to_tracking_radec(self):
97 # Docstring will be inherited. Property defined in properties.py
98 radecsys = ("RADESYS",)
99 radecpairs = (
100 ("RATEL", "DECTEL"),
101 ("RA_DEG", "DEC_DEG"),
102 ("BORE-RA", "BORE-DEC"),
103 )
104 return tracking_from_degree_headers(self, radecsys, radecpairs)
106 @cache_translation
107 def to_altaz_begin(self):
108 # Docstring will be inherited. Property defined in properties.py
109 # Fallback to the "derive from ra/dec" if keys are missing
110 if self.are_keys_ok(["ZENITH", "AZIMUTH"]):
111 return altaz_from_degree_headers(
112 self,
113 (("ZENITH", "AZIMUTH"),),
114 self.to_datetime_begin(),
115 is_zd=set(["ZENITH"]),
116 )
117 else:
118 return super().to_altaz_begin()
120 @cache_translation
121 def to_boresight_rotation_angle(self):
122 angle = Angle(90.0 * u.deg) - Angle(
123 self.quantity_from_card(["ROTANGZ", "ROTANGLE"], u.deg)
124 )
125 angle = angle.wrap_at("360d")
126 return angle