Hide keyboard shortcuts

Hot-keys 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# 

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 

27 

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 

34 

35RotTypeEnumNameDict = { 

36 afwImage.RotType.UNKNOWN: "UNKNOWN", 

37 afwImage.RotType.SKY: "SKY", 

38 afwImage.RotType.HORIZON: "HORIZON", 

39 afwImage.RotType.MOUNT: "MOUNT", 

40} 

41 

42 

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 

49 

50 

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 ) 

69 

70 

71class VisitInfoTestCase(lsst.utils.tests.TestCase): 

72 """Test lsst.afw.image.VisitInfo, a simple struct-like class""" 

73 

74 def setUp(self): 

75 self.testDir = os.path.dirname(__file__) 

76 

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 

82 

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) 

143 

144 def _testValueConstructor(self, data, localEra, hourAngle): 

145 visitInfo = makeVisitInfo(data) 

146 self.assertEqual(visitInfo.getExposureId(), data.exposureId) 

147 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime) 

148 self.assertEqual(visitInfo.getDarkTime(), data.darkTime) 

149 self.assertEqual(visitInfo.getDate(), data.date) 

150 self.assertEqual(visitInfo.getUt1(), data.ut1) 

151 self.assertEqual(visitInfo.getEra(), data.era) 

152 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec) 

153 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt) 

154 self.assertEqual(visitInfo.getBoresightAirmass(), 

155 data.boresightAirmass) 

156 self.assertEqual(visitInfo.getBoresightRotAngle(), 

157 data.boresightRotAngle) 

158 self.assertEqual(visitInfo.getRotType(), data.rotType) 

159 self.assertEqual(visitInfo.getObservatory(), data.observatory) 

160 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel) 

161 self.assertEqual(visitInfo.getWeather(), data.weather) 

162 self.assertEqual(visitInfo.getLocalEra(), localEra) 

163 self.assertEqual(visitInfo.getBoresightHourAngle(), hourAngle) 

164 self.assertEqual(visitInfo.getId(), data.id) 

165 

166 def _testProperties(self, data, localEra, hourAngle): 

167 """Test property attribute accessors.""" 

168 visitInfo = makeVisitInfo(data) 

169 self.assertEqual(visitInfo.exposureTime, data.exposureTime) 

170 self.assertEqual(visitInfo.darkTime, data.darkTime) 

171 self.assertEqual(visitInfo.date, data.date) 

172 self.assertEqual(visitInfo.ut1, data.ut1) 

173 self.assertEqual(visitInfo.era, data.era) 

174 self.assertEqual(visitInfo.boresightRaDec, data.boresightRaDec) 

175 self.assertEqual(visitInfo.boresightAzAlt, data.boresightAzAlt) 

176 self.assertEqual(visitInfo.boresightAirmass, data.boresightAirmass) 

177 self.assertEqual(visitInfo.boresightRotAngle, data.boresightRotAngle) 

178 self.assertEqual(visitInfo.rotType, data.rotType) 

179 self.assertEqual(visitInfo.observatory, data.observatory) 

180 self.assertEqual(visitInfo.instrumentLabel, data.instrumentLabel) 

181 self.assertEqual(visitInfo.weather, data.weather) 

182 self.assertEqual(visitInfo.localEra, localEra) 

183 self.assertEqual(visitInfo.boresightHourAngle, hourAngle) 

184 self.assertEqual(visitInfo.id, data.id) 

185 

186 def testValueConstructor_data1(self): 

187 self._testValueConstructor(self.data1, self.localEra1, self.hourAngle1) 

188 self._testProperties(self.data1, self.localEra1, self.hourAngle1) 

189 

190 def testValueConstructor_data2(self): 

191 self._testValueConstructor(self.data2, self.localEra2, self.hourAngle2) 

192 self._testProperties(self.data2, self.localEra2, self.hourAngle2) 

193 

194 def testTablePersistence(self): 

195 """Test that VisitInfo can be round-tripped with current code. 

196 """ 

197 for item in (self.data1, self.data2): 

198 tablePath = os.path.join( 

199 self.testDir, "testVisitInfo_testTablePersistence.fits") 

200 v1 = afwImage.VisitInfo(*item) 

201 v1.writeFits(tablePath) 

202 v2 = afwImage.VisitInfo.readFits(tablePath) 

203 self.assertEqual(v1, v2) 

