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