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`. 93 for c
in obsInfo.cards_used:
100 """Construct a `~lsst.afw.image.VisitInfo` from an 101 `~astro_metadata_translator.ObservationInfo` 105 obsInfo : `astro_metadata_translator.ObservationInfo` 106 Information gathered from the observation metadata. 107 log : `logging.Logger` or `lsst.log.Log`, optional 108 Logger to use for logging informational messages. 109 If `None` logging will be disabled. 113 visitInfo : `lsst.afw.image.VisitInfo` 114 `~lsst.afw.image.VisitInfo` derived from the supplied 115 `~astro_metadata_translator.ObservationInfo`. 120 if obsInfo.exposure_time
is not None:
121 argDict[
"exposureTime"] = obsInfo.exposure_time.to_value(
"s")
122 if obsInfo.dark_time
is not None:
123 argDict[
"darkTime"] = obsInfo.dark_time.to_value(
"s")
124 argDict[
"exposureId"] = obsInfo.detector_exposure_id
127 if obsInfo.datetime_begin
is not None and obsInfo.datetime_end
is not None:
128 tdelta = obsInfo.datetime_end - obsInfo.datetime_begin
129 middle = obsInfo.datetime_begin + 0.5*tdelta
136 argDict[
"date"] = DateTime(middle.tai.isot, DateTime.TAI)
145 except iers.IERSRangeError:
148 era = erfa.era00(ut1time.jd1, ut1time.jd2)
149 argDict[
"era"] = era * radians
151 argDict[
"date"] = DateTime()
154 if obsInfo.tracking_radec
is not None:
155 icrs = obsInfo.tracking_radec.transform_to(
"icrs")
156 argDict[
"boresightRaDec"] = SpherePoint(icrs.ra.degree,
157 icrs.dec.degree, units=degrees)
159 altaz = obsInfo.altaz_begin
160 if altaz
is not None:
161 argDict[
"boresightAzAlt"] = SpherePoint(altaz.az.degree,
162 altaz.alt.degree, units=degrees)
164 argDict[
"boresightAirmass"] = obsInfo.boresight_airmass
166 if obsInfo.boresight_rotation_angle
is not None:
167 argDict[
"boresightRotAngle"] = obsInfo.boresight_rotation_angle.degree*degrees
169 if obsInfo.boresight_rotation_coord
is not None:
170 rotType = RotType.UNKNOWN
171 if obsInfo.boresight_rotation_coord ==
"sky":
172 rotType = RotType.SKY
173 argDict[
"rotType"] = rotType
176 temperature = float(
"nan")
177 if obsInfo.temperature
is not None:
178 temperature = obsInfo.temperature.to_value(
"deg_C", astropy.units.temperature())
179 pressure = float(
"nan")
180 if obsInfo.pressure
is not None:
181 pressure = obsInfo.pressure.to_value(
"Pa")
182 relative_humidity = float(
"nan")
183 if obsInfo.relative_humidity
is not None:
184 relative_humidity = obsInfo.relative_humidity
185 argDict[
"weather"] = Weather(temperature, pressure, relative_humidity)
187 if obsInfo.location
is not None:
188 geolocation = obsInfo.location.to_geodetic()
189 argDict[
"observatory"] = Observatory(geolocation.lon.degree*degrees,
190 geolocation.lat.degree*degrees,
191 geolocation.height.to_value(
"m"))
193 for key
in list(argDict.keys()):
194 if argDict[key]
is None:
196 log.warn(
"argDict[{}] is None; stripping".format(key, argDict[key]))
199 return VisitInfo(**argDict)
def __init__(self, log=None)
def __call__(self, md, exposureId=None)
def observationInfo2visitInfo(obsInfo, log=None)