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

1from __future__ import division 

2from builtins import zip 

3from builtins import range 

4import numpy as np 

5import unittest 

6import lsst.utils.tests 

7 

8from lsst.sims.utils import ObservationMetaData, _nativeLonLatFromRaDec 

9from lsst.sims.utils import _pupilCoordsFromRaDec, pupilCoordsFromRaDec 

10from lsst.sims.utils import _raDecFromPupilCoords 

11from lsst.sims.utils import _observedFromICRS, _icrsFromObserved 

12from lsst.sims.utils import haversine, arcsecFromRadians, solarRaDec, ModifiedJulianDate, distanceToSun 

13from lsst.sims.utils import raDecFromAltAz, observedFromICRS, icrsFromObserved 

14from lsst.sims.utils import radiansFromArcsec 

15from lsst.sims.utils import _observedFromPupilCoords 

16from lsst.sims.utils import observedFromPupilCoords 

17 

18 

19def setup_module(module): 

20 lsst.utils.tests.init() 

21 

22 

23class PupilCoordinateUnitTest(unittest.TestCase): 

24 

25 longMessage = True 

26 

27 def testExceptions(self): 

28 """ 

29 Test that exceptions are raised when they ought to be 

30 """ 

31 obs_metadata = ObservationMetaData(pointingRA=25.0, 

32 pointingDec=25.0, 

33 rotSkyPos=25.0, 

34 mjd=52000.0) 

35 

36 rng = np.random.RandomState(42) 

37 ra = rng.random_sample(10) * np.radians(1.0) + np.radians(obs_metadata.pointingRA) 

38 dec = rng.random_sample(10) * np.radians(1.0) + np.radians(obs_metadata.pointingDec) 

39 raShort = np.array([1.0]) 

40 decShort = np.array([1.0]) 

41 

42 # test without obs_metadata 

43 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec, 

44 epoch=2000.0) 

45 

46 # test without pointingRA 

47 dummy = ObservationMetaData(pointingDec=obs_metadata.pointingDec, 

48 rotSkyPos=obs_metadata.rotSkyPos, 

49 mjd=obs_metadata.mjd) 

50 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec, 

51 epoch=2000.0, obs_metadata=dummy) 

52 

53 # test without pointingDec 

54 dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA, 

55 rotSkyPos=obs_metadata.rotSkyPos, 

56 mjd=obs_metadata.mjd) 

57 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec, 

58 epoch=2000.0, obs_metadata=dummy) 

59 

60 # test without rotSkyPos 

61 dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA, 

62 pointingDec=obs_metadata.pointingDec, 

63 mjd=obs_metadata.mjd) 

64 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec, 

65 epoch=2000.0, obs_metadata=dummy) 

66 

67 # test without mjd 

68 dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA, 

69 pointingDec=obs_metadata.pointingDec, 

70 rotSkyPos=obs_metadata.rotSkyPos) 

71 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec, 

72 epoch=2000.0, obs_metadata=dummy) 

73 

74 # test for mismatches 

75 dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA, 

76 pointingDec=obs_metadata.pointingDec, 

77 rotSkyPos=obs_metadata.rotSkyPos, 

78 mjd=obs_metadata.mjd) 

79 

80 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, decShort, epoch=2000.0, 

81 obs_metadata=dummy) 

82 

83 self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, raShort, dec, epoch=2000.0, 

84 obs_metadata=dummy) 

85 

86 # test that it actually runs (and that passing in either numpy arrays or floats gives 

87 # the same results) 

88 xx_arr, yy_arr = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata) 

89 self.assertIsInstance(xx_arr, np.ndarray) 

90 self.assertIsInstance(yy_arr, np.ndarray) 

91 

92 for ix in range(len(ra)): 

93 xx_f, yy_f = _pupilCoordsFromRaDec(ra[ix], dec[ix], obs_metadata=obs_metadata) 

94 self.assertIsInstance(xx_f, np.float) 

95 self.assertIsInstance(yy_f, np.float) 

96 self.assertAlmostEqual(xx_arr[ix], xx_f, 12) 

