Coverage for python/astro_metadata_translator/properties.py: 49%
Shortcuts 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
Shortcuts 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 part of astro_metadata_translator.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the LICENSE file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12"""Properties calculated by this package.
14Defines all properties in one place so that both `ObservationInfo` and
15`MetadataTranslator` can use them. In particular, the translator
16base class can use knowledge of these properties to predefine translation
17stubs with documentation attached, and `ObservationInfo` can automatically
18define the getter methods.
20"""
22__all__ = ("PROPERTIES",)
24import astropy.coordinates
25import astropy.time
26import astropy.units
29# Helper functions to convert complex types to simple form suitable
30# for JSON serialization
31# All take the complex type and return simple python form using str, float,
32# int, dict, or list.
33# All assume the supplied parameter is not None.
35def earthlocation_to_simple(location):
36 """Convert EarthLocation to tuple.
38 Parameters
39 ----------
40 location : `astropy.coordinates.EarthLocation`
41 The location to simplify.
43 Returns
44 -------
45 geocentric : `tuple` of (`float`, `float`, `float`)
46 The geocentric location as three floats in meters.
47 """
48 geocentric = location.to_geocentric()
49 return tuple(c.to_value(astropy.units.m) for c in geocentric)
52def simple_to_earthlocation(simple, **kwargs):
53 """Convert simple form back to EarthLocation.
54 """
55 return astropy.coordinates.EarthLocation.from_geocentric(*simple, unit=astropy.units.m)
58def datetime_to_simple(datetime):
59 """Convert Time to tuple.
61 Parameters
62 ----------
63 datetime : `astropy.time.Time`
64 The time to simplify.
66 Returns
67 -------
68 mjds : `tuple` of (`float`, `float`)
69 The two MJDs in TAI.
70 """
71 tai = datetime.tai
72 return (tai.jd1, tai.jd2)
75def simple_to_datetime(simple, **kwargs):
76 """Convert simple form back to astropy.time.Time"""
77 return astropy.time.Time(*simple, format="jd", scale="tai")
80def exptime_to_simple(exptime):
81 """Convert exposure time Quantity to seconds."""
82 return exptime.to_value(astropy.units.s)
85def simple_to_exptime(simple, **kwargs):
86 """Convert simple form back to Quantity."""
87 return simple * astropy.units.s
90def angle_to_simple(angle):
91 """Convert Angle to degrees."""
92 return angle.to_value(astropy.units.deg)
95def simple_to_angle(simple, **kwargs):
96 """Convert degrees to Angle."""
97 return astropy.coordinates.Angle(simple * astropy.units.deg)
100def temperature_to_simple(temp):
101 """Convert temperature to kelvin."""
102 return temp.to(astropy.units.K, equivalencies=astropy.units.temperature()).to_value()
105def simple_to_temperature(simple, **kwargs):
106 """Convert scalar kelvin value back to quantity."""
107 return simple * astropy.units.K
110def pressure_to_simple(press):
111 """Convert pressure Quantity to hPa."""
112 return press.to_value(astropy.units.hPa)
115def simple_to_pressure(simple, **kwargs):
116 """Convert the pressure scalar back to Quantity."""
117 return simple * astropy.units.hPa
120def skycoord_to_simple(skycoord):
121 """Convert SkyCoord to ICRS RA/Dec tuple"""
122 icrs = skycoord.icrs
123 return (icrs.ra.to_value(astropy.units.deg),
124 icrs.dec.to_value(astropy.units.deg))
127def simple_to_skycoord(simple, **kwargs):
128 """Convert ICRS tuple to SkyCoord."""
129 return astropy.coordinates.SkyCoord(*simple, unit=astropy.units.deg)
132def altaz_to_simple(altaz):
133 """Convert AltAz to Alt/Az tuple.
135 Do not include obstime or location in simplification. It is assumed
136 that those will be present from other properties.
137 """
138 return (altaz.az.to_value(astropy.units.deg),
139 altaz.alt.to_value(astropy.units.deg))
142def simple_to_altaz(simple, **kwargs):
143 """Convert simple altaz tuple to AltAz.
145 Will look for location and datetime_begin in kwargs.
146 """
147 location = kwargs.get("location")
148 obstime = kwargs.get("datetime_begin")
150 return astropy.coordinates.AltAz(simple[0]*astropy.units.deg, simple[1]*astropy.units.deg,
151 obstime=obstime, location=location)
154# Dict of properties to tuple where tuple is:
155# - description of property
156# - Python type of property as a string (suitable for docstrings)
157# - Actual python type as a type
158# - Simplification function (can be None)
159# - Function to convert simple form back to required type (can be None)
160PROPERTIES = {"telescope": ("Full name of the telescope.", "str", str, None, None),
161 "instrument": ("The instrument used to observe the exposure.", "str", str, None, None),
162 "location": ("Location of the observatory.", "astropy.coordinates.EarthLocation",
163 astropy.coordinates.EarthLocation,
164 earthlocation_to_simple, simple_to_earthlocation),
165 "exposure_id": ("Unique (with instrument) integer identifier for this observation.", "int",
166 int, None, None),
167 "visit_id": ("""ID of the Visit this Exposure is associated with.
169Science observations should essentially always be
170associated with a visit, but calibration observations
171may not be.""", "int", int, None, None),
172 "physical_filter": ("The bandpass filter used for this observation.", "str", str, None, None),
173 "datetime_begin": ("Time of the start of the observation.", "astropy.time.Time",
174 astropy.time.Time,
175 datetime_to_simple, simple_to_datetime),
176 "datetime_end": ("Time of the end of the observation.", "astropy.time.Time",
177 astropy.time.Time,
178 datetime_to_simple, simple_to_datetime),
179 "exposure_time": ("Duration of the exposure with shutter open (seconds).",
180 "astropy.units.Quantity", astropy.units.Quantity,
181 exptime_to_simple, simple_to_exptime),
182 "dark_time": ("Duration of the exposure with shutter closed (seconds).",
183 "astropy.units.Quantity", astropy.units.Quantity,
184 exptime_to_simple, simple_to_exptime),
185 "boresight_airmass": ("Airmass of the boresight of the telescope.", "float", float, None, None),
186 "boresight_rotation_angle": ("Angle of the instrument in boresight_rotation_coord frame.",
187 "astropy.coordinates.Angle", astropy.coordinates.Angle,
188 angle_to_simple, simple_to_angle),
189 "boresight_rotation_coord": ("Coordinate frame of the instrument rotation angle"
190 " (options: sky, unknown).", "str", str, None, None),
191 "detector_num": ("Unique (for instrument) integer identifier for the sensor.", "int", int,
192 None, None),
193 "detector_name": ("Name of the detector within the instrument (might not be unique"
194 " if there are detector groups).",
195 "str", str, None, None),
196 "detector_unique_name": ("Unique name of the detector within the focal plane, generally"
197 " combining detector_group with detector_name.",
198 "str", str, None, None),
199 "detector_serial": ("Serial number/string associated with this detector.", "str", str,
200 None, None),
201 "detector_group": ("Collection name of which this detector is a part. "
202 "Can be None if there are no detector groupings.", "str", str,
203 None, None),
204 "detector_exposure_id": ("Unique integer identifier for this detector in this exposure.",
205 "int", int, None, None),
206 "object": ("Object of interest or field name.", "str", str, None, None),
207 "temperature": ("Temperature outside the dome.", "astropy.units.Quantity",
208 astropy.units.Quantity, temperature_to_simple, simple_to_temperature),
209 "pressure": ("Atmospheric pressure outside the dome.", "astropy.units.Quantity",
210 astropy.units.Quantity, pressure_to_simple, simple_to_pressure),
211 "relative_humidity": ("Relative humidity outside the dome.", "float", float, None, None),
212 "tracking_radec": ("Requested RA/Dec to track.", "astropy.coordinates.SkyCoord",
213 astropy.coordinates.SkyCoord,
214 skycoord_to_simple, simple_to_skycoord),
215 "altaz_begin": ("Telescope boresight azimuth and elevation at start of observation.",
216 "astropy.coordinates.AltAz", astropy.coordinates.AltAz,
217 altaz_to_simple, simple_to_altaz),
218 "science_program": ("Observing program (survey or proposal) identifier.", "str", str,
219 None, None),
220 "observation_type": ("Type of observation (currently: science, dark, flat, bias, focus).",
221 "str", str, None, None),
222 "observation_id": ("Label uniquely identifying this observation "
223 "(can be related to 'exposure_id').",
224 "str", str, None, None),
225 "observation_reason": ("Reason this observation was taken, or its purpose ('science' and "
226 "'calibration' are common values)",
227 "str", str, None, None),
228 "exposure_group": ("Label to use to associate this exposure with others "
229 "(can be related to 'exposure_id').",
230 "str", str, None, None),
231 "observing_day": ("Integer in YYYYMMDD format corresponding to the day of observation.",
232 "int", int, None, None),
233 "observation_counter": ("Counter of this observation. Can be counter within observing_day "
234 " or a global counter. Likely to be observatory specific.",
235 "int", int, None, None),
236 }