コード例 #1
0
    def setUpClass(cls):
        cls.scratchDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'scratchSpace')
        cls.obs = ObservationMetaData(pointingRA=122.0, pointingDec=-29.1,
                                      mjd=57381.2, rotSkyPos=43.2)


        cls.camera = camTestUtils.CameraWrapper().camera

        cls.dbFileName = os.path.join(cls.scratchDir, 'allowed_chips_test_db.txt')
        if os.path.exists(cls.dbFileName):
            os.unlink(cls.dbFileName)

        cls.controlSed = Sed()
        cls.controlSed.readSED_flambda(os.path.join(getPackageDir('sims_sed_library'),
                                               'flatSED','sed_flat.txt.gz'))
        cls.magNorm = 18.1
        imsim = Bandpass()
        imsim.imsimBandpass()
        ff = cls.controlSed.calcFluxNorm(cls.magNorm, imsim)
        cls.controlSed.multiplyFluxNorm(ff)
        a_x, b_x = cls.controlSed.setupCCMab()
        cls.controlSed.addCCMDust(a_x, b_x, A_v=0.1, R_v=3.1)
        bpd = BandpassDict.loadTotalBandpassesFromFiles()
        pp = PhotometricParameters()
        cls.controlADU = cls.controlSed.calcADU(bpd['u'], pp)
        cls.countSigma = np.sqrt(cls.controlADU/pp.gain)

        cls.x_pix = 50
        cls.y_pix = 50

        x_list = []
        y_list = []
        name_list = []
        for dd in cls.camera:
            x_list.append(cls.x_pix)
            y_list.append(cls.y_pix)
            name_list.append(dd.getName())

        x_list = np.array(x_list)
        y_list = np.array(y_list)

        ra_list, dec_list = raDecFromPixelCoords(x_list, y_list, name_list,
                                                 camera=cls.camera, obs_metadata=cls.obs,
                                                 epoch=2000.0)

        dra_list = 3600.0*(ra_list-cls.obs.pointingRA)
        ddec_list = 3600.0*(dec_list-cls.obs.pointingDec)

        create_text_catalog(cls.obs, cls.dbFileName, dra_list, ddec_list,
                            mag_norm=[cls.magNorm]*len(dra_list))

        cls.db = allowedChipsFileDBObj(cls.dbFileName, runtable='test')
コード例 #2
0
    def raDecFromPixelCoords(self,
                             xPix,
                             yPix,
                             chipName,
                             obs_metadata,
                             epoch=2000.0,
                             includeDistortion=True):
        """
        Convert pixel coordinates into RA, Dec

        Parameters
        ----------
        xPix is the x pixel coordinate.  It can be either
        a float or a numpy array.

        yPix is the y pixel coordinate.  It can be either
        a float or a numpy array.

        chipName is the name of the chip(s) on which the pixel coordinates
        are defined.  This can be a list (in which case there should be one chip name
        for each (xPix, yPix) coordinate pair), or a single value (in which case, all
        of the (xPix, yPix) points will be reckoned on that chip).

        obs_metadata is an ObservationMetaData defining the pointing

        epoch is the mean epoch in years of the celestial coordinate system.
        Default is 2000.

        includeDistortion is a boolean.  If True (default), then this method will
        expect the true pixel coordinates with optical distortion included.  If False, this
        method will expect 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 RA coordinate
        and the second row is the Dec coordinate (both in degrees; in the
        International Celestial Reference System)

        WARNING: This method does not account for apparent motion due to parallax.
        This method is only useful for mapping positions on a theoretical focal plane
        to positions on the celestial sphere.
        """

        return coordUtils.raDecFromPixelCoords(xPix,
                                               yPix,
                                               chipName,
                                               camera=self._camera,
                                               obs_metadata=obs_metadata,
                                               epoch=2000.0,
                                               includeDistortion=True)
コード例 #3
0
    def setUpClass(cls):
        cls.scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='allowedChipsTest-')
        cls.obs = ObservationMetaData(pointingRA=122.0, pointingDec=-29.1,
                                      mjd=57381.2, rotSkyPos=43.2,
                                      bandpassName='r')

        cls.camera = camTestUtils.CameraWrapper().camera

        cls.dbFileName = os.path.join(cls.scratchDir, 'allowed_chips_test_db.txt')
        if os.path.exists(cls.dbFileName):
            os.unlink(cls.dbFileName)

        cls.controlSed = Sed()
        cls.controlSed.readSED_flambda(os.path.join(getPackageDir('sims_sed_library'),
                                                    'flatSED', 'sed_flat.txt.gz'))
        cls.magNorm = 18.1
        imsim = Bandpass()
        imsim.imsimBandpass()
        ff = cls.controlSed.calcFluxNorm(cls.magNorm, imsim)
        cls.controlSed.multiplyFluxNorm(ff)
        a_x, b_x = cls.controlSed.setupCCMab()
        cls.controlSed.addCCMDust(a_x, b_x, A_v=0.1, R_v=3.1)
        bpd = BandpassDict.loadTotalBandpassesFromFiles()
        pp = PhotometricParameters()
        cls.controlADU = cls.controlSed.calcADU(bpd['u'], pp)
        cls.countSigma = np.sqrt(cls.controlADU/pp.gain)

        cls.x_pix = 50
        cls.y_pix = 50

        x_list = []
        y_list = []
        name_list = []
        for dd in cls.camera:
            x_list.append(cls.x_pix)
            y_list.append(cls.y_pix)
            name_list.append(dd.getName())

        x_list = np.array(x_list)
        y_list = np.array(y_list)

        ra_list, dec_list = raDecFromPixelCoords(x_list, y_list, name_list,
                                                 camera=cls.camera, obs_metadata=cls.obs,
                                                 epoch=2000.0)

        dra_list = 3600.0*(ra_list-cls.obs.pointingRA)
        ddec_list = 3600.0*(dec_list-cls.obs.pointingDec)

        create_text_catalog(cls.obs, cls.dbFileName, dra_list, ddec_list,
                            mag_norm=[cls.magNorm]*len(dra_list))

        cls.db = allowedChipsFileDBObj(cls.dbFileName, runtable='test')
コード例 #4
0
def chip_center_coords(chip_name, obs_md, camera):
    """
    The coordinates of the center of the specified chip.

    Parameters
    ----------
    chip_name : str
        The chip name, e.g., "R:2,2 S:1,1".
    obs_md : lsst.sims.utils.ObservationMetaData
        Obsevation metadata extracted from the phosim commands.
    camera : lsst.afw.cameraGeom.camera.Camera
        The camera instance from lsst.obs.lsstSim.LsstSimMapper().
    """
    corner_pixels = coordUtils.getCornerPixels(chip_name, camera)
    xmid = (corner_pixels[-1][0] - corner_pixels[0][0] + 1) / 2
    ymid = (corner_pixels[-1][1] - corner_pixels[0][1] + 1) / 2
    return tuple(
        coordUtils.raDecFromPixelCoords(ymid,
                                        xmid,
                                        chip_name,
                                        camera=camera,
                                        obs_metadata=obs_md))