97 self.assertAlmostEqual(yy_arr[ix], yy_f, 12) 

98 self.assertFalse(np.isnan(xx_f)) 

99 self.assertFalse(np.isnan(yy_f)) 

100 

101 def testCardinalDirections(self): 

102 """ 

103 This unit test verifies that the following conventions hold: 

104 

105 if rotSkyPos = 0, then north is +y the camera and east is +x 

106 

107 if rotSkyPos = -90, then north is -x on the camera and east is +y 

108 

109 if rotSkyPos = 90, then north is +x on the camera and east is -y 

110 

111 if rotSkyPos = 180, then north is -y on the camera and east is -x 

112 

113 This is consistent with rotSkyPos = rotTelPos - parallacticAngle 

114 

115 parallacticAngle is negative when the pointing is east of the meridian. 

116 http://www.petermeadows.com/html/parallactic.html 

117 

118 rotTelPos is the angle between up on the telescope and up on 

119 the camera, where positive rotTelPos goes from north to west 

120 (from an email sent to me by LynneJones) 

121 

122 I have verified that OpSim follows the rotSkyPos = rotTelPos - paralacticAngle 

123 convention. 

124 

125 I have verified that altAzPaFromRaDec follows the convention that objects 

126 east of the meridian have a negative parallactic angle. (altAzPaFromRaDec 

127 uses PALPY under the hood, so it can probably be taken as correct) 

128 

129 It will verify this convention for multiple random pointings. 

130 """ 

131 

132 epoch = 2000.0 

133 mjd = 42350.0 

134 rng = np.random.RandomState(42) 

135 raList = rng.random_sample(10) * 360.0 

136 decList = rng.random_sample(10) * 180.0 - 90.0 

137 

138 for rotSkyPos in np.arange(-90.0, 181.0, 90.0): 

139 for ra, dec in zip(raList, decList): 

140 obs = ObservationMetaData(pointingRA=ra, 

141 pointingDec=dec, 

142 mjd=mjd, 

143 rotSkyPos=rotSkyPos) 

144 

145 ra_obs, dec_obs = _observedFromICRS(np.radians([ra]), np.radians([dec]), 

146 obs_metadata=obs, epoch=2000.0, 

147 includeRefraction=True) 

148 

149 # test points that are displaced just to the (E, W, N, S) of the pointing 

150 # in observed geocentric RA, Dec; verify that the pupil coordinates 

151 # change as expected 

152 raTest_obs = ra_obs[0] + np.array([0.01, -0.01, 0.0, 0.0]) 

153 decTest_obs = dec_obs[0] + np.array([0.0, 0.0, 0.01, -0.01]) 

154 raTest, decTest = _icrsFromObserved(raTest_obs, decTest_obs, obs_metadata=obs, 

155 epoch=2000.0, includeRefraction=True) 

156 

157 x, y = _pupilCoordsFromRaDec(raTest, decTest, obs_metadata=obs, epoch=epoch) 

158 

159 lon, lat = _nativeLonLatFromRaDec(raTest, decTest, obs) 

160 rr = np.abs(np.cos(lat) / np.sin(lat)) 

161 

162 if np.abs(rotSkyPos) < 0.01: # rotSkyPos == 0 

163 control_x = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0]) 

164 control_y = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]]) 

165 elif np.abs(rotSkyPos + 90.0) < 0.01: # rotSkyPos == -90 

166 control_x = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]]) 

167 control_y = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0]) 

168 elif np.abs(rotSkyPos - 90.0) < 0.01: # rotSkyPos == 90 

169 control_x = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]]) 

170 control_y = np.array([-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0]) 

171 elif np.abs(rotSkyPos - 180.0) < 0.01: # rotSkyPos == 180 

172 control_x = np.array([-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0]) 

173 control_y = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]]) 

174 

175 msg = 'failed on rotSkyPos == %e\n' % rotSkyPos 

176 msg += 'control_x %s\n' % str(control_x) 

177 msg += 'test_x %s\n' % str(x) 

178 msg += 'control_y %s\n' % str(control_y) 

179 msg += 'test_y %s\n' % str(y) 

