24 import astropy.utils.exceptions
25 from astropy.utils
import iers
31 import astropy._erfa
as erfa
33 from astro_metadata_translator
import ObservationInfo
35 from lsst.log
import Log
36 from lsst.daf.base
import DateTime
37 from lsst.geom
import degrees, radians
38 from lsst.afw.image
import VisitInfo, RotType
39 from lsst.afw.coord
import Observatory, Weather
40 from lsst.geom
import SpherePoint
42 __all__ = [
"MakeRawVisitInfoViaObsInfo"]
46 """Base class functor to make a VisitInfo from the FITS header of a 47 raw image using `~astro_metadata_translator.ObservationInfo` translators. 49 Subclasses can be used if a specific 50 `~astro_metadata_translator.MetadataTranslator` translator should be used. 52 The design philosophy is to make a best effort and log warnings of 53 problems, rather than raising exceptions, in order to extract as much 54 VisitInfo information as possible from a messy FITS header without the 55 user needing to add a lot of error handling. 59 log : `lsst.log.Log` or None 60 Logger to use for messages. 61 (None to use ``Log.getLogger("MakeRawVisitInfoViaObsInfo")``). 64 metadataTranslator =
None 65 """Header translator to use to construct VisitInfo, defaulting to 66 automatic determination.""" 70 log = Log.getLogger(
"MakeRawVisitInfoViaObsInfo")
74 """Construct a VisitInfo and strip associated data from the metadata. 78 md : `lsst.daf.base.PropertyList` or `lsst.daf.base.PropertySet` 79 Metadata to pull from. 80 Items that are used are stripped from the metadata. 81 exposureId : `int`, optional 82 Ignored. Here for compatibility with `MakeRawVisitInfo`. 86 visitInfo : `lsst.afw.image.VisitInfo` 87 `~lsst.afw.image.VisitInfo` derived from the header using 88 a `~astro_metadata_translator.MetadataTranslator`. 94 for c
in obsInfo.cards_used:
101 """Construct a `~lsst.afw.image.VisitInfo` from an 102 `~astro_metadata_translator.ObservationInfo` 106 obsInfo : `astro_metadata_translator.ObservationInfo` 107 Information gathered from the observation metadata. 108 log : `logging.Logger` or `lsst.log.Log`, optional 109 Logger to use for logging informational messages. 110 If `None` logging will be disabled. 114 visitInfo : `lsst.afw.image.VisitInfo` 115 `~lsst.afw.image.VisitInfo` derived from the supplied 116 `~astro_metadata_translator.ObservationInfo`. 121 if obsInfo.exposure_time
is not None:
122 argDict[
"exposureTime"] = obsInfo.exposure_time.to_value(
"s")
123 if obsInfo.dark_time
is not None:
124 argDict[
"darkTime"] = obsInfo.dark_time.to_value(
"s")
125 argDict[
"exposureId"] = obsInfo.detector_exposure_id
128 if obsInfo.datetime_begin
is not None and obsInfo.datetime_end
is not None:
129 tdelta = obsInfo.datetime_end - obsInfo.datetime_begin
130 middle = obsInfo.datetime_begin + 0.5*tdelta
137 argDict[
"date"] = DateTime(middle.tai.isot, DateTime.TAI)
148 with warnings.catch_warnings():
149 warnings.simplefilter(
"ignore", category=astropy.utils.exceptions.AstropyWarning)
151 except iers.IERSRangeError:
154 era = erfa.era00(ut1time.jd1, ut1time.jd2)
155 argDict[
"era"] = era * radians
157 argDict[
"date"] = DateTime()
160 if obsInfo.tracking_radec
is not None:
161 icrs = obsInfo.tracking_radec.transform_to(
"icrs")
162 argDict[
"boresightRaDec"] = SpherePoint(icrs.ra.degree,
163 icrs.dec.degree, units=degrees)
165 altaz = obsInfo.altaz_begin
166 if altaz
is not None:
167 argDict[
"boresightAzAlt"] = SpherePoint(altaz.az.degree,
168 altaz.alt.degree, units=degrees)
170 argDict[
"boresightAirmass"] = obsInfo.boresight_airmass
172 if obsInfo.boresight_rotation_angle
is not None:
173 argDict[
"boresightRotAngle"] = obsInfo.boresight_rotation_angle.degree*degrees
175 if obsInfo.boresight_rotation_coord
is not None:
176 rotType = RotType.UNKNOWN
177 if obsInfo.boresight_rotation_coord ==
"sky":
178 rotType = RotType.SKY
179 argDict[
"rotType"] = rotType
182 temperature = float(
"nan")
183 if obsInfo.temperature
is not None:
184 temperature = obsInfo.temperature.to_value(
"deg_C", astropy.units.temperature())
185 pressure = float(
"nan")
186 if obsInfo.pressure
is not None:
187 pressure = obsInfo.pressure.to_value(
"Pa")
188 relative_humidity = float(
"nan")
189 if obsInfo.relative_humidity
is not None:
190 relative_humidity = obsInfo.relative_humidity
191 argDict[
"weather"] = Weather(temperature, pressure, relative_humidity)
193 if obsInfo.location
is not None:
194 geolocation = obsInfo.location.to_geodetic()
195 argDict[
"observatory"] = Observatory(geolocation.lon.degree*degrees,
196 geolocation.lat.degree*degrees,
197 geolocation.height.to_value(
"m"))
199 for key
in list(argDict.keys()):
200 if argDict[key]
is None:
202 log.warn(
"argDict[{}] is None; stripping".format(key, argDict[key]))
205 return VisitInfo(**argDict)
def __init__(self, log=None)
def __call__(self, md, exposureId=None)
def observationInfo2visitInfo(obsInfo, log=None)