204 os.unlink(tablePath) 

205 

206 def _testFitsRead(self, data, filePath, version): 

207 """Test that old VersionInfo files are read correctly. 

208 

209 Parameters 

210 ---------- 

211 data : `VisitInfoData` 

212 The values expected to be stored in the file, or a 

213 superset thereof. 

214 filePath : `str` 

215 The file to test. 

216 version : `int` 

217 The VersionInfo persistence format used in ``filePath``. 

218 """ 

219 visitInfo = afwImage.VisitInfo.readFits(filePath) 

220 

221 if version >= 0: 

222 self.assertEqual(visitInfo.getExposureId(), data.exposureId) 

223 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime) 

224 self.assertEqual(visitInfo.getDarkTime(), data.darkTime) 

225 self.assertEqual(visitInfo.getDate(), data.date) 

226 self.assertEqual(visitInfo.getUt1(), data.ut1) 

227 self.assertEqual(visitInfo.getEra(), data.era) 

228 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec) 

229 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt) 

230 self.assertEqual(visitInfo.getBoresightAirmass(), 

231 data.boresightAirmass) 

232 self.assertEqual(visitInfo.getBoresightRotAngle(), 

233 data.boresightRotAngle) 

234 self.assertEqual(visitInfo.getRotType(), data.rotType) 

235 self.assertEqual(visitInfo.getObservatory(), data.observatory) 

236 self.assertEqual(visitInfo.getWeather(), data.weather) 

237 if version >= 1: 

238 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel) 

239 else: 

240 self.assertEqual(visitInfo.getInstrumentLabel(), "") 

241 if version >= 2: 

242 self.assertEqual(visitInfo.getId(), data.id) 

243 else: 

244 self.assertEqual(visitInfo.getId(), 0) 

245 

246 def testPersistenceVersions(self): 

247 """Test that older versions are handled appropriately. 

248 """ 

249 dataDir = os.path.join(os.path.dirname(__file__), "data") 

250 

251 # All files created by makeVisitInfo(self.data1).writeFits() 

252 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-noversion.fits"), 0) 

253 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-version-1.fits"), 1) 

254 self._testFitsRead(self.data1, os.path.join(dataDir, "visitInfo-version-2.fits"), 2) 

255 

256 def testSetVisitInfoMetadata(self): 

257 for item in (self.data1, self.data2): 

258 visitInfo = makeVisitInfo(item) 

259 metadata = PropertyList() 

260 afwImage.setVisitInfoMetadata(metadata, visitInfo) 

261 self.assertEqual(metadata.nameCount(), 22) 

262 self.assertEqual(metadata.getScalar("EXPID"), item.exposureId) 

263 self.assertEqual(metadata.getScalar("EXPTIME"), item.exposureTime) 

264 self.assertEqual(metadata.getScalar("DARKTIME"), item.darkTime) 

265 self.assertEqual(metadata.getScalar("DATE-AVG"), 

266 item.date.toString(DateTime.TAI)) 

267 self.assertEqual(metadata.getScalar("TIMESYS"), "TAI") 

268 self.assertEqual(metadata.getScalar("MJD-AVG-UT1"), item.ut1) 

269 self.assertEqual(metadata.getScalar("AVG-ERA"), item.era.asDegrees()) 

270 self.assertEqual(metadata.getScalar("BORE-RA"), 

271 item.boresightRaDec[0].asDegrees()) 

272 self.assertEqual(metadata.getScalar("BORE-DEC"), 

273 item.boresightRaDec[1].asDegrees()) 

274 self.assertEqual(metadata.getScalar("BORE-AZ"), 

275 item.boresightAzAlt[0].asDegrees()) 

276 self.assertEqual(metadata.getScalar("BORE-ALT"), 

277 item.boresightAzAlt[1].asDegrees()) 

278 self.assertEqual(metadata.getScalar("BORE-AIRMASS"), 

279 item.boresightAirmass) 

280 self.assertEqual(metadata.getScalar("BORE-ROTANG"), 

281 item.boresightRotAngle.asDegrees()) 

282 self.assertEqual(metadata.getScalar("ROTTYPE"), 

283 RotTypeEnumNameDict[item.rotType]) 

284 self.assertEqual(metadata.getScalar("OBS-LONG"), 

285 item.observatory.getLongitude().asDegrees()) 

