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

1import unittest 

2import os 

3import numpy as np 

4import numbers 

5import lsst.utils.tests 

6 

7from lsst.utils import getPackageDir 

8from lsst.afw.cameraGeom import PIXELS, FOCAL_PLANE 

9from lsst.afw.cameraGeom import DetectorType 

10import lsst.geom as geom 

11from lsst.sims.coordUtils import lsst_camera 

12from lsst.sims.coordUtils import focalPlaneCoordsFromPupilCoordsLSST 

13from lsst.sims.coordUtils import focalPlaneCoordsFromPupilCoords 

14from lsst.sims.coordUtils import pupilCoordsFromFocalPlaneCoordsLSST 

15from lsst.sims.coordUtils import DMtoCameraPixelTransformer 

16from lsst.sims.utils import ObservationMetaData 

17from lsst.sims.utils import pupilCoordsFromRaDec 

18from lsst.sims.utils import radiansFromArcsec 

19from lsst.sims.utils import angularSeparation 

20from lsst.sims.coordUtils import chipNameFromPupilCoordsLSST 

21from lsst.sims.coordUtils import chipNameFromRaDecLSST 

22from lsst.sims.coordUtils import _chipNameFromRaDecLSST 

23from lsst.sims.coordUtils import pixelCoordsFromRaDecLSST 

24from lsst.sims.coordUtils import _pixelCoordsFromRaDecLSST 

25from lsst.sims.coordUtils import pixelCoordsFromRaDec 

26from lsst.sims.coordUtils import pixelCoordsFromPupilCoordsLSST 

27from lsst.sims.coordUtils import pupilCoordsFromPixelCoordsLSST 

28from lsst.sims.coordUtils import raDecFromPixelCoordsLSST 

29from lsst.sims.coordUtils import _raDecFromPixelCoordsLSST 

30from lsst.sims.coordUtils.LsstZernikeFitter import _rawPupilCoordsFromObserved 

31 

32from lsst.sims.coordUtils import clean_up_lsst_camera 

33 

34def setup_module(module): 

35 lsst.utils.tests.init() 

36 

37 

38class FocalPlaneTestCase(unittest.TestCase): 

39 

40 @classmethod 

41 def setUpClass(cls): 

42 pix_transformer = DMtoCameraPixelTransformer() 

43 data_dir = os.path.join(getPackageDir('sims_data'), 

44 'FocalPlaneData', 

45 'UnitTestData') 

46 

47 cls._data_dir = data_dir 

48 

49 phosim_dtype = np.dtype([('id', int), ('phot', int), 

50 ('xpix', float), ('ypix', float)]) 

51 

52 camera = lsst_camera() 

53 cls._phosim_positions = {} 

54 for i_band in range(6): 

55 id_arr = None 

56 x_arr = None 

57 y_arr = None 

58 for det in camera: 

59 if det.getType() != DetectorType.SCIENCE: 

60 continue 

61 det_name = det.getName() 

62 name = det_name.replace(':','').replace(',','') 

63 name = name.replace(' ','_') 

64 file_name = 'centroid_lsst_e_2_f%d_%s_E000.txt' % (i_band, name) 

65 data = np.genfromtxt(os.path.join(data_dir, 'PhoSimData', 

66 file_name), 

67 dtype=phosim_dtype, 

68 skip_header=1) 

69 dm_x, dm_y = pix_transformer.dmPixFromCameraPix(data['xpix'], 

70 data['ypix'], 

71 det_name) 

72 pix_to_focal = det.getTransform(PIXELS, FOCAL_PLANE) 

73 x_mm = np.zeros(len(dm_x)) 

74 y_mm = np.zeros(len(dm_y)) 

75 for ii in range(len(x_mm)): 

76 pix_pt = geom.Point2D(dm_x[ii], dm_y[ii]) 

77 focal_pt = pix_to_focal.applyForward(pix_pt) 

78 x_mm[ii] = focal_pt.getX() 

79 y_mm[ii] = focal_pt.getY() 

80 

81 if id_arr is None: 

82 id_arr = data['id'] 

83 x_arr = x_mm 

84 y_arr = y_mm 

85 else: 

86 id_arr = np.append(id_arr, data['id']) 

87 x_arr = np.append(x_arr, x_mm) 

88 y_arr = np.append(y_arr, y_mm) 

89 

90 sorted_dex = np.argsort(id_arr) 

91 id_arr = id_arr[sorted_dex] 

92 x_arr = x_arr[sorted_dex] 

93 y_arr = y_arr[sorted_dex] 

94 cls._phosim_positions[i_band] = {} 

95 cls._phosim_positions[i_band]['id'] = id_arr 

96 cls._phosim_positions[i_band]['xmm'] = x_arr 

97 cls._phosim_positions[i_band]['ymm'] = y_arr 

98 

99 @classmethod 

100 def tearDownClass(cls): 

101 clean_up_lsst_camera() 

102 

103 def test_focal_plane_from_pupil(self): 

104 """ 

105 Test conversion from pupil coords to focal plane coords 

106 using data generated by PhoSim 

107 """ 

108 catsim_dtype = np.dtype([('id', int), 

109 ('xmm', float), ('ymm', float), 

110 ('xpup', float), ('ypup', float), 

111 ('raObs', float), ('decObs', float)]) 

112 

113 catsim_data = np.genfromtxt(os.path.join(self._data_dir, 'CatSimData', 

114 'predicted_positions.txt'), 

115 dtype=catsim_dtype) 

116 

117 for i_band, band in enumerate('ugrizy'): 

118 np.testing.assert_array_equal(catsim_data['id'], 

119 self._phosim_positions[i_band]['id']) 

120 

121 xmm, ymm = focalPlaneCoordsFromPupilCoordsLSST(catsim_data['xpup'], 

122 catsim_data['ypup'], 

123 band) 

124 

125 distance = np.sqrt((xmm-self._phosim_positions[i_band]['xmm'])**2 + 

126 (ymm-self._phosim_positions[i_band]['ymm'])**2) 

127 

128 # make sure predicted positions are accurate to within 

129 # 1 pixel = 0.01 mm 

130 self.assertLess(distance.max(), 0.01) 

131 

132 

133class FullTransformationTestCase(unittest.TestCase): 

134 """ 

135 Test that we can go from astrophysical coordinates (RA, Dec) 

136 to pixel coordinates 

137 """ 

138 

139 longMessage = True 

140 

141 @classmethod 

142 def setUpClass(cls): 

143 cls._data_dir = os.path.join(getPackageDir('sims_data'), 

144 'FocalPlaneData', 

145 'UnitTestData', 

146 'FullUnitTest') 

147 

148 truth_name = os.path.join(cls._data_dir, 'truth_catalog.txt') 

149 with open(truth_name, 'r') as in_file: 

150 header = in_file.readline() 

151 params = header.strip().split() 

152 ra = float(params[2]) 

153 dec = float(params[4]) 

154 rotSkyPos = float(params[6]) 

