Coverage for tests/testLsstOpticalDistortions.py : 7%

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
lsst.utils.tests.init()
def setUpClass(cls): pix_transformer = DMtoCameraPixelTransformer() data_dir = os.path.join(getPackageDir('sims_data'), 'FocalPlaneData', 'UnitTestData')
cls._data_dir = data_dir
phosim_dtype = np.dtype([('id', int), ('phot', int), ('xpix', float), ('ypix', float)])
camera = lsst_camera() cls._phosim_positions = {} for i_band in range(6): id_arr = None x_arr = None y_arr = None for det in camera: if det.getType() != SCIENCE: continue det_name = det.getName() name = det_name.replace(':','').replace(',','') name = name.replace(' ','_') file_name = 'centroid_lsst_e_2_f%d_%s_E000.txt' % (i_band, name) data = np.genfromtxt(os.path.join(data_dir, 'PhoSimData', file_name), dtype=phosim_dtype, skip_header=1) dm_x, dm_y = pix_transformer.dmPixFromCameraPix(data['xpix'], data['ypix'], det_name) pix_to_focal = det.getTransform(PIXELS, FOCAL_PLANE) x_mm = np.zeros(len(dm_x)) y_mm = np.zeros(len(dm_y)) for ii in range(len(x_mm)): pix_pt = geom.Point2D(dm_x[ii], dm_y[ii]) focal_pt = pix_to_focal.applyForward(pix_pt) x_mm[ii] = focal_pt.getX() y_mm[ii] = focal_pt.getY()
if id_arr is None: id_arr = data['id'] x_arr = x_mm y_arr = y_mm else: id_arr = np.append(id_arr, data['id']) x_arr = np.append(x_arr, x_mm) y_arr = np.append(y_arr, y_mm)
sorted_dex = np.argsort(id_arr) id_arr = id_arr[sorted_dex] x_arr = x_arr[sorted_dex] y_arr = y_arr[sorted_dex] cls._phosim_positions[i_band] = {} cls._phosim_positions[i_band]['id'] = id_arr cls._phosim_positions[i_band]['xmm'] = x_arr cls._phosim_positions[i_band]['ymm'] = y_arr
def tearDownClass(cls): clean_up_lsst_camera()
""" Test conversion from pupil coords to focal plane coords using data generated by PhoSim """ catsim_dtype = np.dtype([('id', int), ('xmm', float), ('ymm', float), ('xpup', float), ('ypup', float), ('raObs', float), ('decObs', float)])
catsim_data = np.genfromtxt(os.path.join(self._data_dir, 'CatSimData', 'predicted_positions.txt'), dtype=catsim_dtype)
for i_band, band in enumerate('ugrizy'): np.testing.assert_array_equal(catsim_data['id'], self._phosim_positions[i_band]['id'])
xmm, ymm = focalPlaneCoordsFromPupilCoordsLSST(catsim_data['xpup'], catsim_data['ypup'], band)
distance = np.sqrt((xmm-self._phosim_positions[i_band]['xmm'])**2 + (ymm-self._phosim_positions[i_band]['ymm'])**2)
# make sure predicted positions are accurate to within # 1 pixel = 0.01 mm self.assertLess(distance.max(), 0.01)
""" Test that we can go from astrophysical coordinates (RA, Dec) to pixel coordinates """
def setUpClass(cls): cls._data_dir = os.path.join(getPackageDir('sims_data'), 'FocalPlaneData', 'UnitTestData', 'FullUnitTest')
truth_name = os.path.join(cls._data_dir, 'truth_catalog.txt') with open(truth_name, 'r') as in_file: header = in_file.readline() params = header.strip().split() ra = float(params[2]) dec = float(params[4]) rotSkyPos = float(params[6]) mjd = float(params[8]) cls._obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, rotSkyPos=rotSkyPos, mjd=mjd)
cls._obs.site._humidity = 0.0 cls._obs.site._pressure = 0.0 assert cls._obs.site.humidity == 0.0 assert cls._obs.site.pressure == 0.0
truth_dtype = np.dtype([('id', int), ('ra', float), ('dec', float), ('pmra', float), ('pmdec', float), ('px', float), ('vrad', float)])
cls._truth_data = np.genfromtxt(truth_name, dtype=truth_dtype, delimiter=', ')
phosim_dtype = np.dtype([('id', int), ('phot', int), ('xcam', float), ('ycam', float)])
list_of_files = os.listdir(cls._data_dir)
cls._phosim_data = {}
for file_name in list_of_files: if 'centroid' not in file_name: continue full_name = os.path.join(cls._data_dir, file_name) data = np.genfromtxt(full_name, dtype=phosim_dtype, skip_header=1)
if len(data.shape)>0: valid = np.where(data['phot']>0) if len(valid[0]) == 0: continue data = data[valid] else: if data['phot'] == 0: continue
params = file_name.split('_') chip_name = params[5]+'_'+params[6] filter_name = int(params[4][1]) if len(data.shape) == 0: data_raw = data data = {} data['id'] = np.array([data_raw['id']]) data['phot'] = np.array([data_raw['phot']]) data['xcam'] = np.array([data_raw['xcam']]) data['ycam'] = np.array([data_raw['ycam']]) cls._phosim_data[(chip_name, 'ugrizy'[filter_name])] = data
def tearDownClass(cls): clean_up_lsst_camera()
camera = lsst_camera()
x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
for band in 'ugrizy': chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) n_checked = 0 for ii in range(len(chip_name_list)): chip_name = chip_name_list[ii] if chip_name is None: for kk in self._phosim_data: if kk[1] == band: try: assert self._truth_data['id'][ii] not in self._phosim_data[kk]['id'] except AssertionError: # check that source wasn't just on the edge of the chip dex = np.where(self._phosim_data[kk]['id']==self._truth_data['id'][ii])[0] xx = self._phosim_data[kk]['xcam'][dex] yy = self._phosim_data[kk]['ycam'][dex] if xx>10.0 and xx<3990.0 and yy>10.0 and yy<3990.0: msg = '\nxpix: %.3f\nypix: %.3f\n' % (xx, yy) self.assertNotIn(self._truth_data['id'][ii], self._phosim_data[kk]['id'], msg=msg) continue
det = camera[chip_name] if det.getType() != SCIENCE: continue n_checked += 1 chip_name = chip_name.replace(':','').replace(',','') chip_name = chip_name.replace(' ','_') self.assertIn(self._truth_data['id'][ii], self._phosim_data[(chip_name, band)]['id'])
self.assertGreater(n_checked, 200)
""" Test that chipNameFromPupilCoordsLSST works on scalars """ rng = np.random.RandomState(76621) x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
for band in 'ugrizy': chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) self.assertIsInstance(chip_name_list, np.ndarray) n_none = 0 n_not_none = 0 subsample = rng.choice(np.arange(len(chip_name_list), dtype=int), size=50, replace=False) for ii in subsample: name = chipNameFromPupilCoordsLSST(x_pup[ii], y_pup[ii], band=band) if name is not None: self.assertIsInstance(name, str) n_not_none += 1 else: n_none += 1 self.assertEqual(name, chip_name_list[ii])
self.assertGreater(n_not_none, n_none//2)
""" Verify that pupilCoordsFromRaDec gives results consistent with the naive pupil coordinate method used by the Zernike fitter """
phosim_catalog_file = os.path.join(self._data_dir, 'phosim_catalog.txt') ra_obs = [] dec_obs = [] unique_id = [] with open(phosim_catalog_file,'r') as input_file: for line in input_file: params = line.strip().split() if params[0] != 'object': if params[0] == 'rightascension': ra_pointing = float(params[1]) if params[0] == 'declination': dec_pointing = float(params[1]) if params[0] == 'rotskypos': rotskypos = float(params[1]) continue unique_id.append(int(params[1])) ra_obs.append(float(params[2])) dec_obs.append(float(params[3])) unique_id = np.array(unique_id) ra_obs = np.array(ra_obs) dec_obs = np.array(dec_obs) x_pup, y_pup = _rawPupilCoordsFromObserved(np.radians(ra_obs), np.radians(dec_obs), np.radians(ra_pointing), np.radians(dec_pointing), np.radians(rotskypos))
sorted_dex = np.argsort(unique_id) unique_id = unique_id[sorted_dex] x_pup = x_pup[sorted_dex] y_pup = y_pup[sorted_dex]
(x_pup_test, y_pup_test) = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
sorted_dex = np.argsort(self._truth_data['id']) truth_id = self._truth_data['id'][sorted_dex] x_pup_test = x_pup_test[sorted_dex] y_pup_test = y_pup_test[sorted_dex]
np.testing.assert_array_equal(unique_id, truth_id) distance = np.sqrt((x_pup-x_pup_test)**2 + (y_pup-y_pup_test)**2)
self.assertLess(distance.max(), 1.0e-12)
""" Test that using pupilCoordsFromRaDec and focalPlaneCoordsFromPupilCoordsLSST gives answers consistent with PhoSim """ camera = lsst_camera() pix_transformer = DMtoCameraPixelTransformer()
x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
(xf_no_optics, yf_no_optics) = focalPlaneCoordsFromPupilCoords(x_pup, y_pup, camera=lsst_camera())
for band in 'ugrizy':
n_check = 0 d_max = None n_old_better = 0 n_new_better = 0
(xf_optics, yf_optics) = focalPlaneCoordsFromPupilCoordsLSST(x_pup, y_pup, band)
for det in camera: if det.getType() != SCIENCE: continue det_name = det.getName() name = det_name.replace(':','').replace(',','').replace(' ','_') key_tuple = (name, band) if key_tuple not in self._phosim_data: continue phosim_data = self._phosim_data[key_tuple]
pixel_to_focal = det.getTransform(PIXELS, FOCAL_PLANE)
(xdm_arr, ydm_arr) = pix_transformer.dmPixFromCameraPix(phosim_data['xcam'], phosim_data['ycam'], det_name)
for id_val, xdm, ydm in zip(phosim_data['id'],xdm_arr, ydm_arr):
dex = np.where(self._truth_data['id'] == id_val) xf = xf_optics[dex] yf = yf_optics[dex]
pixel_pt = geom.Point2D(xdm, ydm) focal_pt = pixel_to_focal.applyForward(pixel_pt)
dist = np.sqrt((xf-focal_pt.getX())**2+(yf-focal_pt.getY())**2) r_center = np.sqrt(focal_pt.getX()**2 + focal_pt.getY()**2)
old_dist = np.sqrt((xf_no_optics[dex]-focal_pt.getX())**2 + (yf_no_optics[dex]-focal_pt.getY())**2)
msg = '\nObject %d' % id_val msg += '\nchip %s' % det_name msg += '\nband %s' % band msg += '\ndistance from center: %.4e' % r_center msg += '\nPupil: %.4e %.4e' % (x_pup[dex], y_pup[dex]) msg += '\nPhosim: %.4f %.4f' % (focal_pt.getX(),focal_pt.getY()) msg += '\nCatSim: %.4f %.4f'% (xf, yf) msg += '\nPixels: %.4f %.4f' % (xdm, ydm) msg += '\nnew dist %.4e old_dist %.4e' % (dist, old_dist)
if dist<old_dist: n_new_better += 1 else: n_old_better += 1
# Near the center of the focal plane, the old transformation # with no filter-dependence is actually better, but neither # is off by more than a pixel # # It also occasionally happens that the old transformation # was slightly better at the very edge of the focal plane # (in some filters) if old_dist<dist: if r_center < 100.0: # if we in the heart of the focal plane, make # sure that the fit has not degraded by more # than half a pixel and that the difference # between CatSim and PhoSim is still less # than a pixel self.assertLess(dist-old_dist, 0.005, msg=msg) self.assertLess(dist, 0.01, msg=msg) else: # if we are near the edge of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than 2 pixels self.assertLess(dist, 0.02, msg=msg) else: if r_center < 100.0: # if we are in the heart of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than a pixel self.assertLess(dist, 0.01, msg=msg) else: # If we are at the edge of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than five pixels, # and if the difference is less than 2 pixels, # make sure that the difference under the old # transformation is more than 15 pixels (indicating # that we are in a difficult-to-fit part of the # focal plane) self.assertLess(dist, 0.05, msg=msg) if dist > 0.02: self.assertGreater(old_dist, 0.15, msg=msg)
n_check += 1
self.assertGreater(n_check, 200) self.assertGreater(n_new_better, 4*n_old_better)
""" Test that focalPlaneCoordsFromPupilCoordsLSST acting on numpy arrays gives the same result as acting on scalars """ rng = np.random.RandomState(192312) camera = lsst_camera() pix_transformer = DMtoCameraPixelTransformer()
x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
for band in 'ugrizy': x_f, y_f = focalPlaneCoordsFromPupilCoordsLSST(x_pup, y_pup, band=band)
subsample = rng.choice(np.arange(len(x_pup), dtype=int), size=50, replace=False) for ii in subsample: x_f1, y_f1 = focalPlaneCoordsFromPupilCoordsLSST(x_pup[ii], y_pup[ii], band=band)
self.assertIsInstance(x_f1, numbers.Number) self.assertIsInstance(y_f1, numbers.Number) self.assertAlmostEqual(x_f1, x_f[ii], 8) self.assertAlmostEqual(y_f1, y_f[ii], 8)
""" Test that pixelCoordsFromRaDecLSST() works correctly """ pix_transformer = DMtoCameraPixelTransformer()
x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
(x_pix_no_optics, y_pix_no_optics) = pixelCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, camera=lsst_camera())
for band in 'ugrizy':
x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
(x_f, y_f) = focalPlaneCoordsFromPupilCoordsLSST(x_pup, y_pup, band=band)
r_center = np.sqrt(x_f**2 + y_f**2)
n_check = 0 n_diff_chip = 0 n_old_better = 0 n_new_better = 0
dist_arr = []
for det in lsst_camera(): if det.getType() != SCIENCE: continue det_name = det.getName() name = det_name.replace(':','').replace(',','').replace(' ','_') key_tuple = (name, band) if key_tuple not in self._phosim_data: continue phosim_data = self._phosim_data[key_tuple]
for id_val, xcam, ycam in zip(phosim_data['id'], phosim_data['xcam'], phosim_data['ycam']):
dex = np.where(self._truth_data['id'] == id_val) self.assertEqual(len(dex[0]), 1) dex = dex[0][0] x_pix_val = x_pix[dex] y_pix_val = y_pix[dex] if np.isnan(x_pix_val): # PhoSim centroid files will report flux from bright # stars that spill over onto neighboring chips. In # this case, CatSim will report chipName=None and # xpix=ypix=Nan. In these cases, we will force # CatSim to calculate the pixel coordinates of the # object on the chip that PhoSim is reporting and # compare that result to the contents of the PhoSim # centroid file. # n_diff_chip += 1
(x_pix_val, y_pix_val) = pixelCoordsFromRaDecLSST(self._truth_data['ra'][dex], self._truth_data['dec'][dex], chipName = det_name, pm_ra=self._truth_data['pmra'][dex], pm_dec=self._truth_data['pmdec'][dex], parallax=self._truth_data['px'][dex], v_rad=self._truth_data['vrad'][dex], obs_metadata=self._obs, band=band)
self.assertIsInstance(x_pix_val, np.float) self.assertIsInstance(y_pix_val, np.float)
x_pix_no_optics_val = x_pix_no_optics[dex] y_pix_no_optics_val = y_pix_no_optics[dex] if np.isnan(x_pix_no_optics_val):
x, y = pixelCoordsFromRaDec(self._truth_data['ra'][dex], self._truth_data['dec'][dex], chipName = det_name, pm_ra=self._truth_data['pmra'][dex], pm_dec=self._truth_data['pmdec'][dex], parallax=self._truth_data['px'][dex], v_rad=self._truth_data['vrad'][dex], obs_metadata=self._obs, camera=lsst_camera())
x_pix_no_optics_val = x y_pix_no_optics_val = y
self.assertIsInstance(x_pix_no_optics_val, np.float) self.assertIsInstance(y_pix_no_optics_val, np.float)
x_dm, y_dm = pix_transformer.dmPixFromCameraPix(xcam, ycam, det_name) dd = np.sqrt((x_dm-x_pix_val)**2 + (y_dm-y_pix_val)**2) dist_arr.append(dd) dd_no_optics = np.sqrt((x_dm-x_pix_no_optics_val)**2 + (y_dm-y_pix_no_optics_val)**2)
msg = '\nObject %d; chip %s' % (id_val, det_name) msg += '\nband %s' % band msg += '\ndist from center %.4e pixels' % (r_center[dex]/0.01) msg += '\nPupil: %.4e %.4e' % (x_pup[dex], x_pup[dex]) msg += '\nPhoSim: %.4f %.4f' % (x_dm, y_dm) msg += '\nCatSim: %.4f %.4f -- %.4e' % (x_pix_val, y_pix_val, dd) msg += '\nno Optics: %.4f %.4f -- %.4e' % (x_pix_no_optics_val, y_pix_no_optics_val, dd_no_optics)
if dd<dd_no_optics: n_new_better += 1 else: n_old_better += 1
# Near the center of the focal plane, the old transformation # with no filter-dependence is actually better, but neither # is off by more than a pixel # # It also occasionally happens that the old transformation # was slightly better at the very edge of the focal plane # (in some filters) if dd_no_optics<dd: if r_center[dex] < 100.0: # if we in the heart of the focal plane, make # sure that the fit has not degraded by more # than half a pixel and that the difference # between CatSim and PhoSim is still less # than a pixel self.assertLess(dd-dd_no_optics, 5.0, msg=msg) self.assertLess(dd, 1.0, msg=msg) else: # if we are near the edge of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than 2 pixels self.assertLess(dd, 2.0, msg=msg) else: if r_center[dex] < 100.0: # if we are in the heart of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than a pixel self.assertLess(dd, 1.0, msg=msg) else: # If we are at the edge of the focal plane, # make sure that the difference between # CatSim and PhoSim is less than five pixels, # and if the difference is less than 2 pixels, # make sure that the difference under the old # transformation is more than 15 pixels (indicating # that we are in a difficult-to-fit part of the # focal plane) self.assertLess(dd, 5.0, msg=msg) if dd > 2.0: self.assertGreater(dd_no_optics, 15.0, msg=msg)
n_check += 1
if dd > 1.0: if dd_no_optics>15.0: self.assertLess(dd, 5.0, msg=msg) else: self.assertLess(dd, 2.0, msg=msg)
self.assertGreater(n_check, 200) self.assertLess(n_diff_chip, n_check//2) self.assertGreater(n_new_better, 4*n_old_better) dist_arr = np.array(dist_arr) dist_arr = np.sort(dist_arr)
""" Test that pixelCoordsFromRaDecLSST works correctly on scalars """
rng = np.random.RandomState(1845332)
for band in 'ugrizy':
x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
self.assertIsInstance(x_pix, np.ndarray) self.assertIsInstance(y_pix, np.ndarray)
n_nan = 0 n_good = 0 subsample = rng.choice(np.arange(len(x_pix), dtype=int), size=50, replace=False) for ii in subsample: # only test on a subsample; this is slow x_pix1, y_pix1 = pixelCoordsFromRaDecLSST(self._truth_data['ra'][ii], self._truth_data['dec'][ii], pm_ra=self._truth_data['pmra'][ii], pm_dec=self._truth_data['pmdec'][ii], parallax=self._truth_data['px'][ii], v_rad=self._truth_data['vrad'][ii], obs_metadata=self._obs, band=band)
self.assertIsInstance(x_pix1, numbers.Number) self.assertIsInstance(y_pix1, numbers.Number) if not np.isnan(x_pix1): self.assertAlmostEqual(x_pix1, x_pix[ii], 8) self.assertAlmostEqual(y_pix1, y_pix[ii], 8) n_good += 1 else: n_nan += 1
self.assertLess(n_nan, n_good//2)
""" Test that pupilCoordsFromFocalPlaneCoordsLSST inverts focalPlaneCoordsFromPupilCoordsLSST """ x_f = np.arange(-317.0, 317.0, 20.0) y_f = np.arange(-317.0, 317.0, 20.0) mesh = np.meshgrid(x_f, y_f) x_f = mesh[0].flatten() y_f = mesh[1].flatten() for band in 'ugrizy': x_p, y_p = pupilCoordsFromFocalPlaneCoordsLSST(x_f, y_f, band=band) x_f1, y_f1 = focalPlaneCoordsFromPupilCoordsLSST(x_p, y_p, band=band)
dd = np.sqrt((x_f-x_f1)**2 + (y_f-y_f1)**2) self.assertLess(dd.max(), 3.0e-6)
""" Test that pupilCoordsFromFocalPlaneCoordsLSST works on scalars """ rng = np.random.RandomState(8123412) x_f = np.arange(-317.0, 317.0, 20.0) y_f = np.arange(-317.0, 317.0, 20.0) mesh = np.meshgrid(x_f, y_f) x_f = mesh[0].flatten() y_f = mesh[1].flatten()
for band in 'ugrizy': x_p, y_p = pupilCoordsFromFocalPlaneCoordsLSST(x_f, y_f, band=band) self.assertIsInstance(x_p, np.ndarray) self.assertIsInstance(y_p, np.ndarray) subsample = rng.choice(np.arange(len(x_p), dtype=int), size=50, replace=False) for ii in subsample: x_p1, y_p1 = pupilCoordsFromFocalPlaneCoordsLSST(x_f[ii], y_f[ii], band=band)
self.assertIsInstance(x_p1, numbers.Number) self.assertIsInstance(y_p1, numbers.Number) self.assertAlmostEqual(x_p1, x_p[ii], 16) self.assertAlmostEqual(y_p1, y_p[ii], 16)
""" Test that chipNameFromRaDecLSST is consistent with chipNameFromPupilCoordsLSST """ x_pup, y_pup = pupilCoordsFromRaDec(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs)
for band in 'ugrizy': chip_name_list = chipNameFromPupilCoordsLSST(x_pup, y_pup, band=band) chip_name_list_1 = chipNameFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
np.testing.assert_array_equal(chip_name_list, chip_name_list_1) n_none = np.where(np.char.find(chip_name_list.astype(str), 'None')==0) self.assertLess(len(n_none[0]), len(chip_name_list)//4)
""" Test that chipNameFromRaDecLSST works on scalars """ rng = np.random.RandomState(65673) for band in 'ugrizy': chip_name_list = chipNameFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
self.assertIsInstance(chip_name_list, np.ndarray) n_none = 0 n_not_none = 0 subsample = rng.choice(np.arange(len(chip_name_list), dtype=int), size=50, replace=False) for ii in subsample: name = chipNameFromRaDecLSST(self._truth_data['ra'][ii], self._truth_data['dec'][ii], pm_ra=self._truth_data['pmra'][ii], pm_dec=self._truth_data['pmdec'][ii], parallax=self._truth_data['px'][ii], v_rad=self._truth_data['vrad'][ii], obs_metadata=self._obs, band=band)
if name is not None: n_not_none += 1 self.assertIsInstance(name, str) else: n_none += 1
self.assertEqual(name, chip_name_list[ii])
self.assertGreater(n_not_none, n_none//2)
""" Test the radians versions of pixelCoordsFromRaDecLSST and chipNameFromRaDecLSST """ for band in 'ugrizy':
x_pix, y_pix = pixelCoordsFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
(x_pix_r, y_pix_r) = _pixelCoordsFromRaDecLSST(np.radians(self._truth_data['ra']), np.radians(self._truth_data['dec']), pm_ra=radiansFromArcsec(self._truth_data['pmra']), pm_dec=radiansFromArcsec(self._truth_data['pmdec']), parallax=radiansFromArcsec(self._truth_data['px']), v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
np.testing.assert_array_equal(x_pix, x_pix_r) np.testing.assert_array_equal(y_pix, y_pix_r)
chip_name_list = chipNameFromRaDecLSST(self._truth_data['ra'], self._truth_data['dec'], pm_ra=self._truth_data['pmra'], pm_dec=self._truth_data['pmdec'], parallax=self._truth_data['px'], v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
chip_name_list_r = _chipNameFromRaDecLSST(np.radians(self._truth_data['ra']), np.radians(self._truth_data['dec']), pm_ra=radiansFromArcsec(self._truth_data['pmra']), pm_dec=radiansFromArcsec(self._truth_data['pmdec']), parallax=radiansFromArcsec(self._truth_data['px']), v_rad=self._truth_data['vrad'], obs_metadata=self._obs, band=band)
np.testing.assert_array_equal(chip_name_list, chip_name_list_r)
""" Test that pupilCoordsFromPixelCoordsLSST inverts pixelCoordsFromPupilCoordsLSST """ xpix = np.arange(-2000.0, 2000.0, 100.0) ypix = np.arange(-2000.0, 2000.0, 100.0) mesh = np.meshgrid(xpix, ypix) xpix = mesh[0].flatten() ypix = mesh[1].flatten()
chip_name = 'R:3,1 S:1,2'
chip_name_list = ['None'] for det in lsst_camera(): if det.getType() == SCIENCE: chip_name_list.append(det.getName()) chip_name_list = np.array(chip_name_list) rng = np.random.RandomState(81231) chip_name_sample = rng.choice(chip_name_list, size=len(xpix), replace=True)
for band in 'ugrizy': xpup, ypup = pupilCoordsFromPixelCoordsLSST(xpix, ypix, chipName=chip_name, band=band)
xpix1, ypix1 = pixelCoordsFromPupilCoordsLSST(xpup, ypup, chipName=chip_name, band=band)
dd = np.sqrt((xpix-xpix1)**2 + (ypix-ypix1)**2) self.assertLess(dd.max(), 1.0e-4)
xpup, ypup = pupilCoordsFromPixelCoordsLSST(xpix, ypix, chipName=chip_name_sample, band=band)
xpix1, ypix1 = pixelCoordsFromPupilCoordsLSST(xpup, ypup, chipName=chip_name_sample, band=band)
valid = np.where(np.char.find(chip_name_sample, 'None')<0) self.assertGreater(len(valid[0]), 0) self.assertLess(len(valid[0]), len(xpix)) dd = np.sqrt((xpix[valid]-xpix1[valid])**2 + (ypix[valid]-ypix1[valid])**2) self.assertLess(dd.max(), 1.0e-4)
for dist in dd: self.assertFalse(np.isnan(dist))
invalid = np.where(np.char.find(chip_name_sample, 'None')==0) for ii in invalid[0]: self.assertTrue(np.isnan(xpix1[ii])) self.assertTrue(np.isnan(ypix1[ii]))
""" Test that raDecFromPixelCoordsLSST inverts pixelCoordsFromRaDecLSST """
rng = np.random.RandomState(1811231) n_samples = 500 rr = rng.random_sample(n_samples)*2.2 theta = rng.random_sample(n_samples)*2.0*np.pi ra = self._obs.pointingRA + rr*np.cos(theta) dec = self._obs.pointingDec + rr*np.sin(theta)
name_list = [None] for det in lsst_camera(): if det.getType() == SCIENCE: name_list.append(det.getName()) name_list = np.array(name_list) name_sample = rng.choice(name_list, size=n_samples, replace=True)
for band in 'ugrizy': xpix, ypix = pixelCoordsFromRaDecLSST(ra, dec, chipName=name_sample, band=band, obs_metadata=self._obs)
ra1, dec1 = raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, band=band, obs_metadata=self._obs)
valid = np.where(np.isfinite(ra1)) valid_name = np.where(np.char.find(name_sample.astype(str), 'None')<0) np.testing.assert_array_equal(valid[0], valid_name[0])
invalid = np.where(np.isnan(ra1)) invalid_name = np.where(np.char.find(name_sample.astype(str), 'None')==0) np.testing.assert_array_equal(invalid[0], invalid_name[0])
self.assertGreater(len(invalid[0]), 0) self.assertGreater(len(valid[0]), 0)
dist = angularSeparation(ra[valid], dec[valid], ra1[valid], dec1[valid]) dist *= 3600.0 self.assertLess(dist.max(), 1.0e-5)
# test one at a time for ii in range(len(ra1)): ra2, dec2 = raDecFromPixelCoordsLSST(xpix[ii], ypix[ii], chipName=str(name_sample[ii]), band=band, obs_metadata=self._obs)
self.assertIsInstance(ra2, numbers.Number) self.assertIsInstance(dec2, numbers.Number)
if name_sample[ii] is None: self.assertTrue(np.isnan(ra2)) self.assertTrue(np.isnan(dec2)) else: self.assertEqual(ra2, ra1[ii]) self.assertEqual(dec2, dec1[ii])
""" Test that radians version of raDecFromPixelCoordsLSST agrees with degrees version """ rng = np.random.RandomState(56123) n_samples = 500 name_list = [None] for det in lsst_camera(): if det.getType() == SCIENCE: name_list.append(det.getName()) name_list = np.array(name_list) name_sample = rng.choice(name_list, size=n_samples, replace=True) invalid = np.where(np.char.find(name_sample.astype(str), 'None')==0) self.assertLess(len(invalid[0]), n_samples//2)
xpix = rng.random_sample(n_samples)*4000.0 ypix = rng.random_sample(n_samples)*4000.0 for band in 'ugrizy': ra_deg, dec_deg = raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, obs_metadata=self._obs)
ra_rad, dec_rad = _raDecFromPixelCoordsLSST(xpix, ypix, chipName=name_sample, obs_metadata=self._obs)
valid = np.where(np.isfinite(ra_deg)) np.testing.assert_array_equal(np.degrees(ra_rad[valid]), ra_deg[valid]) np.testing.assert_array_equal(np.degrees(dec_rad[valid]), dec_deg[valid]) self.assertGreater(len(valid[0]), n_samples//2) for ii in invalid[0]: self.assertTrue(np.isnan(ra_rad[ii])) self.assertTrue(np.isnan(dec_rad[ii])) for ii in range(n_samples): ra1, dec1 = _raDecFromPixelCoordsLSST(xpix[ii], ypix[ii], chipName=str(name_sample[ii]), obs_metadata=self._obs)
self.assertIsInstance(ra1, numbers.Number) self.assertIsInstance(dec1, numbers.Number) if name_sample[ii] is None: self.assertTrue(np.isnan(ra1)) self.assertTrue(np.isnan(dec1)) else: self.assertEqual(ra1, ra_rad[ii]) self.assertEqual(dec1, dec_rad[ii])
""" Test that points outside the focal plane get NaNs for pupil and focal plane coords """ rng = np.random.RandomState(66) n_samples = 100 rr = rng.random_sample(n_samples)*600.0 theta = rng.random_sample(n_samples)*2.0*np.pi self.assertGreater(rr.max(), 500.0) xf = rr*np.cos(theta) yf = rr*np.sin(theta) xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(xf, yf, band='g') name_list = chipNameFromPupilCoordsLSST(xp, yp, band='g') xpix, ypix = pixelCoordsFromPupilCoordsLSST(xp, yp, chipName='R:2,2 S:1,1', band='g')
ra, dec = raDecFromPixelCoordsLSST(xpix, ypix, 'R:2,2 S:1,1', obs_metadata=self._obs, band='g')
xpix2, ypix2 = pixelCoordsFromPupilCoordsLSST(xp, yp, band='g') invalid = np.where(rr>500.0)[0] self.assertGreater(len(invalid), 0) self.assertLess(len(invalid), n_samples) non_nan_pix = 0 non_none_name = 0 for ii in range(n_samples): if ii in invalid: self.assertTrue(np.isnan(xp[ii])) self.assertTrue(np.isnan(yp[ii])) self.assertTrue(np.isnan(xpix[ii])) self.assertTrue(np.isnan(ypix[ii])) self.assertTrue(np.isnan(xpix2[ii])) self.assertTrue(np.isnan(ypix2[ii])) self.assertTrue(np.isnan(ra[ii])) self.assertTrue(np.isnan(dec[ii])) self.assertIsNone(name_list[ii]) else: self.assertFalse(np.isnan(xp[ii])) self.assertFalse(np.isnan(yp[ii])) self.assertFalse(np.isnan(xpix[ii])) self.assertFalse(np.isnan(ypix[ii])) self.assertFalse(np.isnan(ra[ii])) self.assertFalse(np.isnan(dec[ii]))
# this test is because, even if an object # has finite pupil or focal plane coordinates, # it could still land in a chip gap, causing # chip_name=None, xpix=ypix=NaN if not np.isnan(xpix2[ii]) and not np.isnan(ypix2[ii]): non_nan_pix += 1 if name_list[ii] is not None: non_none_name += 1
self.assertGreater(non_nan_pix, 0) self.assertGreater(non_none_name, 0)
rr = rng.random_sample(n_samples)*0.05 xp = rr*np.cos(theta) yp = rr*np.sin(theta)
xf2, yf2 = focalPlaneCoordsFromPupilCoordsLSST(xp, yp, band='i') xpix, ypix = pixelCoordsFromPupilCoordsLSST(xp, yp, chipName='R:2,2 S:1,1', band='i')
ra, dec = raDecFromPixelCoordsLSST(xpix, ypix, 'R:2,2 S:1,1', obs_metadata=self._obs, band='i')
xpix2, ypix2 = pixelCoordsFromPupilCoordsLSST(xp, yp, band='g')
invalid = np.where(rr>0.04841)[0] self.assertGreater(len(invalid), 0) self.assertLess(len(invalid), n_samples) non_nan_pix = 0 for ii in range(n_samples): if ii in invalid: self.assertTrue(np.isnan(xf2[ii])) self.assertTrue(np.isnan(yf2[ii])) self.assertTrue(np.isnan(xpix[ii])) self.assertTrue(np.isnan(ypix[ii])) self.assertTrue(np.isnan(xpix2[ii])) self.assertTrue(np.isnan(ypix2[ii])) self.assertTrue(np.isnan(ra[ii])) self.assertTrue(np.isnan(dec[ii])) else: self.assertFalse(np.isnan(xf2[ii])) self.assertFalse(np.isnan(yf2[ii])) self.assertFalse(np.isnan(xpix[ii])) self.assertFalse(np.isnan(ypix[ii])) self.assertFalse(np.isnan(ra[ii])) self.assertFalse(np.isnan(dec[ii]))
# this test is because, even if an object # has finite pupil or focal plane coordinates, # it could still land in a chip gap, causing # chip_name=None, xpix=ypix=NaN if not np.isnan(xpix2[ii]) and not np.isnan(ypix2[ii]): non_nan_pix += 1
self.assertGreater(non_nan_pix, 0)
xf = np.array([1.1, 2.1, np.NaN, 4.5]) yf = np.array([2.1, np.NaN, 1.2, 3.0]) xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(xf, yf, band='r') self.assertTrue(np.isnan(xp[2])) self.assertTrue(np.isnan(yp[2])) self.assertTrue(np.isnan(xp[1])) self.assertTrue(np.isnan(yp[1])) self.assertFalse(np.isnan(xp[0])) self.assertFalse(np.isnan(yp[0])) self.assertFalse(np.isnan(xp[3])) self.assertFalse(np.isnan(yp[3]))
xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(np.NaN, 1.0, band='g') self.assertTrue(np.isnan(xp)) self.assertTrue(np.isnan(yp))
xp, yp = pupilCoordsFromFocalPlaneCoordsLSST(2.1, np.NaN, band='g') self.assertTrue(np.isnan(xp)) self.assertTrue(np.isnan(yp))
xp = np.array([0.0011, 0.0021, np.NaN, 0.0045]) yp = np.array([0.0021, np.NaN, 0.0012, 0.0030]) xf, yf = focalPlaneCoordsFromPupilCoordsLSST(xp, yp, band='r') self.assertTrue(np.isnan(xf[2])) self.assertTrue(np.isnan(yf[2])) self.assertTrue(np.isnan(xf[1])) self.assertTrue(np.isnan(yf[1])) self.assertFalse(np.isnan(xf[0])) self.assertFalse(np.isnan(yf[0])) self.assertFalse(np.isnan(xf[3])) self.assertFalse(np.isnan(yf[3]))
xf, yf = focalPlaneCoordsFromPupilCoordsLSST(np.NaN, 0.001, band='g') self.assertTrue(np.isnan(xf)) self.assertTrue(np.isnan(yf))
xf, yf = pupilCoordsFromFocalPlaneCoordsLSST(0.002, np.NaN, band='g') self.assertTrue(np.isnan(xf)) self.assertTrue(np.isnan(yf))
lsst.utils.tests.init() unittest.main() |