286 self.assertEqual(metadata.getScalar("OBS-LAT"), 

287 item.observatory.getLatitude().asDegrees()) 

288 self.assertEqual(metadata.getScalar("OBS-ELEV"), 

289 item.observatory.getElevation()) 

290 self.assertEqual(metadata.getScalar("AIRTEMP"), 

291 item.weather.getAirTemperature()) 

292 self.assertEqual(metadata.getScalar("AIRPRESS"), 

293 item.weather.getAirPressure()) 

294 self.assertEqual(metadata.getScalar("HUMIDITY"), 

295 item.weather.getHumidity()) 

296 self.assertEqual(metadata.getScalar("INSTRUMENT"), 

297 item.instrumentLabel) 

298 self.assertEqual(metadata.getScalar("IDNUM"), 

299 item.id) 

300 

301 def testSetVisitInfoMetadataMissingValues(self): 

302 """If a value is unknown then it should not be written to the metadata""" 

303 visitInfo = afwImage.VisitInfo() # only rot type is known 

304 metadata = PropertyList() 

305 afwImage.setVisitInfoMetadata(metadata, visitInfo) 

306 self.assertEqual(metadata.getScalar("ROTTYPE"), 

307 RotTypeEnumNameDict[afwImage.RotType.UNKNOWN]) 

308 self.assertEqual(metadata.nameCount(), 1) 

309 

310 def testStripVisitInfoKeywords(self): 

311 for argList in (self.data1, self.data2): 

312 visitInfo = afwImage.VisitInfo(*argList) 

313 metadata = PropertyList() 

314 afwImage.setVisitInfoMetadata(metadata, visitInfo) 

315 # add an extra keyword that will not be stripped 

316 metadata.set("EXTRA", 5) 

317 self.assertEqual(metadata.nameCount(), 23) 

318 afwImage.stripVisitInfoKeywords(metadata) 

319 self.assertEqual(metadata.nameCount(), 1) 

320 

321 def _testIsEmpty(self, visitInfo): 

322 """Test that visitInfo is all NaN, 0, or empty string, as appropriate. 

323 """ 

324 self.assertEqual(visitInfo.getExposureId(), 0) 

325 self.assertTrue(math.isnan(visitInfo.getExposureTime())) 

326 self.assertTrue(math.isnan(visitInfo.getDarkTime())) 

327 self.assertEqual(visitInfo.getDate(), DateTime()) 

328 self.assertTrue(math.isnan(visitInfo.getUt1())) 

329 self.assertTrue(math.isnan(visitInfo.getEra().asDegrees())) 

330 for i in range(2): 

331 self.assertTrue(math.isnan( 

332 visitInfo.getBoresightRaDec()[i].asDegrees())) 

333 self.assertTrue(math.isnan( 

334 visitInfo.getBoresightAzAlt()[i].asDegrees())) 

335 self.assertTrue(math.isnan(visitInfo.getBoresightAirmass())) 

336 self.assertTrue(math.isnan( 

337 visitInfo.getBoresightRotAngle().asDegrees())) 

338 self.assertEqual(visitInfo.getRotType(), afwImage.RotType.UNKNOWN) 

339 self.assertTrue(math.isnan( 

340 visitInfo.getObservatory().getLongitude().asDegrees())) 

341 self.assertTrue(math.isnan( 

342 visitInfo.getObservatory().getLatitude().asDegrees())) 

343 self.assertTrue(math.isnan(visitInfo.getObservatory().getElevation())) 

344 self.assertTrue(math.isnan(visitInfo.getWeather().getAirTemperature())) 

345 self.assertTrue(math.isnan(visitInfo.getWeather().getAirPressure())) 

346 self.assertTrue(math.isnan(visitInfo.getWeather().getHumidity())) 

347 self.assertTrue(math.isnan(visitInfo.getBoresightHourAngle())) 

348 self.assertEqual(visitInfo.getInstrumentLabel(), "") 

349 self.assertEqual(visitInfo.getId(), 0) 

350 

351 def testMetadataConstructor(self): 

352 """Test the metadata constructor 

353 

354 This constructor allows missing values 

355 """ 

356 data = self.data1 

357 

358 metadata = propertySetFromDict({}) 

359 visitInfo = afwImage.VisitInfo(metadata) 

360 self._testIsEmpty(visitInfo) 

361 

362 metadata = propertySetFromDict({"EXPID": data.exposureId}) 