155 mjd = float(params[8]) 

156 cls._obs = ObservationMetaData(pointingRA=ra, 

157 pointingDec=dec, 

158 rotSkyPos=rotSkyPos, 

159 mjd=mjd) 

160 

161 cls._obs.site._humidity = 0.0 

162 cls._obs.site._pressure = 0.0 

163 assert cls._obs.site.humidity == 0.0 

164 assert cls._obs.site.pressure == 0.0 

165 

166 truth_dtype = np.dtype([('id', int), ('ra', float), ('dec', float), 

167 ('pmra', float), ('pmdec', float), 

168 ('px', float), ('vrad', float)]) 

169 

170 cls._truth_data = np.genfromtxt(truth_name, dtype=truth_dtype, 

171 delimiter=', ') 

172 

173 phosim_dtype = np.dtype([('id', int), ('phot', int), 

174 ('xcam', float), ('ycam', float)]) 

175 

176 list_of_files = os.listdir(cls._data_dir) 

177 

178 cls._phosim_data = {} 

179 

180 for file_name in list_of_files: 

181 if 'centroid' not in file_name: 

182 continue 

183 full_name = os.path.join(cls._data_dir, file_name) 

184 data = np.genfromtxt(full_name, dtype=phosim_dtype, 

185 skip_header=1) 

186 

187 if len(data.shape)>0: 

188 valid = np.where(data['phot']>0) 

189 if len(valid[0]) == 0: 

190 continue 

191 data = data[valid] 

192 else: 

193 if data['phot'] == 0: 

194 continue 

195 

196 params = file_name.split('_') 

197 chip_name = params[5]+'_'+params[6] 

198 filter_name = int(params[4][1]) 

199 if len(data.shape) == 0: 

200 data_raw = data 

201 data = {} 

202 data['id'] = np.array([data_raw['id']]) 

203 data['phot'] = np.array([data_raw['phot']]) 

204 data['xcam'] = np.array([data_raw['xcam']]) 

205 data['ycam'] = np.array([data_raw['ycam']]) 

206 cls._phosim_data[(chip_name, 'ugrizy'[filter_name])] = data 

207 

208 @classmethod 

209 def tearDownClass(cls): 

210 clean_up_lsst_camera() 

211 

212 def test_chip_name_from_pupil_coords_lsst(self): 

213 camera = lsst_camera() 

214 

215 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

216 self._truth_data['dec'], 

217 pm_ra=self._truth_data['pmra'], 

218 pm_dec=self._truth_data['pmdec'], 

219 parallax=self._truth_data['px'], 

220 v_rad=self._truth_data['vrad'], 

221 obs_metadata=self._obs) 

222 

223 for band in 'ugrizy': 

224 chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) 

225 n_checked = 0 

226 for ii in range(len(chip_name_list)): 

227 chip_name = chip_name_list[ii] 

228 if chip_name is None: 

229 for kk in self._phosim_data: 

230 if kk[1] == band: 

231 try: 

232 assert self._truth_data['id'][ii] not in self._phosim_data[kk]['id'] 

233 except AssertionError: 

234 # check that source wasn't just on the edge of the chip 

235 dex = np.where(self._phosim_data[kk]['id']==self._truth_data['id'][ii])[0] 

236 xx = self._phosim_data[kk]['xcam'][dex] 

237 yy = self._phosim_data[kk]['ycam'][dex] 

238 if xx>10.0 and xx<3990.0 and yy>10.0 and yy<3990.0: 

239 msg = '\nxpix: %.3f\nypix: %.3f\n' % (xx, yy) 

240 self.assertNotIn(self._truth_data['id'][ii], 

241 self._phosim_data[kk]['id'], 

242 msg=msg) 

243 continue 

244 

245 det = camera[chip_name] 

246 if det.getType() != DetectorType.SCIENCE: 

247 continue 

248 n_checked += 1 

249 chip_name = chip_name.replace(':','').replace(',','') 

250 chip_name = chip_name.replace(' ','_') 

251 self.assertIn(self._truth_data['id'][ii], 

252 self._phosim_data[(chip_name, band)]['id']) 

253 

254 self.assertGreater(n_checked, 200) 

255 

256 def test_chip_name_from_pupil_coords_lsst_one_at_a_time(self): 

257 """ 

258 Test that chipNameFromPupilCoordsLSST works on scalars 

259 """ 

260 rng = np.random.RandomState(76621) 

261 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

262 self._truth_data['dec'], 

263 pm_ra=self._truth_data['pmra'], 

264 pm_dec=self._truth_data['pmdec'], 

265 parallax=self._truth_data['px'], 

266 v_rad=self._truth_data['vrad'], 

267 obs_metadata=self._obs) 

268 

269 for band in 'ugrizy': 

270 chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) 

271 self.assertIsInstance(chip_name_list, np.ndarray) 

272 n_none = 0 

273 n_not_none = 0 

274 subsample = rng.choice(np.arange(len(chip_name_list), dtype=int), 

275 size=50, replace=False) 

276 for ii in subsample: 

277 name = chipNameFromPupilCoordsLSST(x_pup[ii], y_pup[ii], band=band) 

278 if name is not None: 

279 self.assertIsInstance(name, str) 

280 n_not_none += 1 

281 else: 

282 n_none += 1 

283 self.assertEqual(name, chip_name_list[ii]) 

284 