コード例 #5
0
            (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'
            )

            for det_name in det_name_list:
                det_name_m = det_name.replace(':', '').replace(',',
                                                               '').replace(
                                                                   ' ', '_')

                dm_xpix_in, dm_ypix_in = camera_wrapper.dmPixFromCameraPix(
                    cam_xpix_in, cam_ypix_in, det_name)

                ra_icrs, dec_icrs = raDecFromPixelCoords(dm_xpix_in,
                                                         dm_ypix_in,
                                                         det_name,
                                                         camera=lsst_camera(),
                                                         obs_metadata=obs)

                ra_obs, dec_obs = observedFromICRS(ra_icrs,
                                                   dec_icrs,
                                                   obs_metadata=obs,
                                                   epoch=2000.0,
                                                   includeRefraction=False)

                (ra_deprecessed, dec_deprecessed) = de_precessor._dePrecess(
                    np.radians(ra_obs), np.radians(dec_obs), obs)

                x_f, y_f = focalPlaneCoordsFromRaDec(ra_icrs,
                                                     dec_icrs,
                                                     obs_metadata=obs,
コード例 #6
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
コード例 #7
0
def approximateWcs(wcs,
                   bbox,
                   camera=None,
                   detector=None,
                   obs_metadata=None,
                   order=3,
                   nx=20,
                   ny=20,
                   iterations=3,
                   skyTolerance=0.001 * afwGeom.arcseconds,
                   pixelTolerance=0.02,
                   useTanWcs=False):
    """Approximate an existing WCS as a TAN-SIP WCS

    The fit is performed by evaluating the WCS at a uniform grid of points within a bounding box.

    @param[in] wcs  wcs to approximate
    @param[in] bbox  the region over which the WCS will be fit
    @param[in] camera is an instantiation of afw.cameraGeom.camera
    @param[in] detector is a detector from camera
    @param[in] obs_metadata is an ObservationMetaData characterizing the telescope pointing
    @param[in] order  order of SIP fit
    @param[in] nx  number of grid points along x
    @param[in] ny  number of grid points along y
    @param[in] iterations number of times to iterate over fitting
    @param[in] skyTolerance maximum allowed difference in world coordinates between
               input wcs and approximate wcs (default is 0.001 arcsec)
    @param[in] pixelTolerance maximum allowed difference in pixel coordinates between
               input wcs and approximate wcs (default is 0.02 pixels)
    @param[in] useTanWcs  send a TAN version of wcs to the fitter? It is documented to require that,
        but I don't think the fitter actually cares
    @return the fit TAN-SIP WCS
    """
    if useTanWcs:
        crCoord = wcs.getSkyOrigin()
        crPix = wcs.getPixelOrigin()
        cdMat = wcs.getCDMatrix()
        tanWcs = afwImage.makeWcs(crCoord, crPix, cdMat[0, 0], cdMat[0, 1],
                                  cdMat[1, 0], cdMat[1, 1])
    else:
        tanWcs = wcs

    # create a matchList consisting of a grid of points covering the bbox
    refSchema = afwTable.SimpleTable.makeMinimalSchema()
    refCoordKey = afwTable.CoordKey(refSchema["coord"])
    refCat = afwTable.SimpleCatalog(refSchema)

    sourceSchema = afwTable.SourceTable.makeMinimalSchema()
    SingleFrameMeasurementTask(schema=sourceSchema)  # expand the schema
    sourceCentroidKey = afwTable.Point2DKey(sourceSchema["slot_Centroid"])

    sourceCat = afwTable.SourceCatalog(sourceSchema)

    # 20 March 2017
    # the 'try' block is how it works in swig;
    # the 'except' block is how it works in pybind11
    try:
        matchList = afwTable.ReferenceMatchVector()
    except AttributeError:
        matchList = []

    bboxd = afwGeom.Box2D(bbox)
    for x in np.linspace(bboxd.getMinX(), bboxd.getMaxX(), nx):
        for y in np.linspace(bboxd.getMinY(), bboxd.getMaxY(), ny):
            pixelPos = afwGeom.Point2D(x, y)

            ra, dec = raDecFromPixelCoords(np.array([x]),
                                           np.array([y]), [detector.getName()],
                                           camera=camera,
                                           obs_metadata=obs_metadata,
                                           epoch=2000.0,
                                           includeDistortion=True)

            skyCoord = afwCoord.Coord(afwGeom.Point2D(ra[0], dec[0]))

            refObj = refCat.addNew()
            refObj.set(refCoordKey, skyCoord)

            source = sourceCat.addNew()
            source.set(sourceCentroidKey, pixelPos)

            matchList.append(afwTable.ReferenceMatch(refObj, source, 0.0))

    # The TAN-SIP fitter is fitting x and y separately, so we have to iterate to make it converge
    for indx in range(iterations):
        sipObject = makeCreateWcsWithSip(matchList, tanWcs, order, bbox)
        tanWcs = sipObject.getNewWcs()
    fitWcs = sipObject.getNewWcs()

    return fitWcs
コード例 #8
0
def approximateWcs(wcs, bbox, camera=None, detector=None, obs_metadata=None,
                   order=3, nx=20, ny=20, iterations=3,
                   skyTolerance=0.001*afwGeom.arcseconds, pixelTolerance=0.02,
                   useTanWcs=False):
    """Approximate an existing WCS as a TAN-SIP WCS

    The fit is performed by evaluating the WCS at a uniform grid of points within a bounding box.

    @param[in] wcs  wcs to approximate
    @param[in] bbox  the region over which the WCS will be fit
    @param[in] camera is an instantiation of afw.cameraGeom.camera
    @param[in] detector is a detector from camera
    @param[in] obs_metadata is an ObservationMetaData characterizing the telescope pointing
    @param[in] order  order of SIP fit
    @param[in] nx  number of grid points along x
    @param[in] ny  number of grid points along y
    @param[in] iterations number of times to iterate over fitting
    @param[in] skyTolerance maximum allowed difference in world coordinates between
               input wcs and approximate wcs (default is 0.001 arcsec)
    @param[in] pixelTolerance maximum allowed difference in pixel coordinates between
               input wcs and approximate wcs (default is 0.02 pixels)
    @param[in] useTanWcs  send a TAN version of wcs to the fitter? It is documented to require that,
        but I don't think the fitter actually cares
    @return the fit TAN-SIP WCS
    """
    if useTanWcs:
        crCoord = wcs.getSkyOrigin()
        crPix = wcs.getPixelOrigin()
        cdMat = wcs.getCDMatrix()
        tanWcs = afwImage.makeWcs(crCoord, crPix, cdMat[0,0], cdMat[0,1], cdMat[1,0], cdMat[1,1])
    else:
        tanWcs = wcs

    # create a matchList consisting of a grid of points covering the bbox
    refSchema = afwTable.SimpleTable.makeMinimalSchema()
    refCoordKey = afwTable.CoordKey(refSchema["coord"])
    refCat = afwTable.SimpleCatalog(refSchema)

    sourceSchema = afwTable.SourceTable.makeMinimalSchema()
    SingleFrameMeasurementTask(schema=sourceSchema) # expand the schema
    sourceCentroidKey = afwTable.Point2DKey(sourceSchema["slot_Centroid"])

    sourceCat = afwTable.SourceCatalog(sourceSchema)

    matchList = afwTable.ReferenceMatchVector()

    bboxd = afwGeom.Box2D(bbox)
    for x in np.linspace(bboxd.getMinX(), bboxd.getMaxX(), nx):
        for y in np.linspace(bboxd.getMinY(), bboxd.getMaxY(), ny):
            pixelPos = afwGeom.Point2D(x, y)

            ra, dec = raDecFromPixelCoords(np.array([x]), np.array([y]),
                                           [detector.getName()],
                                           camera=camera,
                                           obs_metadata=obs_metadata,
                                           epoch=2000.0,
                                           includeDistortion=True)

            skyCoord = afwCoord.Coord(afwGeom.Point2D(ra[0], dec[0]))

            refObj = refCat.addNew()
            refObj.set(refCoordKey, skyCoord)

            source = sourceCat.addNew()
            source.set(sourceCentroidKey, pixelPos)

            matchList.append(afwTable.ReferenceMatch(refObj, source, 0.0))

    # The TAN-SIP fitter is fitting x and y separately, so we have to iterate to make it converge
    for indx in range(iterations) :
        sipObject = makeCreateWcsWithSip(matchList, tanWcs, order, bbox)
        tanWcs = sipObject.getNewWcs()
    fitWcs = sipObject.getNewWcs()

    return fitWcs
コード例 #9
0
    def test_LSST_camera_wrapper(self):
        """
        Test that LSSTCameraWrapper wraps its methods as expected.

        Recall that the LSSTCameraWrapper applies the 90 degree rotation
        to go from DM pixel coordinates to Camera team pixel coordinates.
        Namely,

        Camera +y = DM +x
        Camera +x = DM -y
        """
        camera = lsst_camera()
        camera_wrapper = LSSTCameraWrapper()

        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.getMinY())
            self.assertEqual(bbox.getMaxX(), bbox_wrapper.getMaxY())
            self.assertEqual(bbox.getMinY(), bbox_wrapper.getMinX())
            self.assertEqual(bbox.getMaxY(), bbox_wrapper.getMaxX())
            self.assertGreater(bbox_wrapper.getMaxY()-bbox_wrapper.getMinY(),
                               bbox_wrapper.getMaxX()-bbox_wrapper.getMinX())

            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.getY())
            self.assertEqual(center_pix.getY(), center_pix_wrapper.getX())

            # Note that DM and the Camera team agree on the orientation
            # of the pupil coordinate/field angle axes
            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], ypix_min)
            self.assertEqual(pix_bounds_wrapper[1], ypix_max)
            self.assertEqual(pix_bounds_wrapper[2], xpix_min)
            self.assertEqual(pix_bounds_wrapper[3], xpix_max)

            # generate some random pupil coordinates;
            # verify that the relationship between the DM and Camera team
            # pixel coordinates corresponding to those pupil coordinates
            # is as expected
            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,
                                                                        chipName=name)

            nan_x = np.where(np.isnan(x_pix))
            self.assertEqual(len(nan_x[0]), 0)
            np.testing.assert_allclose(x_pix-center_pix.getX(),
                                       y_pix_wrapper-center_pix_wrapper.getY(),
                                       atol=1.0e-10, rtol=0.0)
            np.testing.assert_allclose(y_pix-center_pix.getY(),
                                       center_pix_wrapper.getX()-x_pix_wrapper,
                                       atol=1.0e-10, rtol=0.0)

            # use camera_wrapper.pupilCoordsFromPixelCoords to go back to pupil
            # coordinates from x_pix_wrapper, y_pix_wrapper; make sure you get
            # the original pupil coordinates back out
            (x_pup_wrapper,
             y_pup_wrapper) = camera_wrapper.pupilCoordsFromPixelCoords(x_pix_wrapper,
                                                                        y_pix_wrapper,
                                                                        chipName=name)
            msg = 'worst error %e' % np.abs(x_pup-x_pup_wrapper).max()
            np.testing.assert_allclose(x_pup, x_pup_wrapper, atol=1.0e-10, rtol=0.0, err_msg=msg)
            msg = 'worst error %e' % np.abs(y_pup-y_pup_wrapper).max()
            np.testing.assert_allclose(y_pup, y_pup_wrapper, atol=1.0e-10, rtol=0.0, err_msg=msg)

            # generate some random sky coordinates; verify that the methods that
            # convert between (RA, Dec) and pixel coordinates behave as expected.
            # NOTE: x_pix, y_pix will be in DM pixel coordinate convention
            x_pix = bbox.getMinX() + rng.random_sample(10)*(bbox.getMaxX()-bbox.getMinX())
            y_pix = bbox.getMinY() + rng.random_sample(10)*(bbox.getMaxY()-bbox.getMinY())

            ra, dec = raDecFromPixelCoords(x_pix, y_pix, name, camera=camera,
                                           obs_metadata=obs)

            (ra_wrapper,
             dec_wrapper) = camera_wrapper.raDecFromPixelCoords(2.0*center_pix.getY()-y_pix,
                                                                x_pix, name, obs)

            nan_ra = np.where(np.isnan(ra))
            self.assertEqual(len(nan_ra[0]), 0)
            np.testing.assert_allclose(ra, ra_wrapper, atol=1.0e-10, rtol=0.0)
            np.testing.assert_allclose(dec, dec_wrapper, atol=1.0e-10, rtol=0.0)

            # make sure that the method that returns RA, Dec in radians agrees with
            # the method that returns RA, Dec in degrees
            (ra_rad,
             dec_rad) = camera_wrapper._raDecFromPixelCoords(2.0*center_pix.getY()-y_pix,
                                                             x_pix, name, obs)

            np.testing.assert_allclose(np.radians(ra_wrapper), ra_rad, atol=1.0e-10, rtol=0.0)
            np.testing.assert_allclose(np.radians(dec_wrapper), dec_rad, atol=1.0e-10, rtol=0.0)

            # Go back to pixel coordinates with pixelCoordsFromRaDec; verify that
            # the result relates to the original DM pixel coordinates as expected
            # (x_pix_inv, y_pix_inv will be in Camera pixel coordinates)
            (x_pix_inv,
             y_pix_inv) = camera_wrapper.pixelCoordsFromRaDec(ra_wrapper, dec_wrapper,
                                                              chipName=name,
                                                              obs_metadata=obs)

            np.testing.assert_allclose(y_pix_inv, x_pix, atol=1.0e-5, rtol=0.0)
            np.testing.assert_allclose(x_pix_inv, 2.0*center_pix.getY()-y_pix, atol=1.0e-5, rtol=0.0)

            ra = np.radians(ra_wrapper)
            dec = np.radians(dec_wrapper)

            # check that the the method that accepts RA, Dec in radians agrees with the
            # method that accepts RA, Dec in degrees
            (x_pix_wrapper,
             y_pix_wrapper) = camera_wrapper._pixelCoordsFromRaDec(ra, dec, chipName=name,
                                                                   obs_metadata=obs)

            np.testing.assert_allclose(x_pix_inv, x_pix_wrapper, atol=1.0e-10, rtol=0.0)
            np.testing.assert_allclose(y_pix_inv, y_pix_wrapper, atol=1.0e-10, rtol=0.0)

        del camera
        del camera_wrapper
        del lsst_camera._lsst_camera