363 visitInfo = afwImage.VisitInfo(metadata) 

364 self.assertEqual(visitInfo.getExposureId(), data.exposureId) 

365 self.assertTrue(math.isnan(visitInfo.getExposureTime())) 

366 

367 metadata = propertySetFromDict({"EXPTIME": data.exposureTime}) 

368 visitInfo = afwImage.VisitInfo(metadata) 

369 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime) 

370 

371 metadata = propertySetFromDict({"DARKTIME": data.darkTime}) 

372 visitInfo = afwImage.VisitInfo(metadata) 

373 self.assertEqual(visitInfo.getDarkTime(), data.darkTime) 

374 

375 metadata = propertySetFromDict( 

376 {"DATE-AVG": data.date.toString(DateTime.TAI), "TIMESYS": "TAI"}) 

377 visitInfo = afwImage.VisitInfo(metadata) 

378 self.assertEqual(visitInfo.getDate(), data.date) 

379 

380 # TIME-MID in UTC is an acceptable alternative to DATE-AVG 

381 metadata = propertySetFromDict( 

382 {"TIME-MID": data.date.toString(DateTime.UTC)}) 

383 visitInfo = afwImage.VisitInfo(metadata) 

384 self.assertEqual(visitInfo.getDate(), data.date) 

385 

386 # TIME-MID must be in UTC and TIMESYS is ignored 

387 metadata = propertySetFromDict({ 

388 "TIME-MID": data.date.toString(DateTime.TAI) + "Z", 

389 "TIMESYS": "TAI", 

390 }) 

391 visitInfo = afwImage.VisitInfo(metadata) 

392 self.assertNotEqual(visitInfo.getDate(), data.date) 

393 

394 # if both DATE-AVG and TIME-MID provided then use DATE-AVG 

395 # use the wrong time system for TIME-MID so if it is used, an error 

396 # will result 

397 metadata = propertySetFromDict({ 

398 "DATE-AVG": data.date.toString(DateTime.TAI), 

399 "TIMESYS": "TAI", 

400 "TIME-MID": data.date.toString(DateTime.TAI) + "Z", 

401 }) 

402 visitInfo = afwImage.VisitInfo(metadata) 

403 self.assertEqual(visitInfo.getDate(), data.date) 

404 

405 metadata = propertySetFromDict({"MJD-AVG-UT1": data.ut1}) 

406 visitInfo = afwImage.VisitInfo(metadata) 

407 self.assertEqual(visitInfo.getUt1(), data.ut1) 

408 

409 metadata = propertySetFromDict({"AVG-ERA": data.era.asDegrees()}) 

410 visitInfo = afwImage.VisitInfo(metadata) 

411 self.assertEqual(visitInfo.getEra(), data.era) 

412 

413 for i, key in enumerate(("BORE-RA", "BORE-DEC")): 

414 metadata = propertySetFromDict( 

415 {key: data.boresightRaDec[i].asDegrees()}) 

416 visitInfo = afwImage.VisitInfo(metadata) 

417 self.assertEqual(visitInfo.getBoresightRaDec() 

418 [i], data.boresightRaDec[i]) 

419 

420 for i, key in enumerate(("BORE-AZ", "BORE-ALT")): 

421 metadata = propertySetFromDict( 

422 {key: data.boresightAzAlt[i].asDegrees()}) 

423 visitInfo = afwImage.VisitInfo(metadata) 

424 self.assertEqual(visitInfo.getBoresightAzAlt() 

425 [i], data.boresightAzAlt[i]) 

426 

427 metadata = propertySetFromDict({"BORE-AIRMASS": data.boresightAirmass}) 

428 visitInfo = afwImage.VisitInfo(metadata) 

429 self.assertEqual(visitInfo.getBoresightAirmass(), 

430 data.boresightAirmass) 

431 

432 metadata = propertySetFromDict( 

433 {"BORE-ROTANG": data.boresightRotAngle.asDegrees()}) 

434 visitInfo = afwImage.VisitInfo(metadata) 

435 self.assertEqual(visitInfo.getBoresightRotAngle(), 

436 data.boresightRotAngle) 

437 

438 metadata = propertySetFromDict( 

439 {"ROTTYPE": RotTypeEnumNameDict[data.rotType]}) 

440 visitInfo = afwImage.VisitInfo(metadata) 

441 self.assertEqual(visitInfo.getRotType(), data.rotType) 

