def test_pixelCoords(self): """ Verify that pixelCoordsFromRaDecLSST has not changed """ pix_x, pix_y = pixelCoordsFromRaDec(self.pix_data['ra'], self.pix_data['dec'], obs_metadata=self.obs, camera=self.camera) np.testing.assert_array_almost_equal(pix_x, self.pix_data['pixel_x'], decimal=3) np.testing.assert_array_almost_equal(pix_y, self.pix_data['pixel_y'], decimal=3)
def testObjectPlacement(self): """ Test that GalSim places objects on the correct pixel by drawing images containing single objects and no background, reading those images back in, and comparing the flux-averaged centroids of the images with the expected pixel positions of the input objects. """ scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testLSSTObjectPlacement-') if os.path.exists(scratchDir): shutil.rmtree(scratchDir) os.mkdir(scratchDir) detector = lsst_camera()['R:0,3 S:2,2'] det_name = 'R03_S22' magNorm = 19.0 pixel_transformer = DMtoCameraPixelTransformer() for band in 'ugrizy': obs = self.obs_dict[band] catName = os.path.join(scratchDir, 'placementCatalog.dat') imageRoot = os.path.join(scratchDir, 'placementImage') dbFileName = os.path.join(scratchDir, 'placementInputCatalog.dat') imageName = '%s_%s_%s.fits' % (imageRoot, det_name, obs.bandpass) ra_c, dec_c = raDecFromPixelCoordsLSST(2000.0, 2000.0, detector.getName(), band=obs.bandpass, obs_metadata=obs) nSamples = 30 rng = np.random.RandomState(42) fwhm = 0.12 for iteration in range(nSamples): if os.path.exists(dbFileName): os.unlink(dbFileName) ra_obj = ra_c + rng.random_sample()*0.2 - 0.1 dec_obj = dec_c + rng.random_sample()*0.2 - 0.1 dmx_wrong, dmy_wrong = pixelCoordsFromRaDec(ra_obj, dec_obj, chipName=detector.getName(), obs_metadata=obs, camera=lsst_camera()) dmx_pix, dmy_pix = pixelCoordsFromRaDecLSST(ra_obj, dec_obj, chipName=detector.getName(), obs_metadata=obs, band=obs.bandpass) x_pix, y_pix = pixel_transformer.cameraPixFromDMPix(dmx_pix, dmy_pix, detector.getName()) x_pix_wrong, y_pix_wrong = pixel_transformer.cameraPixFromDMPix(dmx_wrong, dmy_wrong, detector.getName()) d_ra = 360.0*(ra_obj - obs.pointingRA) # in arcseconds d_dec = 360.0*(dec_obj - obs.pointingDec) create_text_catalog(obs, dbFileName, np.array([d_ra]), np.array([d_dec]), mag_norm=[magNorm]) db = LSSTPlacementFileDBObj(dbFileName, runtable='test') cat = LSSTPlacementCatalog(db, obs_metadata=obs) cat.camera_wrapper = LSSTCameraWrapper() psf = SNRdocumentPSF(fwhm=fwhm) cat.setPSF(psf) cat.write_catalog(catName) cat.write_images(nameRoot=imageRoot) im = afwImage.ImageF(imageName).getArray() tot_flux = im.sum() self.assertGreater(tot_flux, 10.0) y_centroid = sum([ii*im[ii,:].sum() for ii in range(im.shape[0])])/tot_flux x_centroid = sum([ii*im[:,ii].sum() for ii in range(im.shape[1])])/tot_flux dd = np.sqrt((x_pix-x_centroid)**2 + (y_pix-y_centroid)**2) self.assertLess(dd, 0.5*fwhm) dd_wrong = np.sqrt((x_pix_wrong-x_centroid)**2 + (y_pix_wrong-y_centroid)**2) self.assertLess(dd, dd_wrong) if os.path.exists(dbFileName): os.unlink(dbFileName) if os.path.exists(catName): os.unlink(catName) if os.path.exists(imageName): os.unlink(imageName) if os.path.exists(scratchDir): shutil.rmtree(scratchDir)
def pixelCoordsFromRaDec(self, ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None, obs_metadata=None, chipName=None, camera=None, epoch=2000.0, includeDistortion=True): """ Get the pixel positions (or nan if not on a chip) for objects based on their RA, and Dec (in degrees) Parameters ---------- ra is in degrees in the International Celestial Reference System. Can be either a float or a numpy array. dec is in degrees in the International Celestial Reference System. Can be either a float or a numpy array. pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr) Can be a numpy array or a number or None (default=None). pm_dec is proper motion in dec (arcsec/yr) Can be a numpy array or a number or None (default=None). parallax is parallax in arcsec Can be a numpy array or a number or None (default=None). v_rad is radial velocity (km/s) Can be a numpy array or a number or None (default=None). obs_metadata is an ObservationMetaData characterizing the telescope pointing. epoch is the epoch in Julian years of the equinox against which RA is measured. Default is 2000. chipName designates the names of the chips on which the pixel coordinates will be reckoned. Can be either single value, an array, or None. If an array, there must be as many chipNames as there are (RA, Dec) pairs. If a single value, all of the pixel coordinates will be reckoned on the same chip. If None, this method will calculate which chip each(RA, Dec) pair actually falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate chip. Default is None. includeDistortion is a boolean. If True (default), then this method will return the true pixel coordinates with optical distortion included. If False, this method will return TAN_PIXEL coordinates, which are the pixel coordinates with estimated optical distortion removed. See the documentation in afw.cameraGeom for more details. Returns ------- a 2-D numpy array in which the first row is the x pixel coordinate and the second row is the y pixel coordinate """ return coordUtils.pixelCoordsFromRaDec( ra, dec, pm_ra=pm_ra, pm_dec=pm_dec, parallax=parallax, v_rad=v_rad, obs_metadata=obs_metadata, chipName=chipName, camera=self._camera, epoch=epoch, includeDistortion=includeDistortion)
def test_pixel_coords_from_ra_dec_degrees(self): """ Test that pixelCoordsFromRaDec and pixelCoordsFromRaDecLSST agree """ raP = 74.2 decP = 13.0 obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=13.0, mjd=43441.0) n_obj = 1000 rng = np.random.RandomState(83241) rr = rng.random_sample(n_obj) * 1.75 theta = rng.random_sample(n_obj) * 2.0 * np.pi ra_list = raP + rr * np.cos(theta) dec_list = decP + rr * np.sin(theta) x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, obs_metadata=obs, camera=self.camera) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj / 10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj / 10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs) np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) # test when we force a chipName x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, chipName=['R:2,2 S:1,1'], obs_metadata=obs, camera=self.camera) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj / 10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj / 10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST( ra_list, dec_list, chipName=['R:2,2 S:1,1'], obs_metadata=obs) np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) # test without distortion x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, obs_metadata=obs, camera=self.camera, includeDistortion=False) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj / 10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj / 10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST( ra_list, dec_list, obs_metadata=obs, includeDistortion=False) np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) # test that exceptions are raised when incomplete ObservationMetaData are used obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, mjd=59580.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs) self.assertIn("rotSkyPos", context.exception.args[0]) obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=35.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs) self.assertIn("mjd", context.exception.args[0]) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list) self.assertIn("ObservationMetaData", context.exception.args[0]) # check that exceptions are raised when ra_list, dec_list are of the wrong shape obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=24.0, mjd=43000.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list[:5], obs_metadata=obs) self.assertIn("pixelCoordsFromRaDecLSST", context.exception.args[0])
def test_alert_data_generation(self): dmag_cutoff = 0.005 mag_name_to_int = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z' : 4, 'y': 5} _max_var_param_str = self.max_str_len class StarAlertTestDBObj(StellarAlertDBObjMixin, CatalogDBObject): objid = 'star_alert' tableid = 'stars' idColKey = 'simobjid' raColName = 'ra' decColName = 'dec' objectTypeId = 0 columns = [('raJ2000', 'ra*0.01745329252'), ('decJ2000', 'dec*0.01745329252'), ('parallax', 'px*0.01745329252/3600.0'), ('properMotionRa', 'pmra*0.01745329252/3600.0'), ('properMotionDec', 'pmdec*0.01745329252/3600.0'), ('radialVelocity', 'vrad'), ('variabilityParameters', 'varParamStr', str, _max_var_param_str)] class TestAlertsVarCatMixin(object): @register_method('alert_test') def applyAlertTest(self, valid_dexes, params, expmjd, variability_cache=None): if len(params) == 0: return np.array([[], [], [], [], [], []]) if isinstance(expmjd, numbers.Number): dmags_out = np.zeros((6, self.num_variable_obj(params))) else: dmags_out = np.zeros((6, self.num_variable_obj(params), len(expmjd))) for i_star in range(self.num_variable_obj(params)): if params['amp'][i_star] is not None: dmags = params['amp'][i_star]*np.cos(params['per'][i_star]*expmjd) for i_filter in range(6): dmags_out[i_filter][i_star] = dmags return dmags_out class TestAlertsVarCat(TestAlertsVarCatMixin, AlertStellarVariabilityCatalog): pass class TestAlertsTruthCat(TestAlertsVarCatMixin, CameraCoords, AstrometryStars, Variability, InstanceCatalog): column_outputs = ['uniqueId', 'chipName', 'dmagAlert', 'magAlert'] camera = obs_lsst_phosim.PhosimMapper().camera @compound('delta_umag', 'delta_gmag', 'delta_rmag', 'delta_imag', 'delta_zmag', 'delta_ymag') def get_TruthVariability(self): return self.applyVariability(self.column_by_name('varParamStr')) @cached def get_dmagAlert(self): return self.column_by_name('delta_%smag' % self.obs_metadata.bandpass) @cached def get_magAlert(self): return self.column_by_name('%smag' % self.obs_metadata.bandpass) + \ self.column_by_name('dmagAlert') star_db = StarAlertTestDBObj(database=self.star_db_name, driver='sqlite') # assemble the true light curves for each object; we need to figure out # if their np.max(dMag) ever goes over dmag_cutoff; then we will know if # we are supposed to simulate them true_lc_dict = {} true_lc_obshistid_dict = {} is_visible_dict = {} obs_dict = {} max_obshistid = -1 n_total_observations = 0 for obs in self.obs_list: obs_dict[obs.OpsimMetaData['obsHistID']] = obs obshistid = obs.OpsimMetaData['obsHistID'] if obshistid > max_obshistid: max_obshistid = obshistid cat = TestAlertsTruthCat(star_db, obs_metadata=obs) for line in cat.iter_catalog(): if line[1] is None: continue n_total_observations += 1 if line[0] not in true_lc_dict: true_lc_dict[line[0]] = {} true_lc_obshistid_dict[line[0]] = [] true_lc_dict[line[0]][obshistid] = line[2] true_lc_obshistid_dict[line[0]].append(obshistid) if line[0] not in is_visible_dict: is_visible_dict[line[0]] = False if line[3] <= self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]]: is_visible_dict[line[0]] = True obshistid_bits = int(np.ceil(np.log(max_obshistid)/np.log(2))) skipped_due_to_mag = 0 objects_to_simulate = [] obshistid_unqid_set = set() for obj_id in true_lc_dict: dmag_max = -1.0 for obshistid in true_lc_dict[obj_id]: if np.abs(true_lc_dict[obj_id][obshistid]) > dmag_max: dmag_max = np.abs(true_lc_dict[obj_id][obshistid]) if dmag_max >= dmag_cutoff: if not is_visible_dict[obj_id]: skipped_due_to_mag += 1 continue objects_to_simulate.append(obj_id) for obshistid in true_lc_obshistid_dict[obj_id]: obshistid_unqid_set.add((obj_id << obshistid_bits) + obshistid) self.assertGreater(len(objects_to_simulate), 10) self.assertGreater(skipped_due_to_mag, 0) log_file_name = tempfile.mktemp(dir=self.output_dir, suffix='log.txt') alert_gen = AlertDataGenerator(testing=True) alert_gen.subdivide_obs(self.obs_list, htmid_level=6) for htmid in alert_gen.htmid_list: alert_gen.alert_data_from_htmid(htmid, star_db, photometry_class=TestAlertsVarCat, output_prefix='alert_test', output_dir=self.output_dir, dmag_cutoff=dmag_cutoff, log_file_name=log_file_name) dummy_sed = Sed() bp_dict = BandpassDict.loadTotalBandpassesFromFiles() phot_params = PhotometricParameters() # First, verify that the contents of the sqlite files are all correct n_tot_simulated = 0 alert_query = 'SELECT alert.uniqueId, alert.obshistId, meta.TAI, ' alert_query += 'meta.band, quiescent.flux, alert.dflux, ' alert_query += 'quiescent.snr, alert.snr, ' alert_query += 'alert.ra, alert.dec, alert.chipNum, ' alert_query += 'alert.xPix, alert.yPix, ast.pmRA, ast.pmDec, ' alert_query += 'ast.parallax ' alert_query += 'FROM alert_data AS alert ' alert_query += 'INNER JOIN metadata AS meta ON meta.obshistId=alert.obshistId ' alert_query += 'INNER JOIN quiescent_flux AS quiescent ' alert_query += 'ON quiescent.uniqueId=alert.uniqueId ' alert_query += 'AND quiescent.band=meta.band ' alert_query += 'INNER JOIN baseline_astrometry AS ast ' alert_query += 'ON ast.uniqueId=alert.uniqueId' alert_dtype = np.dtype([('uniqueId', int), ('obshistId', int), ('TAI', float), ('band', int), ('q_flux', float), ('dflux', float), ('q_snr', float), ('tot_snr', float), ('ra', float), ('dec', float), ('chipNum', int), ('xPix', float), ('yPix', float), ('pmRA', float), ('pmDec', float), ('parallax', float)]) sqlite_file_list = os.listdir(self.output_dir) n_tot_simulated = 0 obshistid_unqid_simulated_set = set() for file_name in sqlite_file_list: if not file_name.endswith('db'): continue full_name = os.path.join(self.output_dir, file_name) self.assertTrue(os.path.exists(full_name)) alert_db = DBObject(full_name, driver='sqlite') alert_data = alert_db.execute_arbitrary(alert_query, dtype=alert_dtype) if len(alert_data) == 0: continue mjd_list = ModifiedJulianDate.get_list(TAI=alert_data['TAI']) for i_obj in range(len(alert_data)): n_tot_simulated += 1 obshistid_unqid_simulated_set.add((alert_data['uniqueId'][i_obj] << obshistid_bits) + alert_data['obshistId'][i_obj]) unq = alert_data['uniqueId'][i_obj] obj_dex = (unq//1024)-1 self.assertAlmostEqual(self.pmra_truth[obj_dex], 0.001*alert_data['pmRA'][i_obj], 4) self.assertAlmostEqual(self.pmdec_truth[obj_dex], 0.001*alert_data['pmDec'][i_obj], 4) self.assertAlmostEqual(self.px_truth[obj_dex], 0.001*alert_data['parallax'][i_obj], 4) ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex], self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex], self.px_truth[obj_dex], self.vrad_truth[obj_dex], mjd=mjd_list[i_obj]) distance = angularSeparation(ra_truth, dec_truth, alert_data['ra'][i_obj], alert_data['dec'][i_obj]) distance_arcsec = 3600.0*distance msg = '\ntruth: %e %e\nalert: %e %e\n' % (ra_truth, dec_truth, alert_data['ra'][i_obj], alert_data['dec'][i_obj]) self.assertLess(distance_arcsec, 0.0005, msg=msg) obs = obs_dict[alert_data['obshistId'][i_obj]] chipname = chipNameFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex], pm_ra=self.pmra_truth[obj_dex], pm_dec=self.pmdec_truth[obj_dex], parallax=self.px_truth[obj_dex], v_rad=self.vrad_truth[obj_dex], obs_metadata=obs, camera=self.camera) chipnum = int(chipname.replace('R', '').replace('S', ''). replace(' ', '').replace(';', '').replace(',', ''). replace(':', '')) self.assertEqual(chipnum, alert_data['chipNum'][i_obj]) xpix, ypix = pixelCoordsFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex], pm_ra=self.pmra_truth[obj_dex], pm_dec=self.pmdec_truth[obj_dex], parallax=self.px_truth[obj_dex], v_rad=self.vrad_truth[obj_dex], obs_metadata=obs, camera=self.camera) self.assertAlmostEqual(alert_data['xPix'][i_obj], xpix, 4) self.assertAlmostEqual(alert_data['yPix'][i_obj], ypix, 4) dmag_sim = -2.5*np.log10(1.0+alert_data['dflux'][i_obj]/alert_data['q_flux'][i_obj]) self.assertAlmostEqual(true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]], dmag_sim, 3) mag_name = ('u', 'g', 'r', 'i', 'z', 'y')[alert_data['band'][i_obj]] m5 = obs.m5[mag_name] q_mag = dummy_sed.magFromFlux(alert_data['q_flux'][i_obj]) self.assertAlmostEqual(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex], q_mag, 4) snr, gamma = calcSNR_m5(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex], bp_dict[mag_name], self.obs_mag_cutoff[alert_data['band'][i_obj]], phot_params) self.assertAlmostEqual(snr/alert_data['q_snr'][i_obj], 1.0, 4) tot_mag = self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex] + \ true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]] snr, gamma = calcSNR_m5(tot_mag, bp_dict[mag_name], m5, phot_params) self.assertAlmostEqual(snr/alert_data['tot_snr'][i_obj], 1.0, 4) for val in obshistid_unqid_set: self.assertIn(val, obshistid_unqid_simulated_set) self.assertEqual(len(obshistid_unqid_set), len(obshistid_unqid_simulated_set)) astrometry_query = 'SELECT uniqueId, ra, dec, TAI ' astrometry_query += 'FROM baseline_astrometry' astrometry_dtype = np.dtype([('uniqueId', int), ('ra', float), ('dec', float), ('TAI', float)]) tai_list = [] for obs in self.obs_list: tai_list.append(obs.mjd.TAI) tai_list = np.array(tai_list) n_tot_ast_simulated = 0 for file_name in sqlite_file_list: if not file_name.endswith('db'): continue full_name = os.path.join(self.output_dir, file_name) self.assertTrue(os.path.exists(full_name)) alert_db = DBObject(full_name, driver='sqlite') astrometry_data = alert_db.execute_arbitrary(astrometry_query, dtype=astrometry_dtype) if len(astrometry_data) == 0: continue mjd_list = ModifiedJulianDate.get_list(TAI=astrometry_data['TAI']) for i_obj in range(len(astrometry_data)): n_tot_ast_simulated += 1 obj_dex = (astrometry_data['uniqueId'][i_obj]//1024) - 1 ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex], self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex], self.px_truth[obj_dex], self.vrad_truth[obj_dex], mjd=mjd_list[i_obj]) distance = angularSeparation(ra_truth, dec_truth, astrometry_data['ra'][i_obj], astrometry_data['dec'][i_obj]) self.assertLess(3600.0*distance, 0.0005) del alert_gen gc.collect() self.assertGreater(n_tot_simulated, 10) self.assertGreater(len(obshistid_unqid_simulated_set), 10) self.assertLess(len(obshistid_unqid_simulated_set), n_total_observations) self.assertGreater(n_tot_ast_simulated, 0)
def test_generic_camera_wrapper(self): """ Test that GalSimCameraWrapper wraps its methods as expected. This is mostly to catch changes in afw API. """ camera = camTestUtils.CameraWrapper().camera camera_wrapper = GalSimCameraWrapper(camera) obs_mjd = ObservationMetaData(mjd=60000.0) ra, dec = raDecFromAltAz(35.0, 112.0, obs_mjd) obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, mjd=obs_mjd.mjd, rotSkyPos=22.4) rng = np.random.RandomState(8124) for detector in camera: name = detector.getName() bbox = camera[name].getBBox() bbox_wrapper = camera_wrapper.getBBox(name) self.assertEqual(bbox.getMinX(), bbox_wrapper.getMinX()) self.assertEqual(bbox.getMaxX(), bbox_wrapper.getMaxX()) self.assertEqual(bbox.getMinY(), bbox_wrapper.getMinY()) self.assertEqual(bbox.getMaxY(), bbox_wrapper.getMaxY()) center_point = camera[name].getCenter(FOCAL_PLANE) pixel_system = camera[name].makeCameraSys(PIXELS) center_pix = camera.transform(center_point, FOCAL_PLANE, pixel_system) center_pix_wrapper = camera_wrapper.getCenterPixel(name) self.assertEqual(center_pix.getX(), center_pix_wrapper.getX()) self.assertEqual(center_pix.getY(), center_pix_wrapper.getY()) pupil_system = camera[name].makeCameraSys(FIELD_ANGLE) center_pupil = camera.transform(center_point, FOCAL_PLANE, pupil_system) center_pupil_wrapper = camera_wrapper.getCenterPupil(name) self.assertEqual(center_pupil.getX(), center_pupil_wrapper.getX()) self.assertEqual(center_pupil.getY(), center_pupil_wrapper.getY()) corner_pupil_wrapper = camera_wrapper.getCornerPupilList(name) corner_point_list = camera[name].getCorners(FOCAL_PLANE) for point in corner_point_list: point_pupil = camera.transform(point, FOCAL_PLANE, pupil_system) dd_min = 1.0e10 for wrapper_point in corner_pupil_wrapper: dd = np.sqrt( (point_pupil.getX() - wrapper_point.getX())**2 + (point_pupil.getY() - wrapper_point.getY())**2) if dd < dd_min: dd_min = dd self.assertLess(dd_min, 1.0e-20) xpix_min = None xpix_max = None ypix_min = None ypix_max = None focal_to_tan_pix = camera[name].getTransform( FOCAL_PLANE, TAN_PIXELS) for point in corner_point_list: pixel_point = focal_to_tan_pix.applyForward(point) xx = pixel_point.getX() yy = pixel_point.getY() if xpix_min is None or xx < xpix_min: xpix_min = xx if ypix_min is None or yy < ypix_min: ypix_min = yy if xpix_max is None or xx > xpix_max: xpix_max = xx if ypix_max is None or yy > ypix_max: ypix_max = yy pix_bounds_wrapper = camera_wrapper.getTanPixelBounds(name) self.assertEqual(pix_bounds_wrapper[0], xpix_min) self.assertEqual(pix_bounds_wrapper[1], xpix_max) self.assertEqual(pix_bounds_wrapper[2], ypix_min) self.assertEqual(pix_bounds_wrapper[3], ypix_max) x_pup = rng.random_sample(10) * 0.005 - 0.01 y_pup = rng.random_sample(10) * 0.005 - 0.01 x_pix, y_pix = pixelCoordsFromPupilCoords(x_pup, y_pup, chipName=name, camera=camera) (x_pix_wrapper, y_pix_wrapper) = camera_wrapper.pixelCoordsFromPupilCoords( x_pup, y_pup, name, obs) nan_x = np.where(np.isnan(x_pix)) self.assertEqual(len(nan_x[0]), 0) np.testing.assert_array_equal(x_pix, x_pix_wrapper) np.testing.assert_array_equal(y_pix, y_pix_wrapper) x_pix = rng.random_sample(10) * 100.0 - 200.0 y_pix = rng.random_sample(10) * 100.0 - 200.0 x_pup, y_pup = pupilCoordsFromPixelCoords(x_pix, y_pix, chipName=name, camera=camera) (x_pup_wrapper, y_pup_wrapper) = camera_wrapper.pupilCoordsFromPixelCoords( x_pix, y_pix, name, obs) nan_x = np.where(np.isnan(x_pup)) self.assertEqual(len(nan_x[0]), 0) np.testing.assert_array_equal(x_pup, x_pup_wrapper) np.testing.assert_array_equal(y_pup, y_pup_wrapper) ra, dec = raDecFromPixelCoords(x_pix, y_pix, name, camera=camera, obs_metadata=obs) (ra_wrapper, dec_wrapper) = camera_wrapper.raDecFromPixelCoords( x_pix, y_pix, name, obs) nan_ra = np.where(np.isnan(ra)) self.assertEqual(len(nan_ra[0]), 0) np.testing.assert_array_equal(ra, ra_wrapper) np.testing.assert_array_equal(dec, dec_wrapper) ra, dec = _raDecFromPixelCoords(x_pix, y_pix, name, camera=camera, obs_metadata=obs) (ra_wrapper, dec_wrapper) = camera_wrapper._raDecFromPixelCoords( x_pix, y_pix, name, obs) nan_ra = np.where(np.isnan(ra)) self.assertEqual(len(nan_ra[0]), 0) np.testing.assert_array_equal(ra, ra_wrapper) np.testing.assert_array_equal(dec, dec_wrapper) ra = obs.pointingRA + (rng.random_sample(10) * 150.0 - 100.0) / 160.0 dec = obs.pointingDec + (rng.random_sample(10) * 150.0 - 100.0) / 160.0 x_pix, y_pix = pixelCoordsFromRaDec(ra, dec, chipName=name, camera=camera, obs_metadata=obs) (x_pix_wrapper, y_pix_wrapper) = camera_wrapper.pixelCoordsFromRaDec( ra, dec, chipName=name, obs_metadata=obs) nan_x = np.where(np.isnan(x_pix)) self.assertEqual(len(nan_x[0]), 0) np.testing.assert_array_equal(x_pix, x_pix_wrapper) np.testing.assert_array_equal(y_pix, y_pix_wrapper) ra = np.radians(ra) dec = np.radians(dec) x_pix, y_pix = _pixelCoordsFromRaDec(ra, dec, chipName=name, camera=camera, obs_metadata=obs) (x_pix_wrapper, y_pix_wrapper) = camera_wrapper._pixelCoordsFromRaDec( ra, dec, chipName=name, obs_metadata=obs) nan_x = np.where(np.isnan(x_pix)) self.assertEqual(len(nan_x[0]), 0) np.testing.assert_array_equal(x_pix, x_pix_wrapper) np.testing.assert_array_equal(y_pix, y_pix_wrapper) del camera
chip_name_grid = chipNameFromRaDec(ra_grid, dec_grid, obs_metadata=obs, camera=camera) valid = np.where(np.char.find(chip_name_grid.astype(str), 'None')<0) ra_grid = ra_grid[valid] dec_grid = dec_grid[valid] chip_name_grid = chip_name_grid[valid] focal_x, focal_y = focalPlaneCoordsFromRaDec(ra_grid, dec_grid, obs_metadata=obs, camera=camera) pix_x, pix_y = pixelCoordsFromRaDec(ra_grid, dec_grid, chipName=chip_name_grid, obs_metadata=obs, camera=camera) with open('lsst_pixel_data.txt', 'w') as out_file: out_file.write(header_msg) out_file.write('# ra dec chipName focal_x focal_y pix_x pix_y\n') for i_obj in range(len(ra_grid)): out_file.write('%.2f;%.2f;%s;%.5f;%.5f;%.5f;%.5f\n' % (ra_grid[i_obj], dec_grid[i_obj], chip_name_grid[i_obj], focal_x[i_obj], focal_y[i_obj], pix_x[i_obj], pix_y[i_obj])) detector_name_list = [dd.getName() for dd in camera] detector_name_list.sort()
camera=camera) valid = np.where(np.char.find(chip_name_grid.astype(str), 'None') < 0) ra_grid = ra_grid[valid] dec_grid = dec_grid[valid] chip_name_grid = chip_name_grid[valid] focal_x, focal_y = focalPlaneCoordsFromRaDec(ra_grid, dec_grid, obs_metadata=obs, camera=camera) pix_x, pix_y = pixelCoordsFromRaDec(ra_grid, dec_grid, chipName=chip_name_grid, obs_metadata=obs, camera=camera) with open('lsst_pixel_data.txt', 'w') as out_file: out_file.write(header_msg) out_file.write('# ra dec chipName focal_x focal_y pix_x pix_y\n') for i_obj in range(len(ra_grid)): out_file.write( '%.2f;%.2f;%s;%.5f;%.5f;%.5f;%.5f\n' % (ra_grid[i_obj], dec_grid[i_obj], chip_name_grid[i_obj], focal_x[i_obj], focal_y[i_obj], pix_x[i_obj], pix_y[i_obj])) detector_name_list = [dd.getName() for dd in camera] detector_name_list.sort()
def test_pixel_coords_from_ra_dec_degrees(self): """ Test that pixelCoordsFromRaDec and pixelCoordsFromRaDecLSST agree """ raP = 74.2 decP = 13.0 obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=13.0, mjd=43441.0) n_obj = 1000 rng = np.random.RandomState(83241) rr = rng.random_sample(n_obj)*1.75 theta = rng.random_sample(n_obj)*2.0*np.pi ra_list = raP + rr*np.cos(theta) dec_list = decP + rr*np.sin(theta) x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, obs_metadata=obs, camera=self.camera, includeDistortion=False) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj/10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj/10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs, includeDistortion=False) try: np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) except AssertionError: n_problematic = 0 for xx, yy, xt, yt in zip(x_pix, y_pix, x_pix_test, y_pix_test): if xx!=xt or yy!=yt: if (not np.isnan(xx) and not np.isnan(xt) and not np.isnan(yy) and not np.isnan(yt)): print(xx,yy,xt,yt) n_problematic += 1 if n_problematic>0: raise # test when we force a chipName x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, chipName=['R:2,2 S:1,1'], obs_metadata=obs, camera=self.camera, includeDistortion=False) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj/10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj/10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST(ra_list, dec_list, chipName=['R:2,2 S:1,1'], obs_metadata=obs, includeDistortion=False) np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) # test without distortion x_pix, y_pix = pixelCoordsFromRaDec(ra_list, dec_list, obs_metadata=obs, camera=self.camera, includeDistortion=False) self.assertLessEqual(len(np.where(np.isnan(x_pix))[0]), n_obj/10) self.assertLessEqual(len(np.where(np.isnan(y_pix))[0]), n_obj/10) x_pix_test, y_pix_test = pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs, includeDistortion=False) try: np.testing.assert_array_equal(x_pix, x_pix_test) np.testing.assert_array_equal(y_pix, y_pix_test) except AssertionError: n_problematic = 0 for xx, yy, xt, yt in zip(x_pix, y_pix, x_pix_test, y_pix_test): if xx!=xt or yy!=yt: if (not np.isnan(xx) and not np.isnan(xt) and not np.isnan(yy) and not np.isnan(yt)): print(xx,yy,xt,yt) n_problematic += 1 if n_problematic>0: raise # test that exceptions are raised when incomplete ObservationMetaData are used obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, mjd=59580.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs) self.assertIn("rotSkyPos", context.exception.args[0]) obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=35.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list, obs_metadata=obs) self.assertIn("mjd", context.exception.args[0]) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list) self.assertIn("ObservationMetaData", context.exception.args[0]) # check that exceptions are raised when ra_list, dec_list are of the wrong shape obs = ObservationMetaData(pointingRA=raP, pointingDec=decP, rotSkyPos=24.0, mjd=43000.0) with self.assertRaises(RuntimeError) as context: pixelCoordsFromRaDecLSST(ra_list, dec_list[:5], obs_metadata=obs) self.assertIn("same length", context.exception.args[0])