180 

181 dx = np.array([xx / cc if np.abs(cc) > 1.0e-10 else 1.0 - xx for xx, cc in zip(x, control_x)]) 

182 dy = np.array([yy / cc if np.abs(cc) > 1.0e-10 else 1.0 - yy for yy, cc in zip(y, control_y)]) 

183 self.assertLess(np.abs(dx-np.ones(4)).max(), 0.001, msg=msg) 

184 self.assertLess(np.abs(dy-np.ones(4)).max(), 0.001, msg=msg) 

185 

186 def testRaDecFromPupil(self): 

187 """ 

188 Test conversion from pupil coordinates back to Ra, Dec 

189 """ 

190 

191 mjd = ModifiedJulianDate(TAI=52000.0) 

192 solarRA, solarDec = solarRaDec(mjd) 

193 

194 # to make sure that we are more than 45 degrees from the Sun as required 

195 # for _icrsFromObserved to be at all accurate 

196 raCenter = solarRA + 100.0 

197 decCenter = solarDec - 30.0 

198 

199 obs = ObservationMetaData(pointingRA=raCenter, 

200 pointingDec=decCenter, 

201 boundType='circle', 

202 boundLength=0.1, 

203 rotSkyPos=23.0, 

204 mjd=mjd) 

205 

206 nSamples = 1000 

207 rng = np.random.RandomState(42) 

208 ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter) 

209 dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter) 

210 xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0) 

211 

212 raTest, decTest = _raDecFromPupilCoords( 

213 xp, yp, obs_metadata=obs, epoch=2000.0) 

214 

215 distance = arcsecFromRadians(haversine(ra, dec, raTest, decTest)) 

216 

217 dex = np.argmax(distance) 

218 

219 worstSolarDistance = distanceToSun( 

220 np.degrees(ra[dex]), np.degrees(dec[dex]), mjd) 

221 

222 msg = "_raDecFromPupilCoords off by %e arcsec at distance to Sun of %e degrees" % \ 

223 (distance.max(), worstSolarDistance) 

224 

225 self.assertLess(distance.max(), 1.0e-6, msg=msg) 

226 

227 # now check that passing in the xp, yp values one at a time still gives 

228 # the right answer 

229 for ix in range(len(ra)): 

230 ra_f, dec_f = _raDecFromPupilCoords(xp[ix], yp[ix], obs_metadata=obs, epoch=2000.0) 

231 self.assertIsInstance(ra_f, np.float) 

232 self.assertIsInstance(dec_f, np.float) 

233 dist_f = arcsecFromRadians(haversine(ra_f, dec_f, raTest[ix], decTest[ix])) 

234 self.assertLess(dist_f, 1.0e-9) 

235 

236 def testRaDecFromPupil_noRefraction(self): 

237 """ 

238 Test conversion from pupil coordinates back to Ra, Dec 

239 with includeRefraction=False 

240 """ 

241 

242 mjd = ModifiedJulianDate(TAI=52000.0) 

243 solarRA, solarDec = solarRaDec(mjd) 

244 

245 # to make sure that we are more than 45 degrees from the Sun as required 

246 # for _icrsFromObserved to be at all accurate 

247 raCenter = solarRA + 100.0 

248 decCenter = solarDec - 30.0 

249 

250 obs = ObservationMetaData(pointingRA=raCenter, 

251 pointingDec=decCenter, 

252 boundType='circle', 

253 boundLength=0.1, 

254 rotSkyPos=23.0, 

255 mjd=mjd) 

256 

257 nSamples = 1000 

258 rng = np.random.RandomState(42) 

259 ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter) 

260 dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter) 

261 xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0, 

262 includeRefraction=False) 

263 

264 raTest, decTest = _raDecFromPupilCoords( 

265 xp, yp, obs_metadata=obs, epoch=2000.0, 

266 includeRefraction=False) 

267 

268 distance = arcsecFromRadians(haversine(ra, dec, raTest, decTest)) 

269 

270 dex = np.argmax(distance) 

271 

272 worstSolarDistance = distanceToSun( 

273 np.degrees(ra[dex]), np.degrees(dec[dex]), mjd) 