442 

443 metadata = propertySetFromDict( 

444 {"OBS-LONG": data.observatory.getLongitude().asDegrees()}) 

445 visitInfo = afwImage.VisitInfo(metadata) 

446 self.assertEqual(visitInfo.getObservatory().getLongitude(), 

447 data.observatory.getLongitude()) 

448 

449 metadata = propertySetFromDict( 

450 {"OBS-LAT": data.observatory.getLatitude().asDegrees()}) 

451 visitInfo = afwImage.VisitInfo(metadata) 

452 self.assertEqual(visitInfo.getObservatory().getLatitude(), 

453 data.observatory.getLatitude()) 

454 

455 metadata = propertySetFromDict( 

456 {"OBS-ELEV": data.observatory.getElevation()}) 

457 visitInfo = afwImage.VisitInfo(metadata) 

458 self.assertEqual(visitInfo.getObservatory().getElevation(), 

459 data.observatory.getElevation()) 

460 

461 metadata = propertySetFromDict( 

462 {"AIRTEMP": data.weather.getAirTemperature()}) 

463 visitInfo = afwImage.VisitInfo(metadata) 

464 self.assertEqual(visitInfo.getWeather().getAirTemperature(), 

465 data.weather.getAirTemperature()) 

466 

467 metadata = propertySetFromDict( 

468 {"AIRPRESS": data.weather.getAirPressure()}) 

469 visitInfo = afwImage.VisitInfo(metadata) 

470 self.assertEqual(visitInfo.getWeather().getAirPressure(), 

471 data.weather.getAirPressure()) 

472 

473 metadata = propertySetFromDict( 

474 {"HUMIDITY": data.weather.getHumidity()}) 

475 visitInfo = afwImage.VisitInfo(metadata) 

476 self.assertEqual(visitInfo.getWeather().getHumidity(), 

477 data.weather.getHumidity()) 

478 

479 metadata = propertySetFromDict({"INSTRUMENT": data.instrumentLabel}) 

480 visitInfo = afwImage.VisitInfo(metadata) 

481 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel) 

482 

483 metadata = propertySetFromDict({"IDNUM": data.id}) 

484 visitInfo = afwImage.VisitInfo(metadata) 

485 self.assertEqual(visitInfo.getId(), data.id) 

486 

487 def testConstructorKeywordArguments(self): 

488 """Test VisitInfo with named arguments""" 

489 data = self.data1 

490 

491 visitInfo = afwImage.VisitInfo() 

492 self._testIsEmpty(visitInfo) 

493 

494 visitInfo = afwImage.VisitInfo(exposureId=data.exposureId) 

495 self.assertEqual(visitInfo.getExposureId(), data.exposureId) 

496 self.assertTrue(math.isnan(visitInfo.getExposureTime())) 

497 

498 visitInfo = afwImage.VisitInfo(exposureTime=data.exposureTime) 

499 self.assertEqual(visitInfo.getExposureTime(), data.exposureTime) 

500 

501 visitInfo = afwImage.VisitInfo(darkTime=data.darkTime) 

502 self.assertEqual(visitInfo.getDarkTime(), data.darkTime) 

503 

504 visitInfo = afwImage.VisitInfo(date=data.date) 

505 self.assertEqual(visitInfo.getDate(), data.date) 

506 

507 visitInfo = afwImage.VisitInfo(ut1=data.ut1) 

508 self.assertEqual(visitInfo.getUt1(), data.ut1) 

509 

510 visitInfo = afwImage.VisitInfo(era=data.era) 

511 self.assertEqual(visitInfo.getEra(), data.era) 

512 

513 visitInfo = afwImage.VisitInfo(boresightRaDec=data.boresightRaDec) 

514 self.assertEqual(visitInfo.getBoresightRaDec(), data.boresightRaDec) 

515 

516 visitInfo = afwImage.VisitInfo(boresightAzAlt=data.boresightAzAlt) 

517 self.assertEqual(visitInfo.getBoresightAzAlt(), data.boresightAzAlt) 

518 

519 visitInfo = afwImage.VisitInfo(boresightAirmass=data.boresightAirmass) 

520 self.assertEqual(visitInfo.getBoresightAirmass(), 

521 data.boresightAirmass) 

522 

523 visitInfo = afwImage.VisitInfo( 

524 boresightRotAngle=data.boresightRotAngle) 

