def main(): """ Drive GalSim to simulate the LSST. """ # Setup a parser to take command line arguments parser = argparse.ArgumentParser() parser.add_argument('file', help="The instance catalog") parser.add_argument('-n', '--numrows', default=None, type=int, help="Read the first numrows of the file.") parser.add_argument('--outdir', type=str, default='fits', help='Output directory for eimage file') parser.add_argument( '--sensor', type=str, default=None, help='Sensor to simulate, e.g., "R:2,2 S:1,1".' + 'If None, then simulate all sensors with sources on them') parser.add_argument( '--config_file', type=str, default=None, help="Config file. If None, the default config will be used.") parser.add_argument('--log_level', type=str, choices=['DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL'], default='INFO', help='Logging level. Default: "INFO"') parser.add_argument( '--psf', type=str, default='Kolmogorov', choices=['DoubleGaussian', 'Kolmogorov'], help="PSF model to use; either the double Gaussian " "from LSE=40 (equation 30), or the Kolmogorov convolved " "with a Gaussian proposed by David Kirkby at the " "23 March 2017 SSims telecon") parser.add_argument('--checkpoint_file', type=str, default=None, help='Checkpoint file name.') parser.add_argument('--nobj_checkpoint', type=int, default=1000, help='# objects to process between checkpoints') parser.add_argument('--seed', type=int, default=267, help='integer used to seed random number generator') arguments = parser.parse_args() config = desc.imsim.read_config(arguments.config_file) logger = desc.imsim.get_logger(arguments.log_level) # Get the number of rows to read from the instance file. Use # default if not specified. numRows = arguments.numrows if numRows is not None: logger.info("Reading %i rows from the instance catalog %s.", numRows, arguments.file) else: logger.info("Reading all rows from the instance catalog %s.", arguments.file) camera_wrapper = LSSTCameraWrapper() catalog_contents = desc.imsim.parsePhoSimInstanceFile(arguments.file, numRows=numRows) obs_md = catalog_contents.obs_metadata phot_params = catalog_contents.phot_params sources = catalog_contents.sources gs_object_arr = sources[0] gs_object_dict = sources[1] # Sub-divide the source dataframe into stars and galaxies. if arguments.sensor is not None: detector_list = [ make_galsim_detector(camera_wrapper, arguments.sensor, phot_params, obs_md) ] else: detector_list = [] for det in camera_wrapper.camera: det_type = det.getType() if det_type != WAVEFRONT and det_type != GUIDER: detector_list.append( make_galsim_detector(camera_wrapper, det.getName(), phot_params, obs_md)) # Add noise and sky background # The simple code using the default lsst-GalSim interface would be: # # PhoSimStarCatalog.noise_and_background = ExampleCCDNoise(addNoise=True, # addBackground=True) # # But, we need a more realistic sky model and we need to pass more than # this basic info to use Peter Y's ESO sky model. # We must pass obs_metadata, chip information etc... noise_and_background \ = ESOSkyModel(obs_md, addNoise=True, addBackground=True) bp_dict = BandpassDict.loadTotalBandpassesFromFiles( bandpassNames=obs_md.bandpass) gs_interpreter = GalSimInterpreter(obs_metadata=obs_md, epoch=2000.0, detectors=detector_list, bandpassDict=bp_dict, noiseWrapper=noise_and_background, seed=arguments.seed) gs_interpreter.checkpoint_file = arguments.checkpoint_file gs_interpreter.nobj_checkpoint = arguments.nobj_checkpoint gs_interpreter.restore_checkpoint(camera_wrapper, phot_params, obs_md) # Add a PSF. if arguments.psf.lower() == "doublegaussian": # This one is taken from equation 30 of # www.astro.washington.edu/users/ivezic/Astr511/LSST_SNRdoc.pdf . # # Set seeing from self.obs_metadata. local_PSF = \ SNRdocumentPSF(obs_md.OpsimMetaData['FWHMgeom']) elif arguments.psf.lower() == "kolmogorov": # This PSF was presented by David Kirkby at the 23 March 2017 # Survey Simulations Working Group telecon # # https://confluence.slac.stanford.edu/pages/viewpage.action?spaceKey=LSSTDESC&title=SSim+2017-03-23 # equation 3 of Krisciunas and Schaefer 1991 airmass = 1.0 / np.sqrt( 1.0 - 0.96 * (np.sin(0.5 * np.pi - obs_md.OpsimMetaData['altitude']))**2) local_PSF = \ Kolmogorov_and_Gaussian_PSF(airmass=airmass, rawSeeing=obs_md.OpsimMetaData['rawSeeing'], band=obs_md.bandpass) else: raise RuntimeError("Do not know what to do with psf model: " "%s" % arguments.psf) gs_interpreter.setPSF(PSF=local_PSF) if arguments.sensor is not None: gs_objects_to_draw = gs_object_dict[arguments.sensor] else: gs_objects_to_draw = gs_object_arr for gs_obj in gs_objects_to_draw: if gs_obj.uniqueId in gs_interpreter.drawn_objects: continue gs_interpreter.drawObject(gs_obj) desc.imsim.add_cosmic_rays(gs_interpreter, phot_params) # Write out the fits files outdir = arguments.outdir if not os.path.isdir(outdir): os.makedirs(outdir) prefix = config['persistence']['eimage_prefix'] gs_interpreter.writeImages(nameRoot=os.path.join(outdir, prefix) + str(obs_md.OpsimMetaData['obshistID']))
def test_checkpointing(self): "Test checkpointing of .detectorImages data." camera = camTestUtils.CameraWrapper().camera camera_wrapper = GalSimCameraWrapper(camera) phot_params = PhotometricParameters() obs_md = ObservationMetaData(pointingRA=23.0, pointingDec=12.0, rotSkyPos=13.2, mjd=59580.0, bandpassName='r') detectors = [ make_galsim_detector(camera_wrapper, dd.getName(), phot_params, obs_md) for dd in camera_wrapper.camera ] # Create a GalSimInterpreter object and set the checkpoint # attributes. gs_interpreter = GalSimInterpreter(detectors=detectors) gs_interpreter.checkpoint_file = self.cp_file nobj = 10 gs_interpreter.nobj_checkpoint = nobj # Set the image data by hand. key = "R00_S00_r.fits" detname = "R:0,0 S:0,0" detector = make_galsim_detector(camera_wrapper, detname, phot_params, obs_md) image = gs_interpreter.blankImage(detector=detector) image += 17 gs_interpreter.detectorImages[key] = image # Add some drawn objects and check that the checkpoint file is # written at the right cadence. for uniqueId in range(1, nobj + 1): gs_interpreter.drawn_objects.add(uniqueId) gs_interpreter.write_checkpoint() if uniqueId < nobj: self.assertFalse(os.path.isfile(self.cp_file)) else: self.assertTrue(os.path.isfile(self.cp_file)) # Verify that the checkpointed data has the expected content. with open(self.cp_file, 'rb') as input_: cp_data = pickle.load(input_) self.assertTrue(np.array_equal(cp_data['images'][key], image.array)) # Check the restore_checkpoint function. new_interpreter = GalSimInterpreter(detectors=detectors) new_interpreter.checkpoint_file = self.cp_file new_interpreter.restore_checkpoint(camera_wrapper, phot_params, obs_md) self.assertEqual(new_interpreter.drawn_objects, gs_interpreter.drawn_objects) self.assertEqual(set(new_interpreter.detectorImages.keys()), set(gs_interpreter.detectorImages.keys())) for det_name in new_interpreter.detectorImages.keys(): new_img = new_interpreter.detectorImages[det_name] gs_img = gs_interpreter.detectorImages[det_name] np.testing.assert_array_equal(new_img.array, gs_img.array) self.assertEqual(new_img.bounds, gs_img.bounds) self.assertEqual(new_img.wcs.crpix1, gs_img.wcs.crpix1) self.assertEqual(new_img.wcs.crpix2, gs_img.wcs.crpix2) self.assertEqual(new_img.wcs.crval1, gs_img.wcs.crval1) self.assertEqual(new_img.wcs.crval2, gs_img.wcs.crval2) self.assertEqual(new_img.wcs.detectorName, gs_img.wcs.detectorName) for name in new_img.wcs.fitsHeader.names(): self.assertEqual(new_img.wcs.fitsHeader.get(name), gs_img.wcs.fitsHeader.get(name))