24 from astropy.utils
import iers
30 import astropy._erfa
as erfa
32 from astro_metadata_translator
import ObservationInfo
34 from lsst.log
import Log
35 from lsst.daf.base
import DateTime
36 from lsst.geom
import degrees, radians
37 from lsst.afw.image
import VisitInfo, RotType
38 from lsst.afw.coord
import Observatory, Weather
39 from lsst.geom
import SpherePoint
41 __all__ = [
"MakeRawVisitInfoViaObsInfo"]
45 """Base class functor to make a VisitInfo from the FITS header of a 46 raw image using `~astro_metadata_translator.ObservationInfo` translators. 48 Subclasses can be used if a specific 49 `~astro_metadata_translator.MetadataTranslator` translator should be used. 51 The design philosophy is to make a best effort and log warnings of 52 problems, rather than raising exceptions, in order to extract as much 53 VisitInfo information as possible from a messy FITS header without the 54 user needing to add a lot of error handling. 58 log : `lsst.log.Log` or None 59 Logger to use for messages. 60 (None to use ``Log.getLogger("MakeRawVisitInfoViaObsInfo")``). 63 metadataTranslator =
None 64 """Header translator to use to construct VisitInfo, defaulting to 65 automatic determination.""" 69 log = Log.getLogger(
"MakeRawVisitInfoViaObsInfo")
73 """Construct a VisitInfo and strip associated data from the metadata. 77 md : `lsst.daf.base.PropertyList` or `lsst.daf.base.PropertySet` 78 Metadata to pull from. 79 Items that are used are stripped from the metadata. 80 exposureId : `int`, optional 81 Ignored. Here for compatibility with `MakeRawVisitInfo`. 85 visitInfo : `lsst.afw.image.VisitInfo` 86 `~lsst.afw.image.VisitInfo` derived from the header using 87 a `~astro_metadata_translator.MetadataTranslator`. 94 for c
in obsInfo.cards_used:
98 if obsInfo.exposure_time
is not None:
99 argDict[
"exposureTime"] = obsInfo.exposure_time.to_value(
"s")
100 if obsInfo.dark_time
is not None:
101 argDict[
"darkTime"] = obsInfo.dark_time.to_value(
"s")
102 argDict[
"exposureId"] = obsInfo.detector_exposure_id
105 if obsInfo.datetime_begin
is not None and obsInfo.datetime_end
is not None:
106 tdelta = obsInfo.datetime_end - obsInfo.datetime_begin
107 middle = obsInfo.datetime_begin + 0.5*tdelta
114 argDict[
"date"] = DateTime(middle.tai.isot, DateTime.TAI)
123 except iers.IERSRangeError:
126 era = erfa.era00(ut1time.jd1, ut1time.jd2)
127 argDict[
"era"] = era * radians
129 argDict[
"date"] = DateTime()
132 if obsInfo.tracking_radec
is not None:
133 icrs = obsInfo.tracking_radec.transform_to(
"icrs")
134 argDict[
"boresightRaDec"] = SpherePoint(icrs.ra.degree,
135 icrs.dec.degree, units=degrees)
137 altaz = obsInfo.altaz_begin
138 if altaz
is not None:
139 argDict[
"boresightAzAlt"] = SpherePoint(altaz.az.degree,
140 altaz.alt.degree, units=degrees)
142 argDict[
"boresightAirmass"] = obsInfo.boresight_airmass
144 if obsInfo.boresight_rotation_angle
is not None:
145 argDict[
"boresightRotAngle"] = obsInfo.boresight_rotation_angle.degree*degrees
147 if obsInfo.boresight_rotation_coord
is not None:
148 rotType = RotType.UNKNOWN
149 if obsInfo.boresight_rotation_coord ==
"sky":
150 rotType = RotType.SKY
151 argDict[
"rotType"] = rotType
154 temperature = float(
"nan")
155 if obsInfo.temperature
is not None:
156 temperature = obsInfo.temperature.to_value(
"deg_C", astropy.units.temperature())
157 pressure = float(
"nan")
158 if obsInfo.pressure
is not None:
159 pressure = obsInfo.pressure.to_value(
"Pa")
160 relative_humidity = float(
"nan")
161 if obsInfo.relative_humidity
is not None:
162 relative_humidity = obsInfo.relative_humidity
163 argDict[
"weather"] = Weather(temperature, pressure, relative_humidity)
165 if obsInfo.location
is not None:
166 geolocation = obsInfo.location.to_geodetic()
167 argDict[
"observatory"] = Observatory(geolocation.lon.degree*degrees,
168 geolocation.lat.degree*degrees,
169 geolocation.height.to_value(
"m"))
171 for key
in list(argDict.keys()):
172 if argDict[key]
is None:
173 self.
log.warn(
"argDict[{}] is None; stripping".format(key, argDict[key]))
176 return VisitInfo(**argDict)
def __init__(self, log=None)
def __call__(self, md, exposureId=None)