def _find_objects_on_chip(self, object_lines, chip_name): num_lines = len(object_lines) ra_phosim = np.zeros(num_lines, dtype=float) dec_phosim = np.zeros(num_lines, dtype=float) mag_norm = 55. * np.ones(num_lines, dtype=float) for i, line in enumerate(object_lines): if not line.startswith('object'): raise RuntimeError('Trying to process non-object entry from ' 'the instance catalog.') tokens = line.split() ra_phosim[i] = float(tokens[2]) dec_phosim[i] = float(tokens[3]) mag_norm[i] = float(tokens[4]) ra_appGeo, dec_appGeo \ = PhoSimAstrometryBase._appGeoFromPhoSim(np.radians(ra_phosim), np.radians(dec_phosim), self.obs_md) ra_obs_rad, dec_obs_rad \ = _observedFromAppGeo(ra_appGeo, dec_appGeo, obs_metadata=self.obs_md, includeRefraction=True) x_pupil, y_pupil = _pupilCoordsFromObserved(ra_obs_rad, dec_obs_rad, self.obs_md) on_chip_dict = _chip_downselect(mag_norm, x_pupil, y_pupil, self.logger, [chip_name]) index = on_chip_dict[chip_name] self.object_lines = [] for i in index[0]: self.object_lines.append(object_lines[i]) self.x_pupil = list(x_pupil[index]) self.y_pupil = list(y_pupil[index]) self.bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
def test_galaxy_astrometry_degrees(self): """ Test that we can go from raPhoSim, decPhoSim to ICRS coordinates in the case of galaxies (in degrees) """ db = testGalaxyDiskDBObj(driver='sqlite', database=self.db_name) cat = GalaxyTestCatalog(db, obs_metadata=self.obs) with lsst.utils.tests.getTempFilePath('.txt') as cat_name: cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) # verify that, when transforming back to ICRS, we are within # 10^-3 arcsec ra_icrs, dec_icrs = PhoSimAstrometryBase.icrsFromPhoSim( data['raPhoSim'], data['decPhoSim'], self.obs) dist = angularSeparation(data['raICRS'], data['decICRS'], ra_icrs, dec_icrs) dist = 3600.0 * dist self.assertLess(dist.max(), 0.001) # verify that the distance between raPhoSim, decPhoSim and # raICRS, decICRS is greater than the distance between # the original raICRS, decICRS and the newly-calculated # raICRS, decICRS dist_bad = angularSeparation(data['raPhoSim'], data['decPhoSim'], data['raICRS'], data['decICRS']) dist_bad = 3600.0 * dist_bad self.assertGreater(dist_bad.min(), dist.max()) del db
def test_de_precession(self): """ test de-precession by de-precessing a list of RA, Dec and verifying that the distance between the de-precessed points is the same as the distance between the input points. Also verify that the observed boresite gets de-precessed correctly """ rng = np.random.RandomState(12) n_samples = 5 pra = 34.0 pdec = 65.0 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec, mjd=58324.1) raObs, decObs = _observedFromICRS(np.array([np.radians(pra)]), np.array([np.radians(pdec)]), obs_metadata=obs, epoch=2000.0, includeRefraction=False) ra_list = [] dec_list = [] ra_list.append(raObs[0]) dec_list.append(decObs[0]) for rr, dd in zip( rng.random_sample(n_samples) * 2.0 * np.pi, (rng.random_sample(n_samples) - 0.5) * np.pi): ra_list.append(rr) dec_list.append(dd) ra_list = np.array(ra_list) dec_list = np.array(dec_list) raDecTransformed = PhoSimAstrometryBase()._dePrecess( ra_list, dec_list, obs) dd = arcsecFromRadians( haversine(np.radians(pra), np.radians(pdec), raDecTransformed[0][0], raDecTransformed[1][0])) self.assertLess(dd, 1.0e-6) dd0 = arcsecFromRadians( haversine(raObs[0], decObs[0], np.radians(pra), np.radians(pdec))) self.assertLess(dd, dd0) for ix in range(n_samples + 1): for iy in range(n_samples + 1): if ix != iy: dd1 = arcsecFromRadians( haversine(ra_list[ix], dec_list[ix], ra_list[iy], dec_list[iy])) dd2 = arcsecFromRadians( haversine(raDecTransformed[0][ix], raDecTransformed[1][ix], raDecTransformed[0][iy], raDecTransformed[1][iy])) self.assertAlmostEqual(dd1, dd2, delta=6)
def test_against_catalog(self): """ Compare deprecession results to a catalog that was validated with PhoSim. """ obs = ObservationMetaData(pointingRA=53.00913847303155535, pointingDec=-27.43894880881512321, rotSkyPos=256.75075318193080420, mjd=59580.13955500000156462, site=Site(name="LSST", pressure=0.0, humidity=0.0)) dtype = np.dtype([('id', int), ('ra', float), ('dec', float), ('ra_deprecessed', float), ('dec_deprecessed', float), ('x_dm', float), ('y_dm', float), ('x_focal', float), ('y_focal', float), ('x_cam', float), ('y_cam', float)]) data = np.genfromtxt(os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData', 'pixel_prediction_catalog.txt'), dtype=dtype) ra_obs, dec_obs = observedFromICRS(data['ra'], data['dec'], obs_metadata=obs, includeRefraction=False, epoch=2000.0) phosim_mixin = PhoSimAstrometryBase() ra_dep, dec_dep = phosim_mixin._dePrecess(np.radians(ra_obs), np.radians(dec_obs), obs) dd = 3600.0 * angularSeparation( data['ra_deprecessed'], data['dec_deprecessed'], np.degrees(ra_dep), np.degrees(dec_dep)) self.assertLess(dd.max(), 1.0e-5)
def test_against_catalog(self): """ Compare deprecession results to a catalog that was validated with PhoSim. """ obs = ObservationMetaData(pointingRA=53.00913847303155535, pointingDec=-27.43894880881512321, rotSkyPos=256.75075318193080420, mjd=59580.13955500000156462, site=Site(name="LSST", pressure=0.0, humidity=0.0)) dtype = np.dtype([('id', int), ('ra', float), ('dec', float), ('ra_deprecessed', float), ('dec_deprecessed', float), ('x_dm', float), ('y_dm', float), ('x_focal', float), ('y_focal', float), ('x_cam', float), ('y_cam', float)]) data = np.genfromtxt(os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData', 'pixel_prediction_catalog.txt'), dtype=dtype) ra_obs, dec_obs = observedFromICRS(data['ra'], data['dec'], obs_metadata=obs, includeRefraction=False, epoch=2000.0) phosim_mixin = PhoSimAstrometryBase() ra_dep, dec_dep = phosim_mixin._dePrecess(np.radians(ra_obs), np.radians(dec_obs), obs) dd = 3600.0*angularSeparation(data['ra_deprecessed'], data['dec_deprecessed'], np.degrees(ra_dep), np.degrees(dec_dep)) self.assertLess(dd.max(), 1.0e-5)
def test_stellar_astrometry_radians(self): """ Test that we can go from raPhoSim, decPhoSim to ICRS coordinates in the case of stars (in radians) """ cat_name = os.path.join(self.scratch_dir, 'phosim_ast_star_cat_rad.txt') if os.path.exists(cat_name): os.unlink(cat_name) db = testStarsDBObj(driver='sqlite', database=self.db_name) cat = StarTestCatalog(db, obs_metadata=self.obs) cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) ra_pho_rad = np.radians(data['raPhoSim']) dec_pho_rad = np.radians(data['decPhoSim']) # verify that, when transforming back to ICRS, we are within # 10^-3 arcsec ra_icrs, dec_icrs = PhoSimAstrometryBase._icrsFromPhoSim( ra_pho_rad, dec_pho_rad, self.obs) dist = _angularSeparation(np.radians(data['raICRS']), np.radians(data['decICRS']), ra_icrs, dec_icrs) dist = arcsecFromRadians(dist) self.assertLess(dist.max(), 0.001) # verify that the distance between raPhoSim, decPhoSim and # raICRS, decICRS is greater than the distance between # the original raICRS, decICRS and the newly-calculated # raICRS, decICRS dist_bad = _angularSeparation(ra_pho_rad, dec_pho_rad, np.radians(data['raICRS']), np.radians(data['decICRS'])) dist_bad = arcsecFromRadians(dist_bad) self.assertGreater(dist_bad.min(), dist.max()) if os.path.exists(cat_name): os.unlink(cat_name) del db
def test_stellar_astrometry_radians(self): """ Test that we can go from raPhoSim, decPhoSim to ICRS coordinates in the case of stars (in radians) """ db = testStarsDBObj(driver='sqlite', database=self.db_name) cat = StarTestCatalog(db, obs_metadata=self.obs) with lsst.utils.tests.getTempFilePath('.txt') as cat_name: cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float), ('raJ2000', float), ('decJ2000', float), ('pmRA', float), ('pmDec', float), ('parallax', float), ('vRad', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) ra_pho_rad = np.radians(data['raPhoSim']) dec_pho_rad = np.radians(data['decPhoSim']) # verify that, when transforming back to ICRS, we are within # 10^-3 arcsec ra_icrs, dec_icrs = PhoSimAstrometryBase._icrsFromPhoSim(ra_pho_rad, dec_pho_rad, self.obs) dist = _angularSeparation(np.radians(data['raICRS']), np.radians(data['decICRS']), ra_icrs, dec_icrs) dist = arcsecFromRadians(dist) self.assertLess(dist.max(), 0.001) # verify that the distance between raPhoSim, decPhoSim and # raICRS, decICRS is greater than the distance between # the original raICRS, decICRS and the newly-calculated # raICRS, decICRS dist_bad = _angularSeparation(ra_pho_rad, dec_pho_rad, np.radians(data['raICRS']), np.radians(data['decICRS'])) dist_bad = arcsecFromRadians(dist_bad) self.assertGreater(dist_bad.min(), dist.max()) del db
def test_stellar_observed_degrees(self): """ Test ability to go all the way to observed RA, Dec from PhoSim (this is necessary for the ImSim software that DESC is working on) """ db = testStarsDBObj(driver='sqlite', database=self.db_name) cat = StarTestCatalog(db, obs_metadata=self.obs) with lsst.utils.tests.getTempFilePath('.txt') as cat_name: cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float), ('raJ2000', float), ('decJ2000', float), ('pmRA', float), ('pmDec', float), ('parallax', float), ('vRad', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) (ra_obs, dec_obs) = observedFromICRS(np.degrees(data['raJ2000']), np.degrees(data['decJ2000']), obs_metadata=self.obs, pm_ra=arcsecFromRadians(data['pmRA']), pm_dec=arcsecFromRadians(data['pmDec']), parallax=arcsecFromRadians(data['parallax']), v_rad=data['vRad'], includeRefraction=True, epoch=2000.0) (ra_appGeo, dec_appGeo) = PhoSimAstrometryBase.appGeoFromPhoSim(data['raPhoSim'], data['decPhoSim'], self.obs) (ra_obs_2, dec_obs_2) = observedFromAppGeo(ra_appGeo, dec_appGeo, obs_metadata=self.obs, includeRefraction=True) dd = 3600.0*angularSeparation(ra_obs, dec_obs, ra_obs_2, dec_obs_2) self.assertLess(dd.max(), 1.0e-5)
def test_stellar_observed_radians(self): """ Test ability to go all the way to observed RA, Dec from PhoSim (this is necessary for the ImSim software that DESC is working on) """ db = testStarsDBObj(driver='sqlite', database=self.db_name) cat = StarTestCatalog(db, obs_metadata=self.obs) with lsst.utils.tests.getTempFilePath('.txt') as cat_name: cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float), ('raJ2000', float), ('decJ2000', float), ('pmRA', float), ('pmDec', float), ('parallax', float), ('vRad', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) (ra_obs, dec_obs) = _observedFromICRS(data['raJ2000'], data['decJ2000'], obs_metadata=self.obs, pm_ra=data['pmRA'], pm_dec=data['pmDec'], parallax=data['parallax'], v_rad=data['vRad'], includeRefraction=True, epoch=2000.0) (ra_appGeo, dec_appGeo) = PhoSimAstrometryBase._appGeoFromPhoSim( np.radians(data['raPhoSim']), np.radians(data['decPhoSim']), self.obs) (ra_obs_2, dec_obs_2) = _observedFromAppGeo(ra_appGeo, dec_appGeo, obs_metadata=self.obs, includeRefraction=True) dd = arcsecFromRadians( _angularSeparation(ra_obs, dec_obs, ra_obs_2, dec_obs_2)) self.assertLess(dd.max(), 1.0e-5)
def test_galaxy_astrometry_degrees(self): """ Test that we can go from raPhoSim, decPhoSim to ICRS coordinates in the case of galaxies (in degrees) """ db = testGalaxyDiskDBObj(driver='sqlite', database=self.db_name) cat = GalaxyTestCatalog(db, obs_metadata=self.obs) with lsst.utils.tests.getTempFilePath('.txt') as cat_name: cat.write_catalog(cat_name) dtype = np.dtype([('raICRS', float), ('decICRS', float), ('raPhoSim', float), ('decPhoSim', float)]) data = np.genfromtxt(cat_name, dtype=dtype) self.assertGreater(len(data), 100) # verify that, when transforming back to ICRS, we are within # 10^-3 arcsec ra_icrs, dec_icrs = PhoSimAstrometryBase.icrsFromPhoSim(data['raPhoSim'], data['decPhoSim'], self.obs) dist = angularSeparation(data['raICRS'], data['decICRS'], ra_icrs, dec_icrs) dist = 3600.0*dist self.assertLess(dist.max(), 0.001) # verify that the distance between raPhoSim, decPhoSim and # raICRS, decICRS is greater than the distance between # the original raICRS, decICRS and the newly-calculated # raICRS, decICRS dist_bad = angularSeparation(data['raPhoSim'], data['decPhoSim'], data['raICRS'], data['decICRS']) dist_bad = 3600.0*dist_bad self.assertGreater(dist_bad.min(), dist.max()) del db
obs = obs_list[0] filter_name = obs.bandpass site_no_atm = Site(name="LSST", pressure=0.0, humidity=0.0) obs.site = site_no_atm assert np.abs(obs.site.pressure) < 1.0e-6 assert np.abs(obs.site.humidity) < 1.0e-6 xpix_0 = np.arange(200.0, 3800.0, 1000.0) ypix_0 = np.arange(200.0, 3800.0, 1000.0) pix_grid = np.meshgrid(xpix_0, ypix_0) cam_xpix_in = pix_grid[0].flatten() cam_ypix_in = pix_grid[1].flatten() camera_wrapper = LSSTCameraWrapper() de_precessor = PhoSimAstrometryBase() phosim_header_map = copy.deepcopy(DefaultPhoSimHeaderMap) phosim_header_map['nsnap'] = 1 phosim_header_map['exptime'] = 30.0 i_obj = 0 with open('full_catalogs/star_grid_%d_%s.txt' % (args.obs, filter_name), 'w') as cat_file: write_phoSim_header(obs, cat_file, phosim_header_map) with open( 'full_catalogs/star_predicted_%d_%s.txt' % (args.obs, filter_name), 'w') as truth_file: truth_file.write( '# i_obj ra_icrs dec_icrs ra_deprecessed dec_deprecessed x_dm y_dm x_f y_f x_cam y_cam\n' )
def test_naive_focal_plane_position(self): """ Test deprecession of PhoSim coordinates by comparing the focal plane position predicted by CatSim from ICRS with the focal plane position predicted by CatSim from deprecessed coordinates. """ phosim_mixin = PhoSimAstrometryBase() mjd = 59587.2 # create site with no atmosphere so that we can avoid # refraction site = Site(name="LSST", pressure=0.0, humidity=0.0) obs = ObservationMetaData(mjd=mjd, site=site) ra, dec = raDecFromAltAz(31.0, 112.0, obs) d_sun = distanceToSun(ra, dec, obs.mjd) self.assertGreater(d_sun, 45.0) obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, rotSkyPos=27.3, mjd=mjd, site=site) ra_icrs = np.arange(obs.pointingRA-2.0, obs.pointingRA+2.0, 0.05) dec_icrs = np.arange(obs.pointingDec-2.0, obs.pointingDec+2.0, 0.05) coord_grid = np.meshgrid(ra_icrs, dec_icrs) ra_icrs = coord_grid[0].flatten() dec_icrs = coord_grid[1].flatten() (xpup_icrs, ypup_icrs) = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs, epoch=2000.0, includeRefraction=False) (x_focal_icrs, y_focal_icrs) = focalPlaneCoordsFromPupilCoords(xpup_icrs, ypup_icrs, camera=lsst_camera()) ra_obs, dec_obs = observedFromICRS(ra_icrs, dec_icrs, obs_metadata=obs, epoch=2000.0, includeRefraction=False) ra_obs_rad = np.radians(ra_obs) dec_obs_rad = np.radians(dec_obs) (ra_deprecessed_rad, dec_deprecessed_rad) = phosim_mixin._dePrecess(ra_obs_rad, dec_obs_rad, obs) (xpup_deprecessed, ypup_deprecessed) = _naivePupilCoordsFromObserved(ra_deprecessed_rad, dec_deprecessed_rad, obs._pointingRA, obs._pointingDec, obs._rotSkyPos) (x_focal_deprecessed, y_focal_deprecessed) = focalPlaneCoordsFromPupilCoords(xpup_deprecessed, ypup_deprecessed, camera=lsst_camera()) dd = np.sqrt((x_focal_icrs-x_focal_deprecessed)**2 +(y_focal_icrs-y_focal_deprecessed)**2) self.assertLess(dd.max(), 5.0e-8)
def sources_from_file(file_name, obs_md, phot_params, numRows=None): """ Read in an InstanceCatalog and extract all of the astrophysical sources from it Parameters ---------- file_name: str The name of the InstanceCatalog obs_md: ObservationMetaData The ObservationMetaData characterizing the pointing phot_params: PhotometricParameters The PhotometricParameters characterizing this telescope numRows: int (optional) The number of rows of the InstanceCatalog to read in (including the header) Returns ------- gs_obj_arr: numpy array Contains the GalSimCelestialObjects for all of the astrophysical sources in this InstanceCatalog out_obj_dict: dict Keyed on the names of the detectors in the LSST camera. The values are numpy arrays of GalSimCelestialObjects that should be simulated for that detector, including objects that are near the edge of the chip or just bright (in which case, they might still illuminate the detector). """ camera = get_obs_lsstSim_camera() num_objects = 0 ct_rows = 0 with fopen(file_name, mode='rt') as input_file: for line in input_file: ct_rows += 1 params = line.strip().split() if params[0] == 'object': num_objects += 1 if numRows is not None and ct_rows >= numRows: break # RA, Dec in the coordinate system expected by PhoSim ra_phosim = np.zeros(num_objects, dtype=float) dec_phosim = np.zeros(num_objects, dtype=float) sed_name = [None] * num_objects mag_norm = 55.0 * np.ones(num_objects, dtype=float) gamma1 = np.zeros(num_objects, dtype=float) gamma2 = np.zeros(num_objects, dtype=float) kappa = np.zeros(num_objects, dtype=float) internal_av = np.zeros(num_objects, dtype=float) internal_rv = np.zeros(num_objects, dtype=float) galactic_av = np.zeros(num_objects, dtype=float) galactic_rv = np.zeros(num_objects, dtype=float) semi_major_arcsec = np.zeros(num_objects, dtype=float) semi_minor_arcsec = np.zeros(num_objects, dtype=float) position_angle_degrees = np.zeros(num_objects, dtype=float) sersic_index = np.zeros(num_objects, dtype=float) npoints = np.zeros(num_objects, dtype=int) redshift = np.zeros(num_objects, dtype=float) unique_id = np.zeros(num_objects, dtype=int) object_type = np.zeros(num_objects, dtype=int) i_obj = -1 with fopen(file_name, mode='rt') as input_file: for line in input_file: params = line.strip().split() if params[0] != 'object': continue i_obj += 1 if numRows is not None and i_obj >= num_objects: break unique_id[i_obj] = int(params[1]) ra_phosim[i_obj] = float(params[2]) dec_phosim[i_obj] = float(params[3]) mag_norm[i_obj] = float(params[4]) sed_name[i_obj] = params[5] redshift[i_obj] = float(params[6]) gamma1[i_obj] = float(params[7]) gamma2[i_obj] = float(params[8]) kappa[i_obj] = float(params[9]) if params[12].lower() == 'point': object_type[i_obj] = _POINT_SOURCE i_gal_dust_model = 14 if params[13].lower() != 'none': i_gal_dust_model = 16 internal_av[i_obj] = float(params[14]) internal_rv[i_obj] = float(params[15]) if params[i_gal_dust_model].lower() != 'none': galactic_av[i_obj] = float(params[i_gal_dust_model + 1]) galactic_rv[i_obj] = float(params[i_gal_dust_model + 2]) elif params[12].lower() == 'sersic2d': object_type[i_obj] = _SERSIC_2D semi_major_arcsec[i_obj] = float(params[13]) semi_minor_arcsec[i_obj] = float(params[14]) position_angle_degrees[i_obj] = float(params[15]) sersic_index[i_obj] = float(params[16]) i_gal_dust_model = 18 if params[17].lower() != 'none': i_gal_dust_model = 20 internal_av[i_obj] = float(params[18]) internal_rv[i_obj] = float(params[19]) if params[i_gal_dust_model].lower() != 'none': galactic_av[i_obj] = float(params[i_gal_dust_model + 1]) galactic_rv[i_obj] = float(params[i_gal_dust_model + 2]) elif params[12].lower() == 'knots': object_type[i_obj] = _RANDOM_WALK semi_major_arcsec[i_obj] = float(params[13]) semi_minor_arcsec[i_obj] = float(params[14]) position_angle_degrees[i_obj] = float(params[15]) npoints[i_obj] = int(params[16]) i_gal_dust_model = 18 if params[17].lower() != 'none': i_gal_dust_model = 20 internal_av[i_obj] = float(params[18]) internal_rv[i_obj] = float(params[19]) if params[i_gal_dust_model].lower() != 'none': galactic_av[i_obj] = float(params[i_gal_dust_model + 1]) galactic_rv[i_obj] = float(params[i_gal_dust_model + 2]) else: raise RuntimeError("Do not know how to handle " "object type: %s" % params[12]) ra_appGeo, dec_appGeo = PhoSimAstrometryBase._appGeoFromPhoSim( np.radians(ra_phosim), np.radians(dec_phosim), obs_md) (ra_obs_rad, dec_obs_rad) = _observedFromAppGeo(ra_appGeo, dec_appGeo, obs_metadata=obs_md, includeRefraction=True) semi_major_radians = radiansFromArcsec(semi_major_arcsec) semi_minor_radians = radiansFromArcsec(semi_minor_arcsec) position_angle_radians = np.radians(position_angle_degrees) x_pupil, y_pupil = _pupilCoordsFromObserved(ra_obs_rad, dec_obs_rad, obs_md) bp_dict = BandpassDict.loadTotalBandpassesFromFiles() sed_dir = lsstUtils.getPackageDir('sims_sed_library') object_is_valid = np.array([True] * num_objects) invalid_objects = np.where( np.logical_or( np.logical_or( mag_norm > 50.0, np.logical_and(galactic_av == 0.0, galactic_rv == 0.0)), np.logical_or( np.logical_and(object_type == _SERSIC_2D, semi_major_arcsec < semi_minor_arcsec), np.logical_and(object_type == _RANDOM_WALK, npoints <= 0)))) object_is_valid[invalid_objects] = False if len(invalid_objects[0]) > 0: message = "\nOmitted %d suspicious objects from " % len( invalid_objects[0]) message += "the instance catalog:\n" n_bad_mag_norm = len(np.where(mag_norm > 50.0)[0]) message += " %d had mag_norm > 50.0\n" % n_bad_mag_norm n_bad_av = len( np.where(np.logical_and(galactic_av == 0.0, galactic_rv == 0.0))[0]) message += " %d had galactic_Av == galactic_Rv == 0\n" % n_bad_av n_bad_axes = len( np.where( np.logical_and(object_type == _SERSIC_2D, semi_major_arcsec < semi_minor_arcsec))[0]) message += " %d had semi_major_axis < semi_minor_axis\n" % n_bad_axes n_bad_knots = len( np.where(np.logical_and(object_type == _RANDOM_WALK, npoints <= 0))[0]) message += " %d had n_points <= 0 \n" % n_bad_knots warnings.warn(message) wav_int = None wav_gal = None gs_object_arr = [] for i_obj in range(num_objects): if not object_is_valid[i_obj]: continue if object_type[i_obj] == _POINT_SOURCE: gs_type = 'pointSource' elif object_type[i_obj] == _SERSIC_2D: gs_type = 'sersic' elif object_type[i_obj] == _RANDOM_WALK: gs_type = 'RandomWalk' # load the SED sed_obj = Sed() sed_obj.readSED_flambda(os.path.join(sed_dir, sed_name[i_obj])) fnorm = getImsimFluxNorm(sed_obj, mag_norm[i_obj]) sed_obj.multiplyFluxNorm(fnorm) if internal_av[i_obj] != 0.0: if wav_int is None or not np.array_equal(sed_obj.wavelen, wav_int): a_int, b_int = sed_obj.setupCCMab() wav_int = copy.deepcopy(sed_obj.wavelen) sed_obj.addCCMDust(a_int, b_int, A_v=internal_av[i_obj], R_v=internal_rv[i_obj]) if redshift[i_obj] != 0.0: sed_obj.redshiftSED(redshift[i_obj], dimming=True) sed_obj.resampleSED(wavelen_match=bp_dict.wavelenMatch) if galactic_av[i_obj] != 0.0: if wav_gal is None or not np.array_equal(sed_obj.wavelen, wav_gal): a_g, b_g = sed_obj.setupCCMab() wav_gal = copy.deepcopy(sed_obj.wavelen) sed_obj.addCCMDust(a_g, b_g, A_v=galactic_av[i_obj], R_v=galactic_rv[i_obj]) gs_object = GalSimCelestialObject(gs_type, x_pupil[i_obj], y_pupil[i_obj], semi_major_radians[i_obj], semi_minor_radians[i_obj], semi_major_radians[i_obj], position_angle_radians[i_obj], sersic_index[i_obj], sed_obj, bp_dict, phot_params, npoints[i_obj], gamma1=gamma1[i_obj], gamma2=gamma2[i_obj], kappa=kappa[i_obj], uniqueId=unique_id[i_obj]) gs_object_arr.append(gs_object) gs_object_arr = np.array(gs_object_arr) # how close to the edge of the detector a source has # to be before we will just simulate it anyway pix_tol = 50.0 # any source brighter than this will be considered # so bright that it should be simulated for all # detectors, just in case light scatters onto them. max_mag = 16.0 # down-select mag_norm, x_pupil, and y_pupil # to only contain those objects that were # deemed to be valid above valid = np.where(object_is_valid) mag_norm = mag_norm[valid] x_pupil = x_pupil[valid] y_pupil = y_pupil[valid] assert len(mag_norm) == len(gs_object_arr) assert len(x_pupil) == len(gs_object_arr) assert len(y_pupil) == len(gs_object_arr) out_obj_dict = {} for det in lsst_camera(): chip_name = det.getName() pixel_corners = getCornerPixels(chip_name, lsst_camera()) x_min = pixel_corners[0][0] x_max = pixel_corners[2][0] y_min = pixel_corners[0][1] y_max = pixel_corners[3][1] xpix, ypix = pixelCoordsFromPupilCoords(x_pupil, y_pupil, chipName=chip_name, camera=lsst_camera()) on_chip = np.where( np.logical_or( mag_norm < max_mag, np.logical_and( xpix > x_min - pix_tol, np.logical_and( xpix < x_max + pix_tol, np.logical_and(ypix > y_min - pix_tol, ypix < y_max + pix_tol))))) out_obj_dict[chip_name] = gs_object_arr[on_chip] return gs_object_arr, out_obj_dict
def test_naive_focal_plane_position(self): """ Test deprecession of PhoSim coordinates by comparing the focal plane position predicted by CatSim from ICRS with the focal plane position predicted by CatSim from deprecessed coordinates. """ phosim_mixin = PhoSimAstrometryBase() mjd = 59587.2 # create site with no atmosphere so that we can avoid # refraction site = Site(name="LSST", pressure=0.0, humidity=0.0) obs = ObservationMetaData(mjd=mjd, site=site) ra, dec = raDecFromAltAz(31.0, 112.0, obs) d_sun = distanceToSun(ra, dec, obs.mjd) self.assertGreater(d_sun, 45.0) obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, rotSkyPos=27.3, mjd=mjd, site=site) ra_icrs = np.arange(obs.pointingRA - 2.0, obs.pointingRA + 2.0, 0.05) dec_icrs = np.arange(obs.pointingDec - 2.0, obs.pointingDec + 2.0, 0.05) coord_grid = np.meshgrid(ra_icrs, dec_icrs) ra_icrs = coord_grid[0].flatten() dec_icrs = coord_grid[1].flatten() (xpup_icrs, ypup_icrs) = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs, epoch=2000.0, includeRefraction=False) (x_focal_icrs, y_focal_icrs) = focalPlaneCoordsFromPupilCoords(xpup_icrs, ypup_icrs, camera=lsst_camera()) ra_obs, dec_obs = observedFromICRS(ra_icrs, dec_icrs, obs_metadata=obs, epoch=2000.0, includeRefraction=False) ra_obs_rad = np.radians(ra_obs) dec_obs_rad = np.radians(dec_obs) (ra_deprecessed_rad, dec_deprecessed_rad) = phosim_mixin._dePrecess( ra_obs_rad, dec_obs_rad, obs) (xpup_deprecessed, ypup_deprecessed) = _naivePupilCoordsFromObserved( ra_deprecessed_rad, dec_deprecessed_rad, obs._pointingRA, obs._pointingDec, obs._rotSkyPos) (x_focal_deprecessed, y_focal_deprecessed) = focalPlaneCoordsFromPupilCoords( xpup_deprecessed, ypup_deprecessed, camera=lsst_camera()) dd = np.sqrt((x_focal_icrs - x_focal_deprecessed)**2 + (y_focal_icrs - y_focal_deprecessed)**2) self.assertLess(dd.max(), 1.0e-8)