Coverage for tests/test_visitInfo.py: 12%
342 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-23 02:38 -0700
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-23 02:38 -0700
1#
2# LSST Data Management System
3# Copyright 2016 LSST Corporation.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22import math
23import os
24import unittest
25import collections
26import numpy as np
28import lsst.utils.tests
29import lsst.pex.exceptions
30from lsst.daf.base import DateTime, PropertySet, PropertyList
31from lsst.geom import Angle, degrees, SpherePoint
32from lsst.afw.coord import Observatory, Weather
33import lsst.afw.image as afwImage
35RotTypeEnumNameDict = {
36 afwImage.RotType.UNKNOWN: "UNKNOWN",
37 afwImage.RotType.SKY: "SKY",
38 afwImage.RotType.HORIZON: "HORIZON",
39 afwImage.RotType.MOUNT: "MOUNT",
40}
43def propertySetFromDict(keyValDict):
44 """Make an lsst.daf.base.PropertySet from a dict of key: value"""
45 metadata = PropertySet()
46 for key, val in keyValDict.items():
47 metadata.set(key, val)
48 return metadata
51def makeVisitInfo(data):
52 """Return a VisitInfo constructed from a VisitInfoData namedtuple."""
53 return afwImage.VisitInfo(data.exposureId,
54 data.exposureTime,
55 data.darkTime,
56 data.date,
57 data.ut1,
58 data.era,
59 data.boresightRaDec,
60 data.boresightAzAlt,
61 data.boresightAirmass,
62 data.boresightRotAngle,
63 data.rotType,
64 data.observatory,
65 data.weather,
66 data.instrumentLabel,
67 data.id,
68 )
71class VisitInfoTestCase(lsst.utils.tests.TestCase):
72 """Test lsst.afw.image.VisitInfo, a simple struct-like class"""
74 def setUp(self):
75 self.testDir = os.path.dirname(__file__)
77 def computeLstHA(data):
78 """Return LST, Hour Angle, computed from VisitInfoData."""
79 localEra = data.era + data.observatory.getLongitude()
80 hourAngle = localEra - data.boresightRaDec[0]
81 return localEra, hourAngle
83 fields = ['exposureId',
84 'exposureTime',
85 'darkTime',
86 'date',
87 'ut1',
88 'era',
89 'boresightRaDec',
90 'boresightAzAlt',
91 'boresightAirmass',
92 'boresightRotAngle',
93 'rotType',
94 'observatory',
95 'weather',
96 'instrumentLabel',
97 'id',
98 ]
99 VisitInfoData = collections.namedtuple("VisitInfoData", fields)
100 data1 = VisitInfoData(exposureId=10313423,
101 exposureTime=10.01,
102 darkTime=11.02,
103 date=DateTime(
104 65321.1, DateTime.MJD, DateTime.TAI),
105 ut1=12345.1,
106 era=45.1*degrees,
107 boresightRaDec=SpherePoint(
108 23.1*degrees, 73.2*degrees),
109 boresightAzAlt=SpherePoint(
110 134.5*degrees, 33.3*degrees),
111 boresightAirmass=1.73,
112 boresightRotAngle=73.2*degrees,
113 rotType=afwImage.RotType.SKY,
114 observatory=Observatory(
115 11.1*degrees, 22.2*degrees, 0.333),
116 weather=Weather(1.1, 2.2, 34.5),
117 instrumentLabel="TestCameraOne",
118 id=987654,
119 )
120 self.data1 = data1
121 self.localEra1, self.hourAngle1 = computeLstHA(data1)
122 data2 = VisitInfoData(exposureId=1,
123 exposureTime=15.5,
124 darkTime=17.8,
125 date=DateTime(
126 55321.2, DateTime.MJD, DateTime.TAI),
127 ut1=312345.1,
128 era=25.1*degrees,
129 boresightRaDec=SpherePoint(
130 2.1*degrees, 33.2*degrees),
131 boresightAzAlt=SpherePoint(13.5*degrees, 83.3*degrees),
132 boresightAirmass=2.05,
133 boresightRotAngle=-53.2*degrees,
134 rotType=afwImage.RotType.HORIZON,
135 observatory=Observatory(
136 22.2*degrees, 33.3*degrees, 0.444),
137 weather=Weather(2.2, 3.3, 44.4),
138 instrumentLabel="TestCameraTwo",
139 id=123456
140 )
141 self.data2 = data2
142 self.localEra2, self.hourAngle2 = computeLstHA(data2)
144 def _testValueConstructor(self, data, localEra, hourAngle):
145 visitInfo = makeVisitInfo(data)
146 with self.assertWarns(FutureWarning):
147 self.assertEqual(visitInfo.getExposureId(), data.exposureId)
148 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime)
149 self.assertEqual(visitInfo.getDarkTime(), data.darkTime)
150 self.assertEqual(visitInfo.getDate(), data.date)
151 self.assertEqual(visitInfo.getUt1(), data.ut1)
152 self.assertEqual(visitInfo.getEra(), data.era)
153 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec)
154 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt)
155 self.assertEqual(visitInfo.getBoresightAirmass(),
156 data.boresightAirmass)
157 self.assertEqual(visitInfo.getBoresightRotAngle(),
158 data.boresightRotAngle)
159 self.assertEqual(visitInfo.getRotType(), data.rotType)
160 self.assertEqual(visitInfo.getObservatory(), data.observatory)
161 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel)
162 self.assertEqual(visitInfo.getWeather(), data.weather)
163 self.assertEqual(visitInfo.getLocalEra(), localEra)
164 self.assertEqual(visitInfo.getBoresightHourAngle(), hourAngle)
165 self.assertEqual(visitInfo.getId(), data.id)
167 def _testProperties(self, data, localEra, hourAngle):
168 """Test property attribute accessors."""
169 visitInfo = makeVisitInfo(data)
170 self.assertEqual(visitInfo.exposureTime, data.exposureTime)
171 self.assertEqual(visitInfo.darkTime, data.darkTime)
172 self.assertEqual(visitInfo.date, data.date)
173 self.assertEqual(visitInfo.ut1, data.ut1)
174 self.assertEqual(visitInfo.era, data.era)
175 self.assertEqual(visitInfo.boresightRaDec, data.boresightRaDec)
176 self.assertEqual(visitInfo.boresightAzAlt, data.boresightAzAlt)
177 self.assertEqual(visitInfo.boresightAirmass, data.boresightAirmass)
178 self.assertEqual(visitInfo.boresightRotAngle, data.boresightRotAngle)
179 self.assertEqual(visitInfo.rotType, data.rotType)
180 self.assertEqual(visitInfo.observatory, data.observatory)
181 self.assertEqual(visitInfo.instrumentLabel, data.instrumentLabel)
182 self.assertEqual(visitInfo.weather, data.weather)
183 self.assertEqual(visitInfo.localEra, localEra)
184 self.assertEqual(visitInfo.boresightHourAngle, hourAngle)
185 self.assertEqual(visitInfo.id, data.id)
187 def testValueConstructor_data1(self):
188 self._testValueConstructor(self.data1, self.localEra1, self.hourAngle1)
189 self._testProperties(self.data1, self.localEra1, self.hourAngle1)
191 def testValueConstructor_data2(self):
192 self._testValueConstructor(self.data2, self.localEra2, self.hourAngle2)
193 self._testProperties(self.data2, self.localEra2, self.hourAngle2)
195 def testTablePersistence(self):
196 """Test that VisitInfo can be round-tripped with current code.
197 """
198 for item in (self.data1, self.data2):
199 tablePath = os.path.join(
200 self.testDir, "testVisitInfo_testTablePersistence.fits")
201 v1 = afwImage.VisitInfo(*item)
202 v1.writeFits(tablePath)
203 v2 = afwImage.VisitInfo.readFits(tablePath)
204 self.assertEqual(v1, v2)
205 os.unlink(tablePath)
207 def _testFitsRead(self, data, filePath, version):
208 """Test that old VersionInfo files are read correctly.
210 Parameters
211 ----------
212 data : `VisitInfoData`
213 The values expected to be stored in the file, or a
214 superset thereof.
215 filePath : `str`
216 The file to test.
217 version : `int`
218 The VersionInfo persistence format used in ``filePath``.
219 """
220 visitInfo = afwImage.VisitInfo.readFits(filePath)
222 if version >= 0:
223 with self.assertWarns(FutureWarning):
224 self.assertEqual(visitInfo.getExposureId(), data.exposureId)
225 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime)
226 self.assertEqual(visitInfo.getDarkTime(), data.darkTime)
227 self.assertEqual(visitInfo.getDate(), data.date)
228 self.assertEqual(visitInfo.getUt1(), data.ut1)
229 self.assertEqual(visitInfo.getEra(), data.era)
230 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec)
231 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt)
232 self.assertEqual(visitInfo.getBoresightAirmass(),
233 data.boresightAirmass)
234 self.assertEqual(visitInfo.getBoresightRotAngle(),
235 data.boresightRotAngle)
236 self.assertEqual(visitInfo.getRotType(), data.rotType)
237 self.assertEqual(visitInfo.getObservatory(), data.observatory)
238 self.assertEqual(visitInfo.getWeather(), data.weather)
239 if version >= 1:
240 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel)
241 else:
242 self.assertEqual(visitInfo.getInstrumentLabel(), "")
243 if version >= 2:
244 self.assertEqual(visitInfo.getId(), data.id)
245 else:
246 self.assertEqual(visitInfo.getId(), 0)
248 def testPersistenceVersions(self):
249 """Test that older versions are handled appropriately.
250 """
251 dataDir = os.path.join(os.path.dirname(__file__), "data")
253 # All files created by makeVisitInfo(self.data1).writeFits()
254 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-noversion.fits"), 0)
255 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-version-1.fits"), 1)
256 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-version-2.fits"), 2)
258 def testSetVisitInfoMetadata(self):
259 for item in (self.data1, self.data2):
260 visitInfo = makeVisitInfo(item)
261 metadata = PropertyList()
262 afwImage.setVisitInfoMetadata(metadata, visitInfo)
263 self.assertEqual(metadata.nameCount(), 22)
264 self.assertEqual(metadata.getScalar("EXPID"), item.exposureId)
265 self.assertEqual(metadata.getScalar("EXPTIME"), item.exposureTime)
266 self.assertEqual(metadata.getScalar("DARKTIME"), item.darkTime)
267 self.assertEqual(metadata.getScalar("DATE-AVG"),
268 item.date.toString(DateTime.TAI))
269 self.assertEqual(metadata.getScalar("TIMESYS"), "TAI")
270 self.assertEqual(metadata.getScalar("MJD-AVG-UT1"), item.ut1)
271 self.assertEqual(metadata.getScalar("AVG-ERA"), item.era.asDegrees())
272 self.assertEqual(metadata.getScalar("BORE-RA"),
273 item.boresightRaDec[0].asDegrees())
274 self.assertEqual(metadata.getScalar("BORE-DEC"),
275 item.boresightRaDec[1].asDegrees())
276 self.assertEqual(metadata.getScalar("BORE-AZ"),
277 item.boresightAzAlt[0].asDegrees())
278 self.assertEqual(metadata.getScalar("BORE-ALT"),
279 item.boresightAzAlt[1].asDegrees())
280 self.assertEqual(metadata.getScalar("BORE-AIRMASS"),
281 item.boresightAirmass)
282 self.assertEqual(metadata.getScalar("BORE-ROTANG"),
283 item.boresightRotAngle.asDegrees())
284 self.assertEqual(metadata.getScalar("ROTTYPE"),
285 RotTypeEnumNameDict[item.rotType])
286 self.assertEqual(metadata.getScalar("OBS-LONG"),
287 item.observatory.getLongitude().asDegrees())
288 self.assertEqual(metadata.getScalar("OBS-LAT"),
289 item.observatory.getLatitude().asDegrees())
290 self.assertEqual(metadata.getScalar("OBS-ELEV"),
291 item.observatory.getElevation())
292 self.assertEqual(metadata.getScalar("AIRTEMP"),
293 item.weather.getAirTemperature())
294 self.assertEqual(metadata.getScalar("AIRPRESS"),
295 item.weather.getAirPressure())
296 self.assertEqual(metadata.getScalar("HUMIDITY"),
297 item.weather.getHumidity())
298 self.assertEqual(metadata.getScalar("INSTRUMENT"),
299 item.instrumentLabel)
300 self.assertEqual(metadata.getScalar("IDNUM"),
301 item.id)
303 def testSetVisitInfoMetadataMissingValues(self):
304 """If a value is unknown then it should not be written to the metadata"""
305 visitInfo = afwImage.VisitInfo() # only rot type is known
306 metadata = PropertyList()
307 afwImage.setVisitInfoMetadata(metadata, visitInfo)
308 self.assertEqual(metadata.getScalar("ROTTYPE"),
309 RotTypeEnumNameDict[afwImage.RotType.UNKNOWN])
310 self.assertEqual(metadata.nameCount(), 1)
312 def testStripVisitInfoKeywords(self):
313 for argList in (self.data1, self.data2):
314 visitInfo = afwImage.VisitInfo(*argList)
315 metadata = PropertyList()
316 afwImage.setVisitInfoMetadata(metadata, visitInfo)
317 # add an extra keyword that will not be stripped
318 metadata.set("EXTRA", 5)
319 self.assertEqual(metadata.nameCount(), 23)
320 afwImage.stripVisitInfoKeywords(metadata)
321 self.assertEqual(metadata.nameCount(), 1)
323 def _testIsEmpty(self, visitInfo):
324 """Test that visitInfo is all NaN, 0, or empty string, as appropriate.
325 """
326 with self.assertWarns(FutureWarning):
327 self.assertEqual(visitInfo.getExposureId(), 0)
328 self.assertTrue(math.isnan(visitInfo.getExposureTime()))
329 self.assertTrue(math.isnan(visitInfo.getDarkTime()))
330 self.assertEqual(visitInfo.getDate(), DateTime())
331 self.assertTrue(math.isnan(visitInfo.getUt1()))
332 self.assertTrue(math.isnan(visitInfo.getEra().asDegrees()))
333 for i in range(2):
334 self.assertTrue(math.isnan(
335 visitInfo.getBoresightRaDec()[i].asDegrees()))
336 self.assertTrue(math.isnan(
337 visitInfo.getBoresightAzAlt()[i].asDegrees()))
338 self.assertTrue(math.isnan(visitInfo.getBoresightAirmass()))
339 self.assertTrue(math.isnan(
340 visitInfo.getBoresightRotAngle().asDegrees()))
341 self.assertEqual(visitInfo.getRotType(), afwImage.RotType.UNKNOWN)
342 self.assertTrue(math.isnan(
343 visitInfo.getObservatory().getLongitude().asDegrees()))
344 self.assertTrue(math.isnan(
345 visitInfo.getObservatory().getLatitude().asDegrees()))
346 self.assertTrue(math.isnan(visitInfo.getObservatory().getElevation()))
347 self.assertTrue(math.isnan(visitInfo.getWeather().getAirTemperature()))
348 self.assertTrue(math.isnan(visitInfo.getWeather().getAirPressure()))
349 self.assertTrue(math.isnan(visitInfo.getWeather().getHumidity()))
350 self.assertTrue(math.isnan(visitInfo.getBoresightHourAngle()))
351 self.assertEqual(visitInfo.getInstrumentLabel(), "")
352 self.assertEqual(visitInfo.getId(), 0)
354 def testEquals(self):
355 """Test that identical VisitInfo objects compare equal, even if some fields are NaN.
356 """
357 # objects with "equal state" should be equal
358 self.assertEqual(makeVisitInfo(self.data1), makeVisitInfo(self.data1))
359 self.assertEqual(makeVisitInfo(self.data2), makeVisitInfo(self.data2))
360 self.assertNotEqual(makeVisitInfo(self.data1), makeVisitInfo(self.data2))
361 self.assertEqual(afwImage.VisitInfo(), afwImage.VisitInfo())
363 # equality must be reflexive
364 info = makeVisitInfo(self.data1)
365 self.assertEqual(info, info)
366 info = makeVisitInfo(self.data2)
367 self.assertEqual(info, info)
368 info = afwImage.VisitInfo()
369 self.assertEqual(info, info)
371 # commutativity and transitivity difficult to test with this setup
373 def testMetadataConstructor(self):
374 """Test the metadata constructor
376 This constructor allows missing values
377 """
378 data = self.data1
380 metadata = propertySetFromDict({})
381 visitInfo = afwImage.VisitInfo(metadata)
382 self._testIsEmpty(visitInfo)
384 metadata = propertySetFromDict({"EXPID": data.exposureId})
385 visitInfo = afwImage.VisitInfo(metadata)
386 with self.assertWarns(FutureWarning):
387 self.assertEqual(visitInfo.getExposureId(), data.exposureId)
388 self.assertTrue(math.isnan(visitInfo.getExposureTime()))
390 metadata = propertySetFromDict({"EXPTIME": data.exposureTime})
391 visitInfo = afwImage.VisitInfo(metadata)
392 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime)
394 metadata = propertySetFromDict({"DARKTIME": data.darkTime})
395 visitInfo = afwImage.VisitInfo(metadata)
396 self.assertEqual(visitInfo.getDarkTime(), data.darkTime)
398 metadata = propertySetFromDict(
399 {"DATE-AVG": data.date.toString(DateTime.TAI), "TIMESYS": "TAI"})
400 visitInfo = afwImage.VisitInfo(metadata)
401 self.assertEqual(visitInfo.getDate(), data.date)
403 # TIME-MID in UTC is an acceptable alternative to DATE-AVG
404 metadata = propertySetFromDict(
405 {"TIME-MID": data.date.toString(DateTime.UTC)})
406 visitInfo = afwImage.VisitInfo(metadata)
407 self.assertEqual(visitInfo.getDate(), data.date)
409 # TIME-MID must be in UTC and TIMESYS is ignored
410 metadata = propertySetFromDict({
411 "TIME-MID": data.date.toString(DateTime.TAI) + "Z",
412 "TIMESYS": "TAI",
413 })
414 visitInfo = afwImage.VisitInfo(metadata)
415 self.assertNotEqual(visitInfo.getDate(), data.date)
417 # if both DATE-AVG and TIME-MID provided then use DATE-AVG
418 # use the wrong time system for TIME-MID so if it is used, an error
419 # will result
420 metadata = propertySetFromDict({
421 "DATE-AVG": data.date.toString(DateTime.TAI),
422 "TIMESYS": "TAI",
423 "TIME-MID": data.date.toString(DateTime.TAI) + "Z",
424 })
425 visitInfo = afwImage.VisitInfo(metadata)
426 self.assertEqual(visitInfo.getDate(), data.date)
428 metadata = propertySetFromDict({"MJD-AVG-UT1": data.ut1})
429 visitInfo = afwImage.VisitInfo(metadata)
430 self.assertEqual(visitInfo.getUt1(), data.ut1)
432 metadata = propertySetFromDict({"AVG-ERA": data.era.asDegrees()})
433 visitInfo = afwImage.VisitInfo(metadata)
434 self.assertEqual(visitInfo.getEra(), data.era)
436 for i, key in enumerate(("BORE-RA", "BORE-DEC")):
437 metadata = propertySetFromDict(
438 {key: data.boresightRaDec[i].asDegrees()})
439 visitInfo = afwImage.VisitInfo(metadata)
440 self.assertEqual(visitInfo.getBoresightRaDec()
441 [i], data.boresightRaDec[i])
443 for i, key in enumerate(("BORE-AZ", "BORE-ALT")):
444 metadata = propertySetFromDict(
445 {key: data.boresightAzAlt[i].asDegrees()})
446 visitInfo = afwImage.VisitInfo(metadata)
447 self.assertEqual(visitInfo.getBoresightAzAlt()
448 [i], data.boresightAzAlt[i])
450 metadata = propertySetFromDict({"BORE-AIRMASS": data.boresightAirmass})
451 visitInfo = afwImage.VisitInfo(metadata)
452 self.assertEqual(visitInfo.getBoresightAirmass(),
453 data.boresightAirmass)
455 metadata = propertySetFromDict(
456 {"BORE-ROTANG": data.boresightRotAngle.asDegrees()})
457 visitInfo = afwImage.VisitInfo(metadata)
458 self.assertEqual(visitInfo.getBoresightRotAngle(),
459 data.boresightRotAngle)
461 metadata = propertySetFromDict(
462 {"ROTTYPE": RotTypeEnumNameDict[data.rotType]})
463 visitInfo = afwImage.VisitInfo(metadata)
464 self.assertEqual(visitInfo.getRotType(), data.rotType)
466 metadata = propertySetFromDict(
467 {"OBS-LONG": data.observatory.getLongitude().asDegrees()})
468 visitInfo = afwImage.VisitInfo(metadata)
469 self.assertEqual(visitInfo.getObservatory().getLongitude(),
470 data.observatory.getLongitude())
472 metadata = propertySetFromDict(
473 {"OBS-LAT": data.observatory.getLatitude().asDegrees()})
474 visitInfo = afwImage.VisitInfo(metadata)
475 self.assertEqual(visitInfo.getObservatory().getLatitude(),
476 data.observatory.getLatitude())
478 metadata = propertySetFromDict(
479 {"OBS-ELEV": data.observatory.getElevation()})
480 visitInfo = afwImage.VisitInfo(metadata)
481 self.assertEqual(visitInfo.getObservatory().getElevation(),
482 data.observatory.getElevation())
484 metadata = propertySetFromDict(
485 {"AIRTEMP": data.weather.getAirTemperature()})
486 visitInfo = afwImage.VisitInfo(metadata)
487 self.assertEqual(visitInfo.getWeather().getAirTemperature(),
488 data.weather.getAirTemperature())
490 metadata = propertySetFromDict(
491 {"AIRPRESS": data.weather.getAirPressure()})
492 visitInfo = afwImage.VisitInfo(metadata)
493 self.assertEqual(visitInfo.getWeather().getAirPressure(),
494 data.weather.getAirPressure())
496 metadata = propertySetFromDict(
497 {"HUMIDITY": data.weather.getHumidity()})
498 visitInfo = afwImage.VisitInfo(metadata)
499 self.assertEqual(visitInfo.getWeather().getHumidity(),
500 data.weather.getHumidity())
502 metadata = propertySetFromDict({"INSTRUMENT": data.instrumentLabel})
503 visitInfo = afwImage.VisitInfo(metadata)
504 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel)
506 metadata = propertySetFromDict({"IDNUM": data.id})
507 visitInfo = afwImage.VisitInfo(metadata)
508 self.assertEqual(visitInfo.getId(), data.id)
510 def testConstructorKeywordArguments(self):
511 """Test VisitInfo with named arguments"""
512 data = self.data1
514 visitInfo = afwImage.VisitInfo()
515 self._testIsEmpty(visitInfo)
517 visitInfo = afwImage.VisitInfo(exposureId=data.exposureId)
518 with self.assertWarns(FutureWarning):
519 self.assertEqual(visitInfo.getExposureId(), data.exposureId)
520 self.assertTrue(math.isnan(visitInfo.getExposureTime()))
522 visitInfo = afwImage.VisitInfo(exposureTime=data.exposureTime)
523 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime)
525 visitInfo = afwImage.VisitInfo(darkTime=data.darkTime)
526 self.assertEqual(visitInfo.getDarkTime(), data.darkTime)
528 visitInfo = afwImage.VisitInfo(date=data.date)
529 self.assertEqual(visitInfo.getDate(), data.date)
531 visitInfo = afwImage.VisitInfo(ut1=data.ut1)
532 self.assertEqual(visitInfo.getUt1(), data.ut1)
534 visitInfo = afwImage.VisitInfo(era=data.era)
535 self.assertEqual(visitInfo.getEra(), data.era)
537 visitInfo = afwImage.VisitInfo(boresightRaDec=data.boresightRaDec)
538 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec)
540 visitInfo = afwImage.VisitInfo(boresightAzAlt=data.boresightAzAlt)
541 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt)
543 visitInfo = afwImage.VisitInfo(boresightAirmass=data.boresightAirmass)
544 self.assertEqual(visitInfo.getBoresightAirmass(),
545 data.boresightAirmass)
547 visitInfo = afwImage.VisitInfo(
548 boresightRotAngle=data.boresightRotAngle)
549 self.assertEqual(visitInfo.getBoresightRotAngle(),
550 data.boresightRotAngle)
552 visitInfo = afwImage.VisitInfo(rotType=data.rotType)
553 self.assertEqual(visitInfo.getRotType(), data.rotType)
555 visitInfo = afwImage.VisitInfo(observatory=data.observatory)
556 self.assertEqual(visitInfo.getObservatory(), data.observatory)
558 visitInfo = afwImage.VisitInfo(weather=data.weather)
559 self.assertEqual(visitInfo.getWeather(), data.weather)
561 visitInfo = afwImage.VisitInfo(instrumentLabel=data.instrumentLabel)
562 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel)
564 visitInfo = afwImage.VisitInfo(id=data.id)
565 self.assertEqual(visitInfo.getId(), data.id)
567 def testGoodRotTypes(self):
568 """Test round trip of all valid rot types"""
569 for rotType in RotTypeEnumNameDict:
570 metadata = propertySetFromDict(
571 {"ROTTYPE": RotTypeEnumNameDict[rotType]})
572 visitInfo = afwImage.VisitInfo(metadata)
573 self.assertEqual(visitInfo.getRotType(), rotType)
575 def testBadRotTypes(self):
576 """Test that invalid rot type names cannot be used to construct a VisitInfo"""
577 for badRotTypeName in (
578 "unknown", # must be all uppercase
579 "sky", # must be all uppercase
580 "Sky", # must be all uppercase
581 "SKY1", # extra chars
582 "HORIZONTAL", # extra chars
583 ):
584 metadata = propertySetFromDict({"ROTTYPE": badRotTypeName})
585 with self.assertRaises(lsst.pex.exceptions.RuntimeError):
586 afwImage.VisitInfo(metadata)
588 def test_str(self):
589 """Check that we get something reasonable for str()"""
590 visitInfo = makeVisitInfo(self.data1)
591 string = str(visitInfo)
592 self.assertIn("exposureId=10313423", string)
593 self.assertIn("exposureTime=10.01", string)
594 self.assertIn("darkTime=11.02", string)
595 self.assertIn("rotType=1", string)
597 # Check that it at least doesn't throw
598 str(afwImage.VisitInfo())
600 def testParallacticAngle(self):
601 """Check that we get the same precomputed values for parallactic angle."""
602 parallacticAngle = [141.39684140703142*degrees, 76.99982166973487*degrees]
603 for item, parAngle in zip((self.data1, self.data2), parallacticAngle):
604 visitInfo = afwImage.VisitInfo(era=item.era,
605 boresightRaDec=item.boresightRaDec,
606 observatory=item.observatory,
607 )
608 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), parAngle)
610 def testParallacticAngleNorthMeridian(self):
611 """An observation on the Meridian that is North of zenith has a parallactic angle of pi radians."""
612 meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude()
613 northBoresightDec = self.data1.observatory.getLatitude() + 10.*degrees
614 visitInfo = afwImage.VisitInfo(era=self.data1.era,
615 boresightRaDec=SpherePoint(meridianBoresightRA,
616 northBoresightDec),
617 observatory=self.data1.observatory,
618 )
619 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), Angle(np.pi))
621 def testParallacticAngleSouthMeridian(self):
622 """An observation on the Meridian that is South of zenith has a parallactic angle of zero."""
623 meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude()
624 southBoresightDec = self.data1.observatory.getLatitude() - 10.*degrees
625 visitInfo = afwImage.VisitInfo(era=self.data1.era,
626 boresightRaDec=SpherePoint(meridianBoresightRA,
627 southBoresightDec),
628 observatory=self.data1.observatory,
629 )
630 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), Angle(0.))
633def setup_module(module):
634 lsst.utils.tests.init()
637class MemoryTester(lsst.utils.tests.MemoryTestCase):
638 pass
641if __name__ == "__main__": 641 ↛ 642line 641 didn't jump to line 642, because the condition on line 641 was never true
642 lsst.utils.tests.init()
643 unittest.main()