def getTanSipWcs(self, order=3, skyToleranceArcSec=0.001, pixelTolerance=0.01): """ Take an afw Detector and approximate its pixel-to-(Ra,Dec) transformation with a TAN-SIP WCs. Definition of the TAN-SIP WCS can be found in Shupe and Hook (2008) http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf @param order The order of the SIP polynomials to be fit to the optical distortions [default: 3] @param skyToleranceArcSec The maximum allowed error in the fitted world coordinates (in arcseconds). [default: 0.001] @param pixelTolerance The maximum allowed error in the fitted pixel coordinates. [default: 0.02] @returns tanSipWcs, an instantiation of lsst.afw.image's TanWcs class representing the WCS of the detector with optical distortions parametrized by the SIP polynomials. """ bbox = self._detector.getBBox() tanWcs = self.getTanWcs() mockExposure = afwImage.ExposureF(bbox.getMaxX(), bbox.getMaxY()) mockExposure.setWcs(tanWcs) mockExposure.setDetector(self._detector) distortedWcs = afwImageUtils.getDistortedWcs(mockExposure.getInfo()) tanSipWcs = measAstrom.approximateWcs( distortedWcs, bbox, order=order, skyTolerance=skyToleranceArcSec*afwGeom.arcseconds, pixelTolerance=pixelTolerance) return tanSipWcs
def tanSipWcsFromDetector(detector_name, camera_wrapper, obs_metadata, epoch, order=3, skyToleranceArcSec=0.001, pixelTolerance=0.01): """ Take an afw Detector and approximate its pixel-to-(Ra,Dec) transformation with a TAN-SIP WCs. Definition of the TAN-SIP WCS can be found in Shupe and Hook (2008) http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf @param [in] detector_name is the name of the detector as stored by afw @param [in] camera_wrapper is an instantionat of a GalSimCameraWrapper @param [in] obs_metadata is an instantiation of ObservationMetaData characterizing the telescope's current pointing @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are measured @param [in] order is the order of the SIP polynomials to be fit to the optical distortions (default 3) @param [in] skyToleranceArcSec is the maximum allowed error in the fitted world coordinates (in arcseconds). Default 0.001 @param [in] pixelTolerance is the maximum allowed error in the fitted pixel coordinates. Default 0.02 @param [out] tanSipWcs is an instantiation of afw.image's TanWcs class representing the WCS of the detector with optical distortions parametrized by the SIP polynomials. """ bbox = camera_wrapper.getBBox(detector_name) tanWcs = tanWcsFromDetector(detector_name, camera_wrapper, obs_metadata, epoch) mockExposure = afwImage.ExposureF(bbox.getMaxX(), bbox.getMaxY()) mockExposure.setWcs(tanWcs) mockExposure.setDetector(camera_wrapper.camera[detector_name]) distortedWcs = afwImageUtils.getDistortedWcs(mockExposure.getInfo()) tanSipWcs = approximateWcs(distortedWcs, order=order, skyTolerance=skyToleranceArcSec * afwGeom.arcseconds, pixelTolerance=pixelTolerance, detector_name=detector_name, camera_wrapper=camera_wrapper, obs_metadata=obs_metadata) return tanSipWcs
def tanSipWcsFromDetector(afwDetector, afwCamera, obs_metadata, epoch, order=3, skyToleranceArcSec=0.001, pixelTolerance=0.01): """ Take an afw Detector and approximate its pixel-to-(Ra,Dec) transformation with a TAN-SIP WCs. Definition of the TAN-SIP WCS can be found in Shupe and Hook (2008) http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf @param [in] afwDetector is an instantiation of afw.cameraGeom's Detector class which characterizes the detector for which you wish to return th WCS @param [in] afwCamera is an instantiation of afw.cameraGeom's Camera class which characterizes the camera containing afwDetector @param [in] obs_metadata is an instantiation of ObservationMetaData characterizing the telescope's current pointing @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are measured @param [in] order is the order of the SIP polynomials to be fit to the optical distortions (default 3) @param [in] skyToleranceArcSec is the maximum allowed error in the fitted world coordinates (in arcseconds). Default 0.001 @param [in] pixelTolerance is the maximum allowed error in the fitted pixel coordinates. Default 0.02 @param [out] tanSipWcs is an instantiation of afw.image's TanWcs class representing the WCS of the detector with optical distortions parametrized by the SIP polynomials. """ bbox = afwDetector.getBBox() tanWcs = tanWcsFromDetector(afwDetector, afwCamera, obs_metadata, epoch) mockExposure = afwImage.ExposureF(bbox.getMaxX(), bbox.getMaxY()) mockExposure.setWcs(tanWcs) mockExposure.setDetector(afwDetector) distortedWcs = afwImageUtils.getDistortedWcs(mockExposure.getInfo()) tanSipWcs = approximateWcs(distortedWcs, bbox, order=order, skyTolerance=skyToleranceArcSec*afwGeom.arcseconds, pixelTolerance=pixelTolerance, detector=afwDetector, camera=afwCamera, obs_metadata=obs_metadata) return tanSipWcs
def createMatchMetadata(exposure, border=0): """Create metadata required for unpersisting a match list @param[in] exposure exposure for which to create metadata @param[in] border number of pixels by which to grow the bbox in all directions @return metadata about the field (a daf_base PropertyList) """ bboxd = Box2D(exposure.getBBox()) bboxd.grow(border) wcs = getDistortedWcs(exposure.getInfo()) ctrCoord = wcs.pixelToSky(bboxd.getCenter()).toIcrs() approxRadius = max( ctrCoord.angularSeparation(wcs.pixelToSky(pp).toIcrs()) for pp in bboxd.getCorners()) return MatchMetadata(ctrCoord, approxRadius, exposure.getFilter().getName())
def _getExposureMetadata(self, exposure): """!Extract metadata from an exposure @return an lsst.pipe.base.Struct containing the following exposure metadata: - bbox: parent bounding box - wcs: WCS (an lsst.afw.image.Wcs) - calib calibration (an lsst.afw.image.Calib), or None if unknown - filterName: name of filter, or None if unknown """ exposureInfo = exposure.getInfo() filterName = exposureInfo.getFilter().getName() or None if filterName == "_unknown_": filterName = None return pipeBase.Struct( bbox=exposure.getBBox(), wcs=getDistortedWcs(exposureInfo, log=self.log), calib=exposureInfo.getCalib() if exposureInfo.hasCalib() else None, filterName=filterName, )
def getTanSipWcs(self, order=3, skyToleranceArcSec=0.001, pixelTolerance=0.01): """ Take an afw Detector and approximate its pixel-to-(Ra,Dec) transformation with a TAN-SIP WCs. Definition of the TAN-SIP WCS can be found in Shupe and Hook (2008) http://fits.gsfc.nasa.gov/registry/sip/SIP_distortion_v1_0.pdf @param order The order of the SIP polynomials to be fit to the optical distortions [default: 3] @param skyToleranceArcSec The maximum allowed error in the fitted world coordinates (in arcseconds). [default: 0.001] @param pixelTolerance The maximum allowed error in the fitted pixel coordinates. [default: 0.02] @returns tanSipWcs, an instantiation of lsst.afw.image's TanWcs class representing the WCS of the detector with optical distortions parametrized by the SIP polynomials. """ bbox = self._detector.getBBox() tanWcs = self.getTanWcs() mockExposure = afwImage.ExposureF(bbox.getMaxX(), bbox.getMaxY()) mockExposure.setWcs(tanWcs) mockExposure.setDetector(self._detector) distortedWcs = afwImageUtils.getDistortedWcs(mockExposure.getInfo()) tanSipWcs = measAstrom.approximateWcs(distortedWcs, bbox, order=order, skyTolerance=skyToleranceArcSec * afwGeom.arcseconds, pixelTolerance=pixelTolerance) return tanSipWcs
def createMatchMetadata(exposure): """Create metadata required for unpersisting a match list @param[in] exposure exposure for which to create metadata @return metadata about the field (a daf_base PropertyList) """ matchMeta = PropertyList() bboxd = Box2D(exposure.getBBox()) ctrPos = bboxd.getCenter() wcs = getDistortedWcs(exposure.getInfo()) ctrCoord = wcs.pixelToSky(ctrPos).toIcrs() llCoord = wcs.pixelToSky(bboxd.getMin()) approxRadius = ctrCoord.angularSeparation(llCoord) matchMeta.add('RA', ctrCoord.getRa().asDegrees(), 'field center in degrees') matchMeta.add('DEC', ctrCoord.getDec().asDegrees(), 'field center in degrees') matchMeta.add('RADIUS', approxRadius.asDegrees(), 'field radius in degrees, approximate') matchMeta.add('SMATCHV', 1, 'SourceMatchVector version number') filterName = exposure.getFilter().getName() or None if filterName is not None and filterName not in ("_unknmown_", ""): matchMeta.add('FILTER', filterName, 'filter name for tagalong data') return matchMeta
def testGetDistortedWcs(self): """Test utils.getDistortedWcs """ dw = DetectorWrapper() detector = dw.detector # the standard case: the exposure's WCS is pure TAN WCS and distortion information is available; # return a DistortedTanWcs exposure = afwImage.ExposureF(10, 10) exposure.setDetector(detector) exposure.setWcs(self.tanWcs) self.assertFalse(self.tanWcs.hasDistortion()) outWcs = getDistortedWcs(exposure.getInfo()) self.assertTrue(outWcs.hasDistortion()) self.assertIsInstance(outWcs, afwImage.DistortedTanWcs) del exposure # avoid accidental reuse del outWcs # return the original WCS if the exposure's WCS has distortion pixelsToTanPixels = afwGeom.RadialXYTransform([0, 1.001, 0.00003]) distortedWcs = afwImage.DistortedTanWcs(self.tanWcs, pixelsToTanPixels) self.assertTrue(distortedWcs.hasDistortion()) exposure = afwImage.ExposureF(10, 10) exposure.setWcs(distortedWcs) exposure.setDetector(detector) outWcs = getDistortedWcs(exposure.getInfo()) self.assertTrue(outWcs.hasDistortion()) self.assertIsInstance(outWcs, afwImage.DistortedTanWcs) del exposure del distortedWcs del outWcs # raise an exception if exposure has no WCS exposure = afwImage.ExposureF(10, 10) exposure.setDetector(detector) with self.assertRaises(Exception): getDistortedWcs(exposure.getInfo()) del exposure # return the original pure TAN WCS if the exposure has no detector exposure = afwImage.ExposureF(10, 10) exposure.setWcs(self.tanWcs) outWcs = getDistortedWcs(exposure.getInfo()) self.assertFalse(outWcs.hasDistortion()) self.assertIsInstance(outWcs, afwImage.TanWcs) self.assertNotIsInstance(outWcs, afwImage.DistortedTanWcs) del exposure del outWcs # return the original pure TAN WCS if the exposure's detector has no # TAN_PIXELS transform def removeTanPixels(detectorWrapper): tanPixSys = detector.makeCameraSys(TAN_PIXELS) detectorWrapper.transMap.pop(tanPixSys) detectorNoTanPix = DetectorWrapper(modFunc=removeTanPixels).detector exposure = afwImage.ExposureF(10, 10) exposure.setWcs(self.tanWcs) exposure.setDetector(detectorNoTanPix) outWcs = getDistortedWcs(exposure.getInfo()) self.assertFalse(outWcs.hasDistortion()) self.assertIsInstance(outWcs, afwImage.TanWcs) self.assertNotIsInstance(outWcs, afwImage.DistortedTanWcs) del exposure del outWcs
def testGetDistortedWcs(self): """Test utils.getDistortedWcs """ dw = DetectorWrapper() detector = dw.detector # the standard case: the exposure's WCS is pure TAN WCS and distortion information is available; # return a DistortedTanWcs exposure = afwImage.ExposureF(10, 10) exposure.setDetector(detector) exposure.setWcs(self.tanWcs) self.assertFalse(self.tanWcs.hasDistortion()) outWcs = getDistortedWcs(exposure.getInfo()) self.assertTrue(outWcs.hasDistortion()) self.assertTrue(afwImage.DistortedTanWcs.cast(outWcs) is not None) del exposure # avoid accidental reuse del outWcs # return the original WCS if the exposure's WCS has distortion pixelsToTanPixels = afwGeom.RadialXYTransform([0, 1.001, 0.00003]) distortedWcs = afwImage.DistortedTanWcs(self.tanWcs, pixelsToTanPixels) self.assertTrue(distortedWcs.hasDistortion()) exposure = afwImage.ExposureF(10, 10) exposure.setWcs(distortedWcs) exposure.setDetector(detector) outWcs = getDistortedWcs(exposure.getInfo()) self.assertTrue(outWcs.hasDistortion()) self.assertTrue(afwImage.DistortedTanWcs.cast(outWcs) is not None) del exposure del distortedWcs del outWcs # raise an exception if exposure has no WCS exposure = afwImage.ExposureF(10, 10) exposure.setDetector(detector) self.assertRaises(Exception, getDistortedWcs, exposure.getInfo()) del exposure # return the original pure TAN WCS if the exposure has no detector exposure = afwImage.ExposureF(10, 10) exposure.setWcs(self.tanWcs) outWcs = getDistortedWcs(exposure.getInfo()) self.assertFalse(outWcs.hasDistortion()) self.assertTrue(afwImage.TanWcs.cast(outWcs) is not None) self.assertTrue(afwImage.DistortedTanWcs.cast(outWcs) is None) del exposure del outWcs # return the original pure TAN WCS if the exposure's detector has no TAN_PIXELS transform def removeTanPixels(detectorWrapper): tanPixSys = detector.makeCameraSys(TAN_PIXELS) detectorWrapper.transMap.pop(tanPixSys) detectorNoTanPix = DetectorWrapper(modFunc=removeTanPixels).detector exposure = afwImage.ExposureF(10, 10) exposure.setWcs(self.tanWcs) exposure.setDetector(detectorNoTanPix) outWcs = getDistortedWcs(exposure.getInfo()) self.assertFalse(outWcs.hasDistortion()) self.assertTrue(afwImage.TanWcs.cast(outWcs) is not None) self.assertTrue(afwImage.DistortedTanWcs.cast(outWcs) is None) del exposure del outWcs