285 self.assertGreater(n_not_none, n_none//2) 

286 

287 def test_pupil_coords_from_ra_dec(self): 

288 """ 

289 Verify that pupilCoordsFromRaDec gives results consistent 

290 with the naive pupil coordinate method used by the 

291 Zernike fitter 

292 """ 

293 

294 phosim_catalog_file = os.path.join(self._data_dir, 'phosim_catalog.txt') 

295 ra_obs = [] 

296 dec_obs = [] 

297 unique_id = [] 

298 with open(phosim_catalog_file,'r') as input_file: 

299 for line in input_file: 

300 params = line.strip().split() 

301 if params[0] != 'object': 

302 if params[0] == 'rightascension': 

303 ra_pointing = float(params[1]) 

304 if params[0] == 'declination': 

305 dec_pointing = float(params[1]) 

306 if params[0] == 'rotskypos': 

307 rotskypos = float(params[1]) 

308 continue 

309 unique_id.append(int(params[1])) 

310 ra_obs.append(float(params[2])) 

311 dec_obs.append(float(params[3])) 

312 unique_id = np.array(unique_id) 

313 ra_obs = np.array(ra_obs) 

314 dec_obs = np.array(dec_obs) 

315 x_pup, y_pup = _rawPupilCoordsFromObserved(np.radians(ra_obs), 

316 np.radians(dec_obs), 

317 np.radians(ra_pointing), 

318 np.radians(dec_pointing), 

319 np.radians(rotskypos)) 

320 

321 sorted_dex = np.argsort(unique_id) 

322 unique_id = unique_id[sorted_dex] 

323 x_pup = x_pup[sorted_dex] 

324 y_pup = y_pup[sorted_dex] 

325 

326 (x_pup_test, 

327 y_pup_test) = pupilCoordsFromRaDec(self._truth_data['ra'], 

328 self._truth_data['dec'], 

329 pm_ra=self._truth_data['pmra'], 

330 pm_dec=self._truth_data['pmdec'], 

331 parallax=self._truth_data['px'], 

332 v_rad=self._truth_data['vrad'], 

333 obs_metadata=self._obs) 

334 

335 sorted_dex = np.argsort(self._truth_data['id']) 

336 truth_id = self._truth_data['id'][sorted_dex] 

337 x_pup_test = x_pup_test[sorted_dex] 

338 y_pup_test = y_pup_test[sorted_dex] 

339 

340 np.testing.assert_array_equal(unique_id, truth_id) 

341 distance = np.sqrt((x_pup-x_pup_test)**2 + 

342 (y_pup-y_pup_test)**2) 

343 

344 tenth_milli_arcsec = np.radians(0.0001/3600.0) 

345 self.assertLess(distance.max(), tenth_milli_arcsec) 

346 

347 def test_focal_coords_from_pupil_coords(self): 

348 """ 

349 Test that using pupilCoordsFromRaDec and 

350 focalPlaneCoordsFromPupilCoordsLSST gives answers 

351 consistent with PhoSim 

352 """ 

353 camera = lsst_camera() 

354 pix_transformer = DMtoCameraPixelTransformer() 

355 

356 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

357 self._truth_data['dec'], 

358 pm_ra=self._truth_data['pmra'], 

359 pm_dec=self._truth_data['pmdec'], 

360 parallax=self._truth_data['px'], 

361 v_rad=self._truth_data['vrad'], 

362 obs_metadata=self._obs) 

363 

364 (xf_no_optics, 

365 yf_no_optics) = focalPlaneCoordsFromPupilCoords(x_pup, 

366 y_pup, camera=lsst_camera()) 

367 

368 for band in 'ugrizy': 

369 

370 n_check = 0 

371 d_max = None 

372 n_old_better = 0 

373 n_new_better = 0 

374 

375 (xf_optics, 

376 yf_optics) = focalPlaneCoordsFromPupilCoordsLSST(x_pup, y_pup, band) 

377 

378 for det in camera: 

379 if det.getType() != DetectorType.SCIENCE: 

380 continue 

381 det_name = det.getName() 

382 name = det_name.replace(':','').replace(',','').replace(' ','_') 

383 key_tuple = (name, band) 

384 if key_tuple not in self._phosim_data: 

385 continue 

386 phosim_data = self._phosim_data[key_tuple] 

387 

388 pixel_to_focal = det.getTransform(PIXELS, FOCAL_PLANE) 

389 

390 (xdm_arr, 

391 ydm_arr) = pix_transformer.dmPixFromCameraPix(phosim_data['xcam'], 

392 phosim_data['ycam'], 

393 det_name) 

394 

395 for id_val, xdm, ydm in zip(phosim_data['id'],xdm_arr, ydm_arr): 

396 

397 dex = np.where(self._truth_data['id'] == id_val) 

398 xf = xf_optics[dex] 

399 yf = yf_optics[dex] 

400 

401 pixel_pt = geom.Point2D(xdm, ydm) 

402 focal_pt = pixel_to_focal.applyForward(pixel_pt) 

403 

404 dist = np.sqrt((xf-focal_pt.getX())**2+(yf-focal_pt.getY())**2) 

405 r_center = np.sqrt(focal_pt.getX()**2 + focal_pt.getY()**2) 

406 

407 old_dist = np.sqrt((xf_no_optics[dex]-focal_pt.getX())**2 + 

408 (yf_no_optics[dex]-focal_pt.getY())**2) 

409 

410 msg = '\nObject %d' % id_val 

411 msg += '\nchip %s' % det_name 

412 msg += '\nband %s' % band 

413 msg += '\ndistance from center: %.4e' % r_center 

414 msg += '\nPupil: %.4e %.4e' % (x_pup[dex], y_pup[dex]) 

415 msg += '\nPhosim: %.4f %.4f' % (focal_pt.getX(),focal_pt.getY()) 

416 msg += '\nCatSim: %.4f %.4f'% (xf, yf) 

417 msg += '\nPixels: %.4f %.4f' % (xdm, ydm) 

418 msg += '\nnew dist %.4e old_dist %.4e' % (dist, old_dist) 

419 

420 if dist<old_dist: 

421 n_new_better += 1 

422 else: 

423 n_old_better += 1 

424 

425 # Near the center of the focal plane, the old transformation 

426 # with no filter-dependence is actually better, but neither 

427 # is off by more than a pixel 

428 # 

429 # It also occasionally happens that the old transformation 

430 # was slightly better at the very edge of the focal plane 

431 # (in some filters) 

432 if old_dist<dist: 

433 if r_center < 100.0: 

434 # if we in the heart of the focal plane, make 

435 # sure that the fit has not degraded by more 

436 # than half a pixel and that the difference 

437 # between CatSim and PhoSim is still less 

438 # than a pixel 

439 self.assertLess(dist-old_dist, 0.005, msg=msg) 

440 self.assertLess(dist, 0.01, msg=msg) 

441 else: 

442 # if we are near the edge of the focal plane, 

443 # make sure that the difference between 

444 # CatSim and PhoSim is less than 2 pixels 

445 self.assertLess(dist, 0.02, msg=msg) 

446 else: 

447 if r_center < 100.0: 

448 # if we are in the heart of the focal plane, 

449 # make sure that the difference between 

450 # CatSim and PhoSim is less than a pixel 

451 self.assertLess(dist, 0.01, msg=msg) 

452 else: 

453 # If we are at the edge of the focal plane, 

454 # make sure that the difference between 

455 # CatSim and PhoSim is less than five pixels, 

456 # and if the difference is less than 2 pixels, 

457 # make sure that the difference under the old 

458 # transformation is more than 15 pixels (indicating 

459 # that we are in a difficult-to-fit part of the 

460 # focal plane) 

461 self.assertLess(dist, 0.05, msg=msg) 

462 if dist > 0.02: 

463 self.assertGreater(old_dist, 0.15, msg=msg) 

464 

465 n_check += 1 

466 

467 self.assertGreater(n_check, 200) 

468 self.assertGreater(n_new_better, 4*n_old_better) 

469 

470 def test_focal_coords_from_pupil_coords_vectorized(self): 

471 """ 

472 Test that focalPlaneCoordsFromPupilCoordsLSST acting 

473 on numpy arrays gives the same result as acting on 

474 scalars 

475 """ 

476 rng = np.random.RandomState(192312) 

477 camera = lsst_camera() 

478 pix_transformer = DMtoCameraPixelTransformer() 

479 

480 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

481 self._truth_data['dec'], 

482 pm_ra=self._truth_data['pmra'], 