274 

275 msg = "_raDecFromPupilCoords off by %e arcsec at distance to Sun of %e degrees" % \ 

276 (distance.max(), worstSolarDistance) 

277 

278 self.assertLess(distance.max(), 1.0e-6, msg=msg) 

279 

280 # now check that passing in the xp, yp values one at a time still gives 

281 # the right answer 

282 for ix in range(len(ra)): 

283 ra_f, dec_f = _raDecFromPupilCoords(xp[ix], yp[ix], obs_metadata=obs, epoch=2000.0, 

284 includeRefraction=False) 

285 self.assertIsInstance(ra_f, np.float) 

286 self.assertIsInstance(dec_f, np.float) 

287 dist_f = arcsecFromRadians(haversine(ra_f, dec_f, raTest[ix], decTest[ix])) 

288 self.assertLess(dist_f, 1.0e-9) 

289 

290 def testObservedFromPupil(self): 

291 """ 

292 Test conversion from pupil coordinates to observed coordinates 

293 """ 

294 

295 mjd = ModifiedJulianDate(TAI=53000.0) 

296 solarRA, solarDec = solarRaDec(mjd) 

297 

298 # to make sure that we are more than 45 degrees from the Sun as required 

299 # for _icrsFromObserved to be at all accurate 

300 raCenter = solarRA + 100.0 

301 decCenter = solarDec - 30.0 

302 

303 obs = ObservationMetaData(pointingRA=raCenter, 

304 pointingDec=decCenter, 

305 boundType='circle', 

306 boundLength=0.1, 

307 rotSkyPos=23.0, 

308 mjd=mjd) 

309 

310 nSamples = 1000 

311 rng = np.random.RandomState(4453) 

312 ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter) 

313 dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter) 

314 xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0, 

315 includeRefraction=True) 

316 

317 raObs, decObs = _observedFromICRS(ra, dec, obs_metadata=obs, epoch=2000.0, 

318 includeRefraction=True) 

319 

320 raObs_test, decObs_test = _observedFromPupilCoords(xp, yp, obs_metadata=obs, 

321 epoch=2000.0, 

322 includeRefraction=True) 

323 

324 dist = arcsecFromRadians(haversine(raObs, decObs, raObs_test, decObs_test)) 

325 self.assertLess(dist.max(), 1.0e-6) 

326 

327 # test output in degrees 

328 raObs_deg, decObs_deg = observedFromPupilCoords(xp, yp, obs_metadata=obs, 

329 epoch=2000.0, 

330 includeRefraction=True) 

331 

332 np.testing.assert_array_almost_equal(raObs_deg, np.degrees(raObs_test), decimal=16) 

333 np.testing.assert_array_almost_equal(decObs_deg, np.degrees(decObs_test), decimal=16) 

334 

335 # test one-at-a-time input 

336 for ii in range(len(raObs)): 

337 rr, dd = _observedFromPupilCoords(xp[ii], yp[ii], 

338 obs_metadata=obs, 

339 epoch=2000.0, 

340 includeRefraction=True) 

341 self.assertAlmostEqual(rr, raObs_test[ii], 16) 

342 self.assertAlmostEqual(dd, decObs_test[ii], 16) 

343 

344 rr, dd = observedFromPupilCoords(xp[ii], yp[ii], 

345 obs_metadata=obs, 

346 epoch=2000.0, 

347 includeRefraction=True) 

348 self.assertAlmostEqual(rr, raObs_deg[ii], 16) 

349 self.assertAlmostEqual(dd, decObs_deg[ii], 16) 

350 

351 def testObservedFromPupil_noRefraction(self): 

352 """ 

353 Test conversion from pupil coordinates to observed coordinates 

354 when includeRefraction=False 

355 """ 

356 

357 mjd = ModifiedJulianDate(TAI=53000.0) 

358 solarRA, solarDec = solarRaDec(mjd) 

359 

360 # to make sure that we are more than 45 degrees from the Sun as required 

361 # for _icrsFromObserved to be at all accurate 