525 self.assertEqual(visitInfo.getBoresightRotAngle(), 

526 data.boresightRotAngle) 

527 

528 visitInfo = afwImage.VisitInfo(rotType=data.rotType) 

529 self.assertEqual(visitInfo.getRotType(), data.rotType) 

530 

531 visitInfo = afwImage.VisitInfo(observatory=data.observatory) 

532 self.assertEqual(visitInfo.getObservatory(), data.observatory) 

533 

534 visitInfo = afwImage.VisitInfo(weather=data.weather) 

535 self.assertEqual(visitInfo.getWeather(), data.weather) 

536 

537 visitInfo = afwImage.VisitInfo(instrumentLabel=data.instrumentLabel) 

538 self.assertEqual(visitInfo.getInstrumentLabel(), data.instrumentLabel) 

539 

540 visitInfo = afwImage.VisitInfo(id=data.id) 

541 self.assertEqual(visitInfo.getId(), data.id) 

542 

543 def testGoodRotTypes(self): 

544 """Test round trip of all valid rot types""" 

545 for rotType in RotTypeEnumNameDict: 

546 metadata = propertySetFromDict( 

547 {"ROTTYPE": RotTypeEnumNameDict[rotType]}) 

548 visitInfo = afwImage.VisitInfo(metadata) 

549 self.assertEqual(visitInfo.getRotType(), rotType) 

550 

551 def testBadRotTypes(self): 

552 """Test that invalid rot type names cannot be used to construct a VisitInfo""" 

553 for badRotTypeName in ( 

554 "unknown", # must be all uppercase 

555 "sky", # must be all uppercase 

556 "Sky", # must be all uppercase 

557 "SKY1", # extra chars 

558 "HORIZONTAL", # extra chars 

559 ): 

560 metadata = propertySetFromDict({"ROTTYPE": badRotTypeName}) 

561 with self.assertRaises(lsst.pex.exceptions.RuntimeError): 

562 afwImage.VisitInfo(metadata) 

563 

564 def test_str(self): 

565 """Check that we get something reasonable for str()""" 

566 visitInfo = makeVisitInfo(self.data1) 

567 string = str(visitInfo) 

568 self.assertIn("exposureId=10313423", string) 

569 self.assertIn("exposureTime=10.01", string) 

570 self.assertIn("darkTime=11.02", string) 

571 self.assertIn("rotType=1", string) 

572 

573 def testParallacticAngle(self): 

574 """Check that we get the same precomputed values for parallactic angle.""" 

575 parallacticAngle = [141.39684140703142*degrees, 76.99982166973487*degrees] 

576 for item, parAngle in zip((self.data1, self.data2), parallacticAngle): 

577 visitInfo = afwImage.VisitInfo(era=item.era, 

578 boresightRaDec=item.boresightRaDec, 

579 observatory=item.observatory, 

580 ) 

581 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), parAngle) 

582 

583 def testParallacticAngleNorthMeridian(self): 

584 """An observation on the Meridian that is North of zenith has a parallactic angle of pi radians.""" 

585 meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude() 

586 northBoresightDec = self.data1.observatory.getLatitude() + 10.*degrees 

587 visitInfo = afwImage.VisitInfo(era=self.data1.era, 

588 boresightRaDec=SpherePoint(meridianBoresightRA, 

589 northBoresightDec), 

590 observatory=self.data1.observatory, 

591 ) 

592 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), Angle(np.pi)) 

593 

594 def testParallacticAngleSouthMeridian(self): 

595 """An observation on the Meridian that is South of zenith has a parallactic angle of zero.""" 

596 meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude() 

597 southBoresightDec = self.data1.observatory.getLatitude() - 10.*degrees 

598 visitInfo = afwImage.VisitInfo(era=self.data1.era, 

599 boresightRaDec=SpherePoint(meridianBoresightRA, 

600 southBoresightDec), 

601 observatory=self.data1.observatory, 

602 ) 

603 self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), Angle(0.)) 

604 

605 

606def setup_module(module): 

607 lsst.utils.tests.init() 

608 

609 

610class MemoryTester(lsst.utils.tests.MemoryTestCase): 

611 pass 

612 

613 

614if __name__ == "__main__": 614 ↛ 615line 614 didn't jump to line 615, because the condition on line 614 was never true

615 lsst.utils.tests.init() 

616 unittest.main()