483 pm_dec=self._truth_data['pmdec'], 

484 parallax=self._truth_data['px'], 

485 v_rad=self._truth_data['vrad'], 

486 obs_metadata=self._obs) 

487 

488 for band in 'ugrizy': 

489 x_f, y_f = focalPlaneCoordsFromPupilCoordsLSST(x_pup, 

490 y_pup, 

491 band=band) 

492 

493 subsample = rng.choice(np.arange(len(x_pup), dtype=int), 

494 size=50, replace=False) 

495 for ii in subsample: 

496 x_f1, y_f1 = focalPlaneCoordsFromPupilCoordsLSST(x_pup[ii], 

497 y_pup[ii], 

498 band=band) 

499 

500 self.assertIsInstance(x_f1, numbers.Number) 

501 self.assertIsInstance(y_f1, numbers.Number) 

502 self.assertAlmostEqual(x_f1, x_f[ii], 8) 

503 self.assertAlmostEqual(y_f1, y_f[ii], 8) 

504 

505 def test_pixel_coords_from_ra_dec(self): 

506 """ 

507 Test that pixelCoordsFromRaDecLSST() works correctly 

508 """ 

509 pix_transformer = DMtoCameraPixelTransformer() 

510 

511 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

512 self._truth_data['dec'], 

513 pm_ra=self._truth_data['pmra'], 

514 pm_dec=self._truth_data['pmdec'], 

515 parallax=self._truth_data['px'], 

516 v_rad=self._truth_data['vrad'], 

517 obs_metadata=self._obs) 

518 

519 (x_pix_no_optics, 

520 y_pix_no_optics) = pixelCoordsFromRaDec(self._truth_data['ra'], 

521 self._truth_data['dec'], 

522 pm_ra=self._truth_data['pmra'], 

523 pm_dec=self._truth_data['pmdec'], 

524 parallax=self._truth_data['px'], 

525 v_rad=self._truth_data['vrad'], 

526 obs_metadata=self._obs, 

527 camera=lsst_camera()) 

528 

529 for band in 'ugrizy': 

530 

531 x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], 

532 self._truth_data['dec'], 

533 pm_ra=self._truth_data['pmra'], 

534 pm_dec=self._truth_data['pmdec'], 

535 parallax=self._truth_data['px'], 

536 v_rad=self._truth_data['vrad'], 

537 obs_metadata=self._obs, 

538 band=band) 

539 

540 (x_f, 

541 y_f) = focalPlaneCoordsFromPupilCoordsLSST(x_pup, y_pup, band=band) 

542 

543 r_center = np.sqrt(x_f**2 + y_f**2) 

544 

545 n_check = 0 

546 n_diff_chip = 0 

547 n_old_better = 0 

548 n_new_better = 0 

549 

550 dist_arr = [] 

551 

552 for det in lsst_camera(): 

553 if det.getType() != DetectorType.SCIENCE: 

554 continue 

555 det_name = det.getName() 

556 name = det_name.replace(':','').replace(',','').replace(' ','_') 

557 key_tuple = (name, band) 

558 if key_tuple not in self._phosim_data: 

559 continue 

560 phosim_data = self._phosim_data[key_tuple] 

561 

562 for id_val, xcam, ycam in zip(phosim_data['id'], 

563 phosim_data['xcam'], 

564 phosim_data['ycam']): 

565 

566 dex = np.where(self._truth_data['id'] == id_val) 

567 self.assertEqual(len(dex[0]), 1) 

568 dex = dex[0][0] 

569 x_pix_val = x_pix[dex] 

570 y_pix_val = y_pix[dex] 

571 if np.isnan(x_pix_val): 

572 # PhoSim centroid files will report flux from bright 

573 # stars that spill over onto neighboring chips. In 

574 # this case, CatSim will report chipName=None and 

575 # xpix=ypix=Nan. In these cases, we will force 

576 # CatSim to calculate the pixel coordinates of the 

577 # object on the chip that PhoSim is reporting and 

578 # compare that result to the contents of the PhoSim 

579 # centroid file. 

580 # 

581 n_diff_chip += 1 

582 

583 (x_pix_val, 

584 y_pix_val) = pixelCoordsFromRaDecLSST(self._truth_data['ra'][dex], 

585 self._truth_data['dec'][dex], 

586 chipName = det_name, 

587 pm_ra=self._truth_data['pmra'][dex], 

588 pm_dec=self._truth_data['pmdec'][dex], 

589 parallax=self._truth_data['px'][dex], 

590 v_rad=self._truth_data['vrad'][dex], 

591 obs_metadata=self._obs, 

592 band=band) 

593 

594 self.assertIsInstance(x_pix_val, np.float) 

595 self.assertIsInstance(y_pix_val, np.float) 

596 

597 x_pix_no_optics_val = x_pix_no_optics[dex] 

598 y_pix_no_optics_val = y_pix_no_optics[dex] 

599 if np.isnan(x_pix_no_optics_val): 

600 

601 x, y = pixelCoordsFromRaDec(self._truth_data['ra'][dex], 

602 self._truth_data['dec'][dex], 

603 chipName = det_name, 

604 pm_ra=self._truth_data['pmra'][dex], 

605 pm_dec=self._truth_data['pmdec'][dex], 

606 parallax=self._truth_data['px'][dex], 

607 v_rad=self._truth_data['vrad'][dex], 

608 obs_metadata=self._obs, 

609 camera=lsst_camera()) 

610 

611 x_pix_no_optics_val = x 

612 y_pix_no_optics_val = y 

613 

614 self.assertIsInstance(x_pix_no_optics_val, np.float) 

615 self.assertIsInstance(y_pix_no_optics_val, np.float) 

616 

617 x_dm, y_dm = pix_transformer.dmPixFromCameraPix(xcam, ycam, det_name) 

618 dd = np.sqrt((x_dm-x_pix_val)**2 + (y_dm-y_pix_val)**2) 

619 dist_arr.append(dd) 

620 dd_no_optics = np.sqrt((x_dm-x_pix_no_optics_val)**2 + 

621 (y_dm-y_pix_no_optics_val)**2) 

622 

623 msg = '\nObject %d; chip %s' % (id_val, det_name) 

624 msg += '\nband %s' % band 

625 msg += '\ndist from center %.4e pixels' % (r_center[dex]/0.01) 

626 msg += '\nPupil: %.4e %.4e' % (x_pup[dex], x_pup[dex]) 

627 msg += '\nPhoSim: %.4f %.4f' % (x_dm, y_dm) 

628 msg += '\nCatSim: %.4f %.4f -- %.4e' % (x_pix_val, y_pix_val, dd) 

629 msg += '\nno Optics: %.4f %.4f -- %.4e' % (x_pix_no_optics_val, 

630 y_pix_no_optics_val, 

631 dd_no_optics) 

632 

633 if dd<dd_no_optics: 

634 n_new_better += 1 

635 else: 

636 n_old_better += 1 