362 raCenter = solarRA + 100.0 

363 decCenter = solarDec - 30.0 

364 

365 obs = ObservationMetaData(pointingRA=raCenter, 

366 pointingDec=decCenter, 

367 boundType='circle', 

368 boundLength=0.1, 

369 rotSkyPos=23.0, 

370 mjd=mjd) 

371 

372 nSamples = 1000 

373 rng = np.random.RandomState(4453) 

374 ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter) 

375 dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter) 

376 xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0, 

377 includeRefraction=False) 

378 

379 raObs, decObs = _observedFromICRS(ra, dec, obs_metadata=obs, epoch=2000.0, 

380 includeRefraction=False) 

381 

382 raObs_test, decObs_test = _observedFromPupilCoords(xp, yp, obs_metadata=obs, 

383 epoch=2000.0, 

384 includeRefraction=False) 

385 

386 dist = arcsecFromRadians(haversine(raObs, decObs, raObs_test, decObs_test)) 

387 self.assertLess(dist.max(), 1.0e-6) 

388 

389 # test output in degrees 

390 raObs_deg, decObs_deg = observedFromPupilCoords(xp, yp, obs_metadata=obs, 

391 epoch=2000.0, 

392 includeRefraction=False) 

393 

394 np.testing.assert_array_almost_equal(raObs_deg, np.degrees(raObs_test), decimal=16) 

395 np.testing.assert_array_almost_equal(decObs_deg, np.degrees(decObs_test), decimal=16) 

396 

397 # test one-at-a-time input 

398 for ii in range(len(raObs)): 

399 rr, dd = _observedFromPupilCoords(xp[ii], yp[ii], 

400 obs_metadata=obs, 

401 epoch=2000.0, 

402 includeRefraction=False) 

403 self.assertAlmostEqual(rr, raObs_test[ii], 16) 

404 self.assertAlmostEqual(dd, decObs_test[ii], 16) 

405 

406 rr, dd = observedFromPupilCoords(xp[ii], yp[ii], 

407 obs_metadata=obs, 

408 epoch=2000.0, 

409 includeRefraction=False) 

410 self.assertAlmostEqual(rr, raObs_deg[ii], 16) 

411 self.assertAlmostEqual(dd, decObs_deg[ii], 16) 

412 

413 def testNaNs(self): 

414 """ 

415 Test how _pupilCoordsFromRaDec handles improper values 

416 """ 

417 obs = ObservationMetaData(pointingRA=42.0, pointingDec=-28.0, 

418 rotSkyPos=111.0, mjd=42356.0) 

419 nSamples = 100 

420 rng = np.random.RandomState(42) 

421 raList = np.radians(rng.random_sample(nSamples) * 2.0 + 42.0) 

422 decList = np.radians(rng.random_sample(nSamples) * 2.0 - 28.0) 

423 

424 xControl, yControl = _pupilCoordsFromRaDec(raList, decList, 

425 obs_metadata=obs, 

426 epoch=2000.0) 

427 

428 raList[5] = np.NaN 

429 decList[5] = np.NaN 

430 raList[15] = np.NaN 

431 decList[20] = np.NaN 

432 raList[30] = np.radians(42.0) + np.pi 

433 

434 xTest, yTest = _pupilCoordsFromRaDec(raList, decList, 

435 obs_metadata=obs, 

436 epoch=2000.0) 

437 

438 for ix, (xc, yc, xt, yt) in \ 

439 enumerate(zip(xControl, yControl, xTest, yTest)): 

440 if ix != 5 and ix != 15 and ix != 20 and ix != 30: 

441 self.assertAlmostEqual(xc, xt, 10) 

442 self.assertAlmostEqual(yc, yt, 10) 

443 self.assertFalse(np.isnan(xt)) 

444 self.assertFalse(np.isnan(yt)) 

445 else: 

446 np.testing.assert_equal(xt, np.NaN) 

447 np.testing.assert_equal(yt, np.NaN) 

448 

449 def test_with_proper_motion(self): 

