Example #1
0
    def test_read_tree_rings(self):
        """Check reading of tree_ring_parameters file"""
        camera_wrapper = LSSTCameraWrapper()
        desc.imsim.read_config()
        needed_stuff = desc.imsim.parsePhoSimInstanceFile(self.instcat_file, ())
        obs_md = needed_stuff.obs_metadata
        phot_params = needed_stuff.phot_params

        detector_list = []
        for sensor in self.sensors:
            detector_list.append(make_galsim_detector(camera_wrapper, sensor, phot_params, obs_md))

        gs_interpreter = GalSimInterpreter(detectors=detector_list)
        tr_filename = os.path.join(lsstUtils.getPackageDir('imsim'),
                                   'data', 'tree_ring_data',
                                   'tree_ring_parameters_19mar18.txt')
        desc.imsim.add_treering_info(gs_interpreter.detectors,
                                     tr_filename=tr_filename)

        for i, detector in enumerate(gs_interpreter.detectors):
            center = detector.tree_rings.center
            shifted_center = (center.x - detector._xCenterPix, center.y - detector._yCenterPix)
            self.assertAlmostEqual(shifted_center, self.centers[i], 1)
            r_value_test = detector.tree_rings.func(self.rtest)
            self.assertAlmostEqual(r_value_test, self.rvalues[i], 6)
def compare_to_imsim(phosim_commands):
    bandpass = bandpass_all[int(phosim_commands['filter'].values[0])]
    obs_md = ObservationMetaData(
        pointingRA=float(phosim_commands['rightascension'].values[0]),
        pointingDec=float(phosim_commands['declination'].values[0]),
        mjd=float(phosim_commands['mjd'].values[0]),
        rotSkyPos=float(phosim_commands['rotskypos'].values[0]),
        bandpassName=bandpass,
        m5=LSSTdefaults().m5(bandpass),
        seeing=float(phosim_commands['seeing'].values[0]))
    noise_and_background = ESOSkyModel(obs_md,
                                       addNoise=True,
                                       addBackground=True)
    phot_params = PhotometricParameters(
        exptime=float(phosim_commands['vistime'].values[0]),
        nexp=int(phosim_commands['nsnap'].values[0]),
        gain=1,
        readnoise=0,
        darkcurrent=0,
        bandpass=bandpass)
    # We are going to check one sensor only
    detector_list = [
        make_galsim_detector(camera_wrapper, "R:2,2 S:1,1", phot_params,
                             obs_md)
    ]
    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=1234)
    image = gs_interpreter.blankImage(detector=detector_list[0])
    image_2 = noise_and_background.addNoiseAndBackground(
        image,
        bandpass=obs_md.bandpass,
        m5=obs_md.m5,
        FWHMeff=obs_md.seeing,
        photParams=phot_params,
        chipName=detector_list[0].name)
    return compute_bkg(image_2.array)
Example #3
0
    def _initializeGalSimInterpreter(self):
        """
        This method creates the GalSimInterpreter (if it is None)

        This method reads in all of the data about the camera and pass it into
        the GalSimInterpreter.

        This method calls _getBandpasses to construct the paths to
        the files containing the bandpass data.
        """

        if not isinstance(self.camera_wrapper, GalSimCameraWrapper):
            raise RuntimeError("GalSimCatalog.camera_wrapper must be an instantiation of "
                               "GalSimCameraWrapper or one of its daughter classes\n"
                               "It is actually of type %s" % str(type(self.camera_wrapper)))

        if self.galSimInterpreter is None:

            # This list will contain instantiations of the GalSimDetector class
            # (see galSimInterpreter.py), which stores detector information in a way
            # that the GalSimInterpreter will understand
            detectors = []

            for dd in self.camera_wrapper.camera:
                if dd.getType() == WAVEFRONT or dd.getType() == GUIDER:
                    # This package does not yet handle the 90-degree rotation
                    # in WCS that occurs for wavefront or guide sensors
                    continue

                if self.allowed_chips is None or dd.getName() in self.allowed_chips:
                    centerPupil = self.camera_wrapper.getCenterPupil(dd.getName())
                    centerPixel = self.camera_wrapper.getCenterPixel(dd.getName())

                    translationPupil = self.camera_wrapper.pupilCoordsFromPixelCoords(centerPixel.getX()+1,
                                                                                      centerPixel.getY()+1,
                                                                                      dd.getName())

                    plateScale = np.sqrt(np.power(translationPupil[0]-centerPupil.getX(), 2) +
                                         np.power(translationPupil[1]-centerPupil.getY(), 2))/np.sqrt(2.0)

                    plateScale = 3600.0*np.degrees(plateScale)

                    # make a detector-custom photParams that copies all of the quantities
                    # in the catalog photParams, except the platescale, which is
                    # calculated above
                    params = PhotometricParameters(exptime=self.photParams.exptime,
                                                   nexp=self.photParams.nexp,
                                                   effarea=self.photParams.effarea,
                                                   gain=self.photParams.gain,
                                                   readnoise=self.photParams.readnoise,
                                                   darkcurrent=self.photParams.darkcurrent,
                                                   othernoise=self.photParams.othernoise,
                                                   platescale=plateScale)

                    detector = GalSimDetector(dd.getName(), self.camera_wrapper,
                                              obs_metadata=self.obs_metadata, epoch=self.db_obj.epoch,
                                              photParams=params)

                    detectors.append(detector)

            if not hasattr(self, 'bandpassDict'):
                if self.noise_and_background is not None:
                    if self.obs_metadata.m5 is None:
                        raise RuntimeError('WARNING  in GalSimCatalog; you did not specify m5 in your '
                                           'obs_metadata. m5 is required in order to '
                                           'add noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.m5:
                            raise RuntimeError('WARNING in GalSimCatalog; your obs_metadata does not have ' +
                                               'm5 values for all of your bandpasses \n' +
                                               'bandpass has: %s \n' % self.bandpassNames.__repr__() +
                                               'm5 has: %s ' % list(self.obs_metadata.m5.keys()).__repr__())

                    if self.obs_metadata.seeing is None:
                        raise RuntimeError('WARNING  in GalSimCatalog; you did not specify seeing in your '
                                           'obs_metadata.  seeing is required in order to add '
                                           'noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.seeing:
                            raise RuntimeError('WARNING in GalSimCatalog; your obs_metadata does not have ' +
                                               'seeing values for all of your bandpasses \n' +
                                               'bandpass has: %s \n' % self.bandpassNames.__repr__() +
                                               'seeing has: %s ' % list(self.obs_metadata.seeing.keys()).__repr__())

                (self.bandpassDict,
                 hardwareDict) = BandpassDict.loadBandpassesFromFiles(bandpassNames=self.bandpassNames,
                                                                      filedir=self.bandpassDir,
                                                                      bandpassRoot=self.bandpassRoot,
                                                                      componentList=self.componentList,
                                                                      atmoTransmission=os.path.join(self.bandpassDir,
                                                                                                    self.atmoTransmissionName))

            self.galSimInterpreter = GalSimInterpreter(obs_metadata=self.obs_metadata,
                                                       epoch=self.db_obj.epoch,
                                                       detectors=detectors,
                                                       bandpassDict=self.bandpassDict,
                                                       noiseWrapper=self.noise_and_background,
                                                       seed=self.seed)

            self.galSimInterpreter.setPSF(PSF=self.PSF)
    def _initializeGalSimInterpreter(self):
        """
        This method creates the GalSimInterpreter (if it is None)

        This method reads in all of the data about the camera and pass it into
        the GalSimInterpreter.

        This method calls _getBandpasses to construct the paths to
        the files containing the bandpass data.
        """

        if not isinstance(self.camera_wrapper, GalSimCameraWrapper):
            raise RuntimeError(
                "GalSimCatalog.camera_wrapper must be an instantiation of "
                "GalSimCameraWrapper or one of its daughter classes\n"
                "It is actually of type %s" % str(type(self.camera_wrapper)))

        if self.galSimInterpreter is None:

            # This list will contain instantiations of the GalSimDetector class
            # (see galSimInterpreter.py), which stores detector information in a way
            # that the GalSimInterpreter will understand
            detectors = []

            for dd in self.camera_wrapper.camera:
                if dd.getType() == WAVEFRONT or dd.getType() == GUIDER:
                    # This package does not yet handle the 90-degree rotation
                    # in WCS that occurs for wavefront or guide sensors
                    continue

                if self.allowed_chips is None or dd.getName(
                ) in self.allowed_chips:
                    detectors.append(
                        make_galsim_detector(self.camera_wrapper,
                                             dd.getName(),
                                             self.photParams,
                                             self.obs_metadata,
                                             epoch=self.db_obj.epoch))

            if not hasattr(self, 'bandpassDict'):
                if self.noise_and_background is not None:
                    if self.obs_metadata.m5 is None:
                        raise RuntimeError(
                            'WARNING  in GalSimCatalog; you did not specify m5 in your '
                            'obs_metadata. m5 is required in order to '
                            'add noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.m5:
                            raise RuntimeError(
                                'WARNING in GalSimCatalog; your obs_metadata does not have '
                                + 'm5 values for all of your bandpasses \n' +
                                'bandpass has: %s \n' %
                                self.bandpassNames.__repr__() + 'm5 has: %s ' %
                                list(self.obs_metadata.m5.keys()).__repr__())

                    if self.obs_metadata.seeing is None:
                        raise RuntimeError(
                            'WARNING  in GalSimCatalog; you did not specify seeing in your '
                            'obs_metadata.  seeing is required in order to add '
                            'noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.seeing:
                            raise RuntimeError(
                                'WARNING in GalSimCatalog; your obs_metadata does not have '
                                +
                                'seeing values for all of your bandpasses \n' +
                                'bandpass has: %s \n' %
                                self.bandpassNames.__repr__() +
                                'seeing has: %s ' %
                                list(self.obs_metadata.seeing.keys()).__repr__(
                                ))

                (self.bandpassDict,
                 hardwareDict) = BandpassDict.loadBandpassesFromFiles(
                     bandpassNames=self.bandpassNames,
                     filedir=self.bandpassDir,
                     bandpassRoot=self.bandpassRoot,
                     componentList=self.componentList,
                     atmoTransmission=os.path.join(self.bandpassDir,
                                                   self.atmoTransmissionName))

            self.galSimInterpreter = GalSimInterpreter(
                obs_metadata=self.obs_metadata,
                epoch=self.db_obj.epoch,
                detectors=detectors,
                bandpassDict=self.bandpassDict,
                noiseWrapper=self.noise_and_background,
                seed=self.seed)

            self.galSimInterpreter.setPSF(PSF=self.PSF)
Example #5
0
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 _initializeGalSimInterpreter(self):
        """
        This method creates the GalSimInterpreter (if it is None)

        This method reads in all of the data about the camera and pass it into
        the GalSimInterpreter.

        This method calls _getBandpasses to construct the paths to
        the files containing the bandpass data.
        """

        if self.galSimInterpreter is None:

            # This list will contain instantiations of the GalSimDetector class
            # (see galSimInterpreter.py), which stores detector information in a way
            # that the GalSimInterpreter will understand
            detectors = []

            for dd in self.camera:
                if self.allowed_chips is None or dd.getName(
                ) in self.allowed_chips:
                    cs = dd.makeCameraSys(PUPIL)
                    centerPupil = self.camera.transform(
                        dd.getCenter(FOCAL_PLANE), cs).getPoint()
                    centerPixel = dd.getCenter(PIXELS).getPoint()

                    translationPixel = afwGeom.Point2D(centerPixel.getX() + 1,
                                                       centerPixel.getY() + 1)
                    translationPupil = self.camera.transform(
                        dd.makeCameraPoint(translationPixel, PIXELS),
                        cs).getPoint()

                    plateScale = np.sqrt(
                        np.power(translationPupil.getX() -
                                 centerPupil.getX(), 2) +
                        np.power(translationPupil.getY() -
                                 centerPupil.getY(), 2)) / np.sqrt(2.0)

                    plateScale = 3600.0 * np.degrees(plateScale)

                    # make a detector-custom photParams that copies all of the quantities
                    # in the catalog photParams, except the platescale, which is
                    # calculated above
                    params = PhotometricParameters(
                        exptime=self.photParams.exptime,
                        nexp=self.photParams.nexp,
                        effarea=self.photParams.effarea,
                        gain=self.photParams.gain,
                        readnoise=self.photParams.readnoise,
                        darkcurrent=self.photParams.darkcurrent,
                        othernoise=self.photParams.othernoise,
                        platescale=plateScale)

                    detector = GalSimDetector(dd,
                                              self.camera,
                                              obs_metadata=self.obs_metadata,
                                              epoch=self.db_obj.epoch,
                                              photParams=params)

                    detectors.append(detector)

            if not hasattr(self, 'bandpassDict'):
                if self.noise_and_background is not None:
                    if self.obs_metadata.m5 is None:
                        raise RuntimeError(
                            'WARNING  in GalSimCatalog; you did not specify m5 in your '
                            'obs_metadata. m5 is required in order to '
                            'add noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.m5:
                            raise RuntimeError(
                                'WARNING in GalSimCatalog; your obs_metadata does not have '
                                + 'm5 values for all of your bandpasses \n' +
                                'bandpass has: %s \n' %
                                self.bandpassNames.__repr__() + 'm5 has: %s ' %
                                list(self.obs_metadata.m5.keys()).__repr__())

                    if self.obs_metadata.seeing is None:
                        raise RuntimeError(
                            'WARNING  in GalSimCatalog; you did not specify seeing in your '
                            'obs_metadata.  seeing is required in order to add '
                            'noise to your images')

                    for name in self.bandpassNames:
                        if name not in self.obs_metadata.seeing:
                            raise RuntimeError(
                                'WARNING in GalSimCatalog; your obs_metadata does not have '
                                +
                                'seeing values for all of your bandpasses \n' +
                                'bandpass has: %s \n' %
                                self.bandpassNames.__repr__() +
                                'seeing has: %s ' %
                                list(self.obs_metadata.seeing.keys()).__repr__(
                                ))

                (self.bandpassDict,
                 hardwareDict) = BandpassDict.loadBandpassesFromFiles(
                     bandpassNames=self.bandpassNames,
                     filedir=self.bandpassDir,
                     bandpassRoot=self.bandpassRoot,
                     componentList=self.componentList,
                     atmoTransmission=os.path.join(self.bandpassDir,
                                                   self.atmoTransmissionName))

            self.galSimInterpreter = GalSimInterpreter(
                obs_metadata=self.obs_metadata,
                epoch=self.db_obj.epoch,
                detectors=detectors,
                bandpassDict=self.bandpassDict,
                noiseWrapper=self.noise_and_background,
                seed=self.seed)

            self.galSimInterpreter.setPSF(PSF=self.PSF)
Example #7
0
    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))