637 

638 # Near the center of the focal plane, the old transformation 

639 # with no filter-dependence is actually better, but neither 

640 # is off by more than a pixel 

641 # 

642 # It also occasionally happens that the old transformation 

643 # was slightly better at the very edge of the focal plane 

644 # (in some filters) 

645 if dd_no_optics<dd: 

646 if r_center[dex] < 100.0: 

647 # if we in the heart of the focal plane, make 

648 # sure that the fit has not degraded by more 

649 # than half a pixel and that the difference 

650 # between CatSim and PhoSim is still less 

651 # than a pixel 

652 self.assertLess(dd-dd_no_optics, 5.0, msg=msg) 

653 self.assertLess(dd, 1.0, msg=msg) 

654 else: 

655 # if we are near the edge of the focal plane, 

656 # make sure that the difference between 

657 # CatSim and PhoSim is less than 2 pixels 

658 self.assertLess(dd, 2.0, msg=msg) 

659 else: 

660 if r_center[dex] < 100.0: 

661 # if we are in the heart of the focal plane, 

662 # make sure that the difference between 

663 # CatSim and PhoSim is less than a pixel 

664 self.assertLess(dd, 1.0, msg=msg) 

665 else: 

666 # If we are at the edge of the focal plane, 

667 # make sure that the difference between 

668 # CatSim and PhoSim is less than five pixels, 

669 # and if the difference is less than 2 pixels, 

670 # make sure that the difference under the old 

671 # transformation is more than 15 pixels (indicating 

672 # that we are in a difficult-to-fit part of the 

673 # focal plane) 

674 self.assertLess(dd, 5.0, msg=msg) 

675 if dd > 2.0: 

676 self.assertGreater(dd_no_optics, 15.0, msg=msg) 

677 

678 n_check += 1 

679 

680 if dd > 1.0: 

681 if dd_no_optics>15.0: 

682 self.assertLess(dd, 5.0, msg=msg) 

683 else: 

684 self.assertLess(dd, 2.0, msg=msg) 

685 

686 self.assertGreater(n_check, 200) 

687 self.assertLess(n_diff_chip, n_check//2) 

688 self.assertGreater(n_new_better, 4*n_old_better) 

689 dist_arr = np.array(dist_arr) 

690 dist_arr = np.sort(dist_arr) 

691 

692 def test_pixel_coords_from_ra_dec_one_at_a_time(self): 

693 """ 

694 Test that pixelCoordsFromRaDecLSST works correctly on 

695 scalars 

696 """ 

697 

698 rng = np.random.RandomState(1845332) 

699 

700 for band in 'ugrizy': 

701 

702 x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], 

703 self._truth_data['dec'], 

704 pm_ra=self._truth_data['pmra'], 

705 pm_dec=self._truth_data['pmdec'], 

706 parallax=self._truth_data['px'], 

707 v_rad=self._truth_data['vrad'], 

708 obs_metadata=self._obs, 

709 band=band) 

710 

711 self.assertIsInstance(x_pix, np.ndarray) 

712 self.assertIsInstance(y_pix, np.ndarray) 

713 

714 n_nan = 0 

715 n_good = 0 

716 subsample = rng.choice(np.arange(len(x_pix), dtype=int), 

717 size=50, replace=False) 

718 for ii in subsample: # only test on a subsample; this is slow 

719 x_pix1, y_pix1 = pixelCoordsFromRaDecLSST(self._truth_data['ra'][ii], 

720 self._truth_data['dec'][ii], 

721 pm_ra=self._truth_data['pmra'][ii], 

722 pm_dec=self._truth_data['pmdec'][ii], 

723 parallax=self._truth_data['px'][ii], 

724 v_rad=self._truth_data['vrad'][ii], 

725 obs_metadata=self._obs, 

726 band=band) 

727 

728 self.assertIsInstance(x_pix1, numbers.Number) 

729 self.assertIsInstance(y_pix1, numbers.Number) 

730 if not np.isnan(x_pix1): 

731 self.assertAlmostEqual(x_pix1, x_pix[ii], 8) 

732 self.assertAlmostEqual(y_pix1, y_pix[ii], 8) 

733 n_good += 1 

734 else: 

735 n_nan += 1 

736 

737 self.assertLess(n_nan, n_good//2) 

738 

739 def test_pupil_coords_from_focal_plane_coords_LSST(self): 

740 """ 

741 Test that pupilCoordsFromFocalPlaneCoordsLSST inverts 

742 focalPlaneCoordsFromPupilCoordsLSST 

743 """ 

744 x_f = np.arange(-317.0, 317.0, 20.0) 

745 y_f = np.arange(-317.0, 317.0, 20.0) 

746 mesh = np.meshgrid(x_f, y_f) 

747 x_f = mesh[0].flatten() 

748 y_f = mesh[1].flatten() 

749 for band in 'ugrizy': 

750 x_p, y_p = pupilCoordsFromFocalPlaneCoordsLSST(x_f, y_f, band=band) 

751 x_f1, y_f1 = focalPlaneCoordsFromPupilCoordsLSST(x_p, y_p, 

752 band=band) 

753 

754 dd = np.sqrt((x_f-x_f1)**2 + (y_f-y_f1)**2) 

755 self.assertLess(dd.max(), 3.0e-6) 

756 

757 def test_pupil_coords_from_focal_plane_coords_LSST_one_at_a_time(self): 

758 """ 

759 Test that pupilCoordsFromFocalPlaneCoordsLSST works on scalars 

760 """ 

761 rng = np.random.RandomState(8123412) 

762 x_f = np.arange(-317.0, 317.0, 20.0) 

763 y_f = np.arange(-317.0, 317.0, 20.0) 

764 mesh = np.meshgrid(x_f, y_f) 

765 x_f = mesh[0].flatten() 

766 y_f = mesh[1].flatten() 

767 

768 for band in 'ugrizy': 

769 x_p, y_p = pupilCoordsFromFocalPlaneCoordsLSST(x_f, y_f, band=band) 

770 self.assertIsInstance(x_p, np.ndarray) 

771 self.assertIsInstance(y_p, np.ndarray) 

772 subsample = rng.choice(np.arange(len(x_p), dtype=int), 

773 size=50, replace=False) 

774 for ii in subsample: 

775 x_p1, y_p1 = pupilCoordsFromFocalPlaneCoordsLSST(x_f[ii], y_f[ii], 

776 band=band) 

777 

778 self.assertIsInstance(x_p1, numbers.Number) 

779 self.assertIsInstance(y_p1, numbers.Number) 

780 self.assertAlmostEqual(x_p1, x_p[ii], 16) 

781 self.assertAlmostEqual(y_p1, y_p[ii], 16) 

782 

783 def test_chip_name_from_ra_dec_lsst(self): 

784 """ 

785 Test that chipNameFromRaDecLSST is consistent with 

786 chipNameFromPupilCoordsLSST 

787 """ 

788 x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], 

789 self._truth_data['dec'], 

790 pm_ra=self._truth_data['pmra'], 

791 pm_dec=self._truth_data['pmdec'], 

792 parallax=self._truth_data['px'], 

793 v_rad=self._truth_data['vrad'], 

794 obs_metadata=self._obs) 

795 

796 for band in 'ugrizy': 

797 chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) 

798 chip_name_list_1 = chipNameFromRaDecLSST(self._truth_data['ra'], 

799 self._truth_data['dec'], 

800 pm_ra=self._truth_data['pmra'], 

801 pm_dec=self._truth_data['pmdec'], 

802 parallax=self._truth_data['px'], 

803 v_rad=self._truth_data['vrad'], 

804 obs_metadata=self._obs, 

805 band=band) 

806 

807 np.testing.assert_array_equal(chip_name_list, chip_name_list_1) 

808 n_none = np.where(np.char.find(chip_name_list.astype(str), 'None')==0) 

809 self.assertLess(len(n_none[0]), len(chip_name_list)//4) 

810 

811 def test_chip_name_from_ra_dec_lsst_one_at_a_time(self): 

812 """ 

813 Test that chipNameFromRaDecLSST works on scalars 

814 """ 

815 rng = np.random.RandomState(65673) 

816 for band in 'ugrizy': 

817 chip_name_list = chipNameFromRaDecLSST(self._truth_data['ra'], 

818 self._truth_data['dec'], 

819 pm_ra=self._truth_data['pmra'], 

820 pm_dec=self._truth_data['pmdec'], 

821 parallax=self._truth_data['px'], 

822 v_rad=self._truth_data['vrad'], 

823 obs_metadata=self._obs, 

824 band=band) 

825 

826 self.assertIsInstance(chip_name_list, np.ndarray) 

827 n_none = 0 

828 n_not_none = 0 

829 subsample = rng.choice(np.arange(len(chip_name_list), dtype=int), 

830 size=50, replace=False) 

831 for ii in subsample: 

832 name = chipNameFromRaDecLSST(self._truth_data['ra'][ii], 

833 self._truth_data['dec'][ii], 

834 pm_ra=self._truth_data['pmra'][ii], 

835 pm_dec=self._truth_data['pmdec'][ii], 

836 parallax=self._truth_data['px'][ii], 

837 v_rad=self._truth_data['vrad'][ii], 

838 obs_metadata=self._obs, 

839 band=band) 

840 

841 if name is not None: 

842 n_not_none += 1 

843 self.assertIsInstance(name, str) 

844 else: 

845 n_none += 1 

846 

847 self.assertEqual(name, chip_name_list[ii]) 

848 

849 self.assertGreater(n_not_none, n_none//2) 

850 

851 def test_radians(self): 

852 """ 

853 Test the radians versions of pixelCoordsFromRaDecLSST and 

854 chipNameFromRaDecLSST 

855 """ 

856 for band in 'ugrizy': 

857 

858 x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], 

859 self._truth_data['dec'], 

860 pm_ra=self._truth_data['pmra'], 

861 pm_dec=self._truth_data['pmdec'], 

862 parallax=self._truth_data['px'], 

863 v_rad=self._truth_data['vrad'], 

864 obs_metadata=self._obs, 

865 band=band) 

866 

867 (x_pix_r, 

868 y_pix_r) = _pixelCoordsFromRaDecLSST(np.radians(self._truth_data['ra']), 

869 np.radians(self._truth_data['dec']), 

870 pm_ra=radiansFromArcsec(self._truth_data['pmra']), 

871 pm_dec=radiansFromArcsec(self._truth_data['pmdec']), 

872 parallax=radiansFromArcsec(self._truth_data['px']), 

873 v_rad=self._truth_data['vrad'], 

874 obs_metadata=self._obs, 

875 band=band) 

876 

877 np.testing.assert_array_equal(x_pix, x_pix_r) 

878 np.testing.assert_array_equal(y_pix, y_pix_r) 

879 

880 chip_name_list = chipNameFromRaDecLSST(self._truth_data['ra'], 

881 self._truth_data['dec'], 

882 pm_ra=self._truth_data['pmra'], 

883 pm_dec=self._truth_data['pmdec'], 

884 parallax=self._truth_data['px'], 

885 v_rad=self._truth_data['vrad'], 

886 obs_metadata=self._obs, 

887 band=band) 

888 

889 chip_name_list_r = _chipNameFromRaDecLSST(np.radians(self._truth_data['ra']), 

890 np.radians(self._truth_data['dec']), 

891 pm_ra=radiansFromArcsec(self._truth_data['pmra']), 

892 pm_dec=radiansFromArcsec(self._truth_data['pmdec']), 

893 parallax=radiansFromArcsec(self._truth_data['px']), 

894 v_rad=self._truth_data['vrad'], 

895 obs_metadata=self._obs, 

896 band=band) 

897 

898 np.testing.assert_array_equal(chip_name_list, chip_name_list_r) 

899 

900 def test_pupil_coords_from_pixel_coords_LSST(self): 

901 """ 

902 Test that pupilCoordsFromPixelCoordsLSST inverts 

903 pixelCoordsFromPupilCoordsLSST 

904 """ 

905 xpix = np.arange(-2000.0, 2000.0, 100.0) 

906 ypix = np.arange(-2000.0, 2000.0, 100.0) 

907 mesh = np.meshgrid(xpix, ypix) 

908 xpix = mesh[0].flatten() 

909 ypix = mesh[1].flatten() 

910 

911 chip_name = 'R:3,1 S:1,2' 

912 

913 chip_name_list = ['None'] 

914 for det in lsst_camera(): 

915 if det.getType() == DetectorType.SCIENCE: 

916 chip_name_list.append(det.getName()) 

917 chip_name_list = np.array(chip_name_list) 

918 rng = np.random.RandomState(81231) 

919 chip_name_sample = rng.choice(chip_name_list, size=len(xpix), 

920 replace=True) 

921 

922 for band in 'ugrizy': 

923 xpup, ypup = pupilCoordsFromPixelCoordsLSST(xpix, ypix, 

924 chipName=chip_name, 

925 band=band) 

926 

927 xpix1, ypix1 = pixelCoordsFromPupilCoordsLSST(xpup, ypup, 

928 chipName=chip_name, 

929 band=band) 

930 

931 dd = np.sqrt((xpix-xpix1)**2 + (ypix-ypix1)**2) 

932 self.assertLess(dd.max(), 1.0e-4) 

933 

934 xpup, ypup = pupilCoordsFromPixelCoordsLSST(xpix, ypix, 

935 chipName=chip_name_sample, 

936 band=band) 

937 

938 xpix1, ypix1 = pixelCoordsFromPupilCoordsLSST(xpup, ypup, 

939 chipName=chip_name_sample, 

940 band=band) 

941 

942 valid = np.where(np.char.find(chip_name_sample, 'None')<0) 

943 self.assertGreater(len(valid[0]), 0) 

944 self.assertLess(len(valid[0]), len(xpix)) 

945 dd = np.sqrt((xpix[valid]-xpix1[valid])**2 + (ypix[valid]-ypix1[valid])**2) 

946 self.assertLess(dd.max(), 1.0e-4) 

947 

948 for dist in dd: 

949 self.assertFalse(np.isnan(dist)) 

950 

951 invalid = np.where(np.char.find(chip_name_sample, 'None')==0) 

952 for ii in invalid[0]: 

953 self.assertTrue(np.isnan(xpix1[ii])) 

954 self.assertTrue(np.isnan(ypix1[ii])) 

955 

956 def test_ra_dec_from_pixel_coords_lsst(self): 

957 """ 

958 Test that raDecFromPixelCoordsLSST inverts 

959 pixelCoordsFromRaDecLSST 

960 """ 

961 

962 rng = np.random.RandomState(1811231) 

963 n_samples = 500 

964 rr = rng.random_sample(n_samples)*2.2 

965 theta = rng.random_sample(n_samples)*2.0*np.pi 

966 ra = self._obs.pointingRA + rr*np.cos(theta) 

967 dec = self._obs.pointingDec + rr*np.sin(theta) 

968 

969 name_list = [None] 

970 for det in lsst_camera(): 

971 if det.getType() == DetectorType.SCIENCE: 

972 name_list.append(det.getName()) 

973 name_list = np.array(name_list) 

974 name_sample = rng.choice(name_list, size=n_samples, replace=True) 

975 

976 for band in 'ugrizy': 

977 xpix, ypix = pixelCoordsFromRaDecLSST(ra, dec, 

978 chipName=name_sample, 

979 band=band, 

980 obs_metadata=self._obs) 

981 

982 ra1, dec1 = raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, 

983 band=band, 

984 obs_metadata=self._obs) 

985 

986 valid = np.where(np.isfinite(ra1)) 

987 valid_name = np.where(np.char.find(name_sample.astype(str), 'None')<0) 

988 np.testing.assert_array_equal(valid[0], valid_name[0]) 

989 

990 invalid = np.where(np.isnan(ra1)) 

991 invalid_name = np.where(np.char.find(name_sample.astype(str), 'None')==0) 

992 np.testing.assert_array_equal(invalid[0], invalid_name[0]) 

993 

994 self.assertGreater(len(invalid[0]), 0) 

995 self.assertGreater(len(valid[0]), 0) 

996 

997 dist = angularSeparation(ra[valid], dec[valid], ra1[valid], dec1[valid]) 

998 dist *= 3600.0 

999 self.assertLess(dist.max(), 1.0e-5) 

1000 

1001 # test one at a time 

1002 for ii in range(len(ra1)): 

1003 ra2, dec2 = raDecFromPixelCoordsLSST(xpix[ii], ypix[ii], 

1004 chipName=str(name_sample[ii]), 

1005 band=band, 

1006 obs_metadata=self._obs) 

1007 

1008 self.assertIsInstance(ra2, numbers.Number) 

1009 self.assertIsInstance(dec2, numbers.Number) 

1010 

1011 if name_sample[ii] is None: 

1012 self.assertTrue(np.isnan(ra2)) 

1013 self.assertTrue(np.isnan(dec2)) 

1014 else: 

1015 self.assertAlmostEqual(ra2, ra1[ii], 10) 

1016 self.assertAlmostEqual(dec2, dec1[ii], 10) 

1017 

1018 

1019 def test_ra_dec_from_pixel_coords_lsst_radians(self): 

1020 """ 

1021 Test that radians version of raDecFromPixelCoordsLSST 

1022 agrees with degrees version 

1023 """ 

1024 rng = np.random.RandomState(56123) 

1025 n_samples = 500 

1026 name_list = [None] 

1027 for det in lsst_camera(): 

1028 if det.getType() == DetectorType.SCIENCE: 

1029 name_list.append(det.getName()) 

1030 name_list = np.array(name_list) 

1031 name_sample = rng.choice(name_list, size=n_samples, replace=True) 

1032 invalid = np.where(np.char.find(name_sample.astype(str), 'None')==0) 

1033 self.assertLess(len(invalid[0]), n_samples//2) 

1034 

1035 xpix = rng.random_sample(n_samples)*4000.0 

1036 ypix = rng.random_sample(n_samples)*4000.0 

1037 for band in 'ugrizy': 

1038 ra_deg, dec_deg = raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, 

1039 obs_metadata=self._obs) 

1040 

1041 

1042 ra_rad, dec_rad = _raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, 

1043 obs_metadata=self._obs) 

1044 

1045 

1046 valid = np.where(np.isfinite(ra_deg)) 

1047 np.testing.assert_array_equal(np.degrees(ra_rad[valid]), ra_deg[valid]) 

1048 np.testing.assert_array_equal(np.degrees(dec_rad[valid]), dec_deg[valid]) 

1049 self.assertGreater(len(valid[0]), n_samples//2) 

1050 for ii in invalid[0]: 

1051 self.assertTrue(np.isnan(ra_rad[ii])) 

1052 self.assertTrue(np.isnan(dec_rad[ii])) 

1053 for ii in range(n_samples): 

1054 ra1, dec1 = _raDecFromPixelCoordsLSST(xpix[ii], ypix[ii], 

1055 chipName=str(name_sample[ii]), 

1056 obs_metadata=self._obs) 

1057 

1058 self.assertIsInstance(ra1, numbers.Number) 

1059 self.assertIsInstance(dec1, numbers.Number) 

1060 if name_sample[ii] is None: 

1061 self.assertTrue(np.isnan(ra1)) 

1062 self.assertTrue(np.isnan(dec1)) 

1063 else: 

1064 self.assertAlmostEqual(ra1, ra_rad[ii], 10) 

1065 self.assertAlmostEqual(dec1, dec_rad[ii], 10) 

1066 

1067 def test_nans(self): 

1068 """ 

1069 Test that points outside the focal plane get NaNs for pupil 

1070 and focal plane coords 

1071 """ 

1072 rng = np.random.RandomState(66) 

1073 n_samples = 100 

1074 rr = rng.random_sample(n_samples)*600.0 

1075 theta = rng.random_sample(n_samples)*2.0*np.pi 

1076 self.assertGreater(rr.max(), 500.0) 

1077 xf = rr*np.cos(theta) 

1078 yf = rr*np.sin(theta) 

1079 xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(xf, yf, band='g') 

1080 name_list = chipNameFromPupilCoordsLSST(xp, yp, band='g') 

1081 xpix, ypix = pixelCoordsFromPupilCoordsLSST(xp, yp, 

1082 chipName='R:2,2 S:1,1', 

1083 band='g') 

1084 

1085 ra, dec = raDecFromPixelCoordsLSST(xpix, ypix, 'R:2,2 S:1,1', 

1086 obs_metadata=self._obs, 

1087 band='g') 

1088 

1089 xpix2, ypix2 = pixelCoordsFromPupilCoordsLSST(xp, yp, 

1090 band='g') 

1091 invalid = np.where(rr>500.0)[0] 

1092 self.assertGreater(len(invalid), 0) 

1093 self.assertLess(len(invalid), n_samples) 

1094 non_nan_pix = 0 

1095 non_none_name = 0 

1096 for ii in range(n_samples): 

1097 if ii in invalid: 

1098 self.assertTrue(np.isnan(xp[ii])) 

1099 self.assertTrue(np.isnan(yp[ii])) 

1100 self.assertTrue(np.isnan(xpix[ii])) 

1101 self.assertTrue(np.isnan(ypix[ii])) 

1102 self.assertTrue(np.isnan(xpix2[ii])) 

1103 self.assertTrue(np.isnan(ypix2[ii])) 

1104 self.assertTrue(np.isnan(ra[ii])) 

1105 self.assertTrue(np.isnan(dec[ii])) 

1106 self.assertIsNone(name_list[ii]) 

1107 else: 

1108 self.assertFalse(np.isnan(xp[ii])) 

1109 self.assertFalse(np.isnan(yp[ii])) 

1110 self.assertFalse(np.isnan(xpix[ii])) 

1111 self.assertFalse(np.isnan(ypix[ii])) 

1112 self.assertFalse(np.isnan(ra[ii])) 

1113 self.assertFalse(np.isnan(dec[ii])) 

1114 

1115 # this test is because, even if an object 

1116 # has finite pupil or focal plane coordinates, 

1117 # it could still land in a chip gap, causing 

1118 # chip_name=None, xpix=ypix=NaN 

1119 if not np.isnan(xpix2[ii]) and not np.isnan(ypix2[ii]): 

1120 non_nan_pix += 1 

1121 if name_list[ii] is not None: 

1122 non_none_name += 1 

1123 

1124 self.assertGreater(non_nan_pix, 0) 

1125 self.assertGreater(non_none_name, 0) 

1126 

1127 rr = rng.random_sample(n_samples)*0.05 

1128 xp = rr*np.cos(theta) 

1129 yp = rr*np.sin(theta) 

1130 

1131 xf2, yf2 = focalPlaneCoordsFromPupilCoordsLSST(xp, yp, band='i') 

1132 xpix, ypix = pixelCoordsFromPupilCoordsLSST(xp, yp, chipName='R:2,2 S:1,1', 

1133 band='i') 

1134 

1135 ra, dec = raDecFromPixelCoordsLSST(xpix, ypix, 'R:2,2 S:1,1', 

1136 obs_metadata=self._obs, 

1137 band='i') 

1138 

1139 xpix2, ypix2 = pixelCoordsFromPupilCoordsLSST(xp, yp, 

1140 band='g') 

1141 

1142 invalid = np.where(rr>0.04841)[0] 

1143 self.assertGreater(len(invalid), 0) 

1144 self.assertLess(len(invalid), n_samples) 

1145 non_nan_pix = 0 

1146 for ii in range(n_samples): 

1147 if ii in invalid: 

1148 self.assertTrue(np.isnan(xf2[ii])) 

1149 self.assertTrue(np.isnan(yf2[ii])) 

1150 self.assertTrue(np.isnan(xpix[ii])) 

1151 self.assertTrue(np.isnan(ypix[ii])) 

1152 self.assertTrue(np.isnan(xpix2[ii])) 

1153 self.assertTrue(np.isnan(ypix2[ii])) 

1154 self.assertTrue(np.isnan(ra[ii])) 

1155 self.assertTrue(np.isnan(dec[ii])) 

1156 else: 

1157 self.assertFalse(np.isnan(xf2[ii])) 

1158 self.assertFalse(np.isnan(yf2[ii])) 

1159 self.assertFalse(np.isnan(xpix[ii])) 

1160 self.assertFalse(np.isnan(ypix[ii])) 

1161 self.assertFalse(np.isnan(ra[ii])) 

1162 self.assertFalse(np.isnan(dec[ii])) 

1163 

1164 # this test is because, even if an object 

1165 # has finite pupil or focal plane coordinates, 

1166 # it could still land in a chip gap, causing 

1167 # chip_name=None, xpix=ypix=NaN 

1168 if not np.isnan(xpix2[ii]) and not np.isnan(ypix2[ii]): 

1169 non_nan_pix += 1 

1170 

1171 self.assertGreater(non_nan_pix, 0) 

1172 

1173 xf = np.array([1.1, 2.1, np.NaN, 4.5]) 

1174 yf = np.array([2.1, np.NaN, 1.2, 3.0]) 

1175 xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(xf, yf, band='r') 

1176 self.assertTrue(np.isnan(xp[2])) 

1177 self.assertTrue(np.isnan(yp[2])) 

1178 self.assertTrue(np.isnan(xp[1])) 

1179 self.assertTrue(np.isnan(yp[1])) 

1180 self.assertFalse(np.isnan(xp[0])) 

1181 self.assertFalse(np.isnan(yp[0])) 

1182 self.assertFalse(np.isnan(xp[3])) 

1183 self.assertFalse(np.isnan(yp[3])) 

1184 

1185 xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(np.NaN, 1.0, band='g') 

1186 self.assertTrue(np.isnan(xp)) 

1187 self.assertTrue(np.isnan(yp)) 

1188 

1189 xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(2.1, np.NaN, band='g') 

1190 self.assertTrue(np.isnan(xp)) 

1191 self.assertTrue(np.isnan(yp)) 

1192 

1193 xp = np.array([0.0011, 0.0021, np.NaN, 0.0045]) 

1194 yp = np.array([0.0021, np.NaN, 0.0012, 0.0030]) 

1195 xf, yf = focalPlaneCoordsFromPupilCoordsLSST(xp, yp, band='r') 

1196 self.assertTrue(np.isnan(xf[2])) 

1197 self.assertTrue(np.isnan(yf[2])) 

1198 self.assertTrue(np.isnan(xf[1])) 

1199 self.assertTrue(np.isnan(yf[1])) 

1200 self.assertFalse(np.isnan(xf[0])) 

1201 self.assertFalse(np.isnan(yf[0])) 

1202 self.assertFalse(np.isnan(xf[3])) 

1203 self.assertFalse(np.isnan(yf[3])) 

1204 

1205 xf, yf = focalPlaneCoordsFromPupilCoordsLSST(np.NaN, 0.001, band='g') 

1206 self.assertTrue(np.isnan(xf)) 

1207 self.assertTrue(np.isnan(yf)) 

1208 

1209 xf, yf = pupilCoordsFromFocalPlaneCoordsLSST(0.002, np.NaN, band='g') 

1210 self.assertTrue(np.isnan(xf)) 

1211 self.assertTrue(np.isnan(yf)) 

1212 

1213 

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

1215 pass 

1216 

1217 

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

1219 lsst.utils.tests.init() 

1220 unittest.main()