450 """ 

451 Test that calculating pupil coordinates in the presence of proper motion, parallax, 

452 and radial velocity is equivalent to 

453 observedFromICRS -> icrsFromObserved -> pupilCoordsFromRaDec 

454 (mostly to make surethat pupilCoordsFromRaDec is correctly calling observedFromICRS 

455 with non-zero proper motion, etc.) 

456 """ 

457 rng = np.random.RandomState(38442) 

458 is_valid = False 

459 while not is_valid: 

460 mjd_tai = 59580.0 + 10000.0*rng.random_sample() 

461 obs = ObservationMetaData(mjd=mjd_tai) 

462 ra, dec = raDecFromAltAz(78.0, 112.0, obs) 

463 dd = distanceToSun(ra, dec, obs.mjd) 

464 if dd > 45.0: 

465 is_valid = True 

466 

467 n_obj = 1000 

468 rr = rng.random_sample(n_obj)*2.0 

469 theta = rng.random_sample(n_obj)*2.0*np.pi 

470 ra_list = ra + rr*np.cos(theta) 

471 dec_list = dec + rr*np.sin(theta) 

472 obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, mjd=mjd_tai, rotSkyPos=19.0) 

473 

474 pm_ra_list = rng.random_sample(n_obj)*100.0 - 50.0 

475 pm_dec_list = rng.random_sample(n_obj)*100.0 - 50.0 

476 px_list = rng.random_sample(n_obj) + 0.05 

477 v_rad_list = rng.random_sample(n_obj)*600.0 - 300.0 

478 

479 for includeRefraction in (True, False): 

480 

481 ra_obs, dec_obs = observedFromICRS(ra_list, dec_list, 

482 pm_ra=pm_ra_list, pm_dec=pm_dec_list, 

483 parallax=px_list, v_rad=v_rad_list, 

484 obs_metadata=obs, epoch=2000.0, 

485 includeRefraction=includeRefraction) 

486 

487 ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs, 

488 epoch=2000.0, includeRefraction=includeRefraction) 

489 

490 xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs, 

491 epoch=2000.0, includeRefraction=includeRefraction) 

492 

493 xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list, 

494 pm_ra=pm_ra_list, pm_dec=pm_dec_list, 

495 parallax=px_list, v_rad=v_rad_list, 

496 obs_metadata=obs, epoch=2000.0, 

497 includeRefraction=includeRefraction) 

498 

499 distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) + 

500 np.power(yp_test-yp_control, 2))) 

501 self.assertLess(distance.max(), 0.006) 

502 

503 # now test it in radians 

504 xp_rad, yp_rad = _pupilCoordsFromRaDec(np.radians(ra_list), np.radians(dec_list), 

505 pm_ra=radiansFromArcsec(pm_ra_list), 

506 pm_dec=radiansFromArcsec(pm_dec_list), 

507 parallax=radiansFromArcsec(px_list), 

508 v_rad=v_rad_list, 

509 obs_metadata=obs, epoch=2000.0, 

510 includeRefraction=includeRefraction) 

511 

512 np.testing.assert_array_equal(xp_rad, xp_test) 

513 np.testing.assert_array_equal(yp_rad, yp_test) 

514 

515 # now test it with proper motion = 0 

516 ra_obs, dec_obs = observedFromICRS(ra_list, dec_list, 

517 parallax=px_list, v_rad=v_rad_list, 

518 obs_metadata=obs, epoch=2000.0, 

519 includeRefraction=includeRefraction) 

520 

521 ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs, 

522 epoch=2000.0, includeRefraction=includeRefraction) 

523 

524 xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs, 

525 epoch=2000.0, includeRefraction=includeRefraction) 

526 

527 xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list, 

528 parallax=px_list, v_rad=v_rad_list, 

529 obs_metadata=obs, epoch=2000.0, 

530 includeRefraction=includeRefraction) 

531 

532 distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) + 

533 np.power(yp_test-yp_control, 2))) 

534 self.assertLess(distance.max(), 1.0e-6) 

535 

536 

537class MemoryTestClass(lsst.utils.tests.MemoryTestCase): 

538 pass 

539 

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

541 lsst.utils.tests.init() 

542 unittest.main()