def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ originalExposure = afwImage.ExposureF(afwGeom.Extent2I(100, 100)) warpingControl = afwMath.WarpingControl("bilinear", "", 0, interpLength) try: afwMath.warpExposure(originalExposure, originalExposure, warpingControl) self.fail("warpExposure in place (dest is src) should fail") except Exception: pass try: afwMath.warpImage(originalExposure.getMaskedImage(), originalExposure.getWcs(), originalExposure.getMaskedImage(), originalExposure.getWcs(), warpingControl) self.fail( "warpImage<MaskedImage> in place (dest is src) should fail") except Exception: pass try: afwMath.warpImage(originalExposure.getImage(), originalExposure.getWcs(), originalExposure.getImage(), originalExposure.getWcs(), warpingControl) self.fail("warpImage<Image> in place (dest is src) should fail") except Exception: pass
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - NO_DATA and off-CCD pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ filterPolicyFile = pexPolicy.DefaultPolicyFile("afw", "SdssFilters.paf", "tests") filterPolicy = pexPolicy.Policy.createPolicy( filterPolicyFile, filterPolicyFile.getRepositoryPath(), True) imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True) originalExposure = afwImage.ExposureF(originalExposurePath) originalFilter = afwImage.Filter("i") originalCalib = afwImage.Calib() originalCalib.setFluxMag0(1.0e5, 1.0e3) originalExposure.setFilter(originalFilter) originalExposure.setCalib(originalCalib) afwWarpedExposure = afwImage.ExposureF(originalExposure.getBBox(), originalExposure.getWcs()) warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull.fits") self.assertEqual(afwWarpedExposure.getFilter().getName(), originalFilter.getName()) self.assertEqual(afwWarpedExposure.getCalib().getFluxMag0(), originalCalib.getFluxMag0()) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() noDataBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-DATA pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels noDataMaskArr = afwWarpedMaskArr & noDataBitMask msg = "afw null-warped MaskedImage (all pixels, relaxed tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), doMask=False, skipMask=noDataMaskArr, atol=1e-5, msg=msg) # compare good pixels (mask=0) of image, mask and variance using full # tolerance msg = "afw null-warped MaskedImage (good pixels, max tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), skipMask=afwWarpedMask, msg=msg)
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - NO_DATA and off-CCD pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ originalExposure = afwImage.ExposureF(originalExposurePath) originalExposure.getInfo().setId(10313423) originalExposure.getInfo().setVisitInfo(makeVisitInfo()) originalFilterLabel = afwImage.FilterLabel(band="i") originalPhotoCalib = afwImage.PhotoCalib(1.0e5, 1.0e3) originalExposure.setFilter(originalFilterLabel) originalExposure.setPhotoCalib(originalPhotoCalib) afwWarpedExposure = afwImage.ExposureF(originalExposure.getBBox(), originalExposure.getWcs()) warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull.fits") self.assertEqual(afwWarpedExposure.getFilter().bandLabel, originalFilterLabel.bandLabel) self.assertEqual(afwWarpedExposure.getPhotoCalib(), originalPhotoCalib) self.assertEqual(afwWarpedExposure.getInfo().getVisitInfo(), originalExposure.getInfo().getVisitInfo()) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() noDataBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-DATA pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels noDataMaskArr = afwWarpedMaskArr & noDataBitMask msg = "afw null-warped MaskedImage (all pixels, relaxed tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), doMask=False, skipMask=noDataMaskArr, atol=1e-5, msg=msg) # compare good pixels (mask=0) of image, mask and variance using full # tolerance msg = "afw null-warped MaskedImage (good pixels, max tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), skipMask=afwWarpedMask, msg=msg)
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - edge and off-CCD pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ filterPolicyFile = pexPolicy.DefaultPolicyFile("afw", "SdssFilters.paf", "tests") filterPolicy = pexPolicy.Policy.createPolicy(filterPolicyFile, filterPolicyFile.getRepositoryPath(), True) imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True) originalExposure = afwImage.ExposureF(originalExposurePath) originalFilter = afwImage.Filter("i") originalCalib = afwImage.Calib() originalCalib.setFluxMag0(1.0e5, 1.0e3) originalExposure.setFilter(originalFilter) originalExposure.setCalib(originalCalib) afwWarpedExposure = afwImage.ExposureF( originalExposure.getBBox(), originalExposure.getWcs()) warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull.fits") self.assertEquals(afwWarpedExposure.getFilter().getName(), originalFilter.getName()) self.assertEquals(afwWarpedExposure.getCalib().getFluxMag0(), originalCalib.getFluxMag0()) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") noDataBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") if noDataBitMask == 0: self.fail("warped mask has no NO_DATA bit") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-edge pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels maskArr = afwWarpedMaskArr & (edgeBitMask | noDataBitMask) originalMaskedImageArrSet = originalExposure.getMaskedImage().getArrays() errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doMask=False, skipMaskArr=maskArr, atol=1e-5) if errStr: self.fail("afw null-warped MaskedImage (all pixels, relaxed tolerance): %s" % (errStr,)) # compare good pixels of image, mask and variance using full tolerance errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doImage=False, doVariance=False, skipMaskArr=afwWarpedMaskArr) if errStr: self.fail("afw null-warped MaskedImage (good pixels, max tolerance): %s" % (errStr,))
def acsEventCallback(key, source, im, frame): """Callback for event handlers to find COSMOS ACS cutout. \param key Key struck \param source The Source under the cursor \param im The (HSC) image cutout displayed in frame \param frame The frame that the HSC data's displayed in (we'll use the next one) We also use the following static members of utils.EventHandler (if set): sizeCutout The size of the HSC cutout (arcsec; default: 4.0) scale Make the COSMOS image with pixel size scale*HSC's pixel size (default 0.25 => 0.42mas) Use as e.g. utils.eventCallbacks['c'] = cosmos.acsEventCallback """ sizeCutout = utils.EventHandler.sizeCutout if hasattr( utils.EventHandler, "sizeCutout") else 4.0 # arcsec scale = utils.EventHandler.scale if hasattr( utils.EventHandler, "scale") else 0.25 # Pixel size scaling pos = source.get("coord") exp = getCosmosCutout(*pos.getPosition(), sizeX=sizeCutout) if im and exp and exp.getWcs(): # # Resample and rotate to the HSC orientation # warpingControl = afwMath.WarpingControl("lanczos3") rat = im.getWcs().pixelScale().asArcseconds() / exp.getWcs( ).pixelScale().asArcseconds() hsize = int(0.5 * exp.getWidth() / (scale * rat)) rexp = afwImage.ExposureF(2 * hsize + 1, 2 * hsize + 1) rexp.setWcs( afwImage.Wcs(pos.getPosition(), afwGeom.Point2D(hsize, hsize), im.getWcs().getCDMatrix() * scale)) afwMath.warpExposure(rexp, exp, warpingControl) else: print "\nI'm unable to remap the cosmos image to your coordinates, sorry" rexp = exp.getMaskedImage().getImage() frame += 1 rim = rexp if hasattr(rim, "getMaskedImage"): rim = rim.getMaskedImage().getImage() if hasattr(rim, "getImage"): rim = rim.getImage() disp = afwDisplay.Display(frame=frame) disp.mtv(rim) if hasattr(rexp, "getWcs"): cen = rexp.getWcs().skyToPixel(pos) - afwGeom.PointD(rexp.getXY0()) disp.pan(*cen) disp.dot('+', *cen)
def testNullWcs(self, interpLength=10): """Cannot warp from or into an exposure without a Wcs. """ exposureWithWcs = afwImage.ExposureF(originalExposurePath) mi = exposureWithWcs.getMaskedImage() exposureWithoutWcs = afwImage.ExposureF(mi.getDimensions()) warpingControl = afwMath.WarpingControl( "bilinear", "", 0, interpLength) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposureWithWcs, exposureWithoutWcs, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposureWithoutWcs, exposureWithWcs, warpingControl)
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - NO_DATA and off-CCD pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ imageUtils.defineFilter("i", 748.1) originalExposure = afwImage.ExposureF(originalExposurePath) originalExposure.getInfo().setVisitInfo(makeVisitInfo()) originalFilter = afwImage.Filter("i") originalPhotoCalib = afwImage.PhotoCalib(1.0e5, 1.0e3) originalExposure.setFilter(originalFilter) originalExposure.setCalib(originalPhotoCalib) afwWarpedExposure = afwImage.ExposureF( originalExposure.getBBox(), originalExposure.getWcs()) warpingControl = afwMath.WarpingControl( "lanczos4", "", 0, interpLength) afwMath.warpExposure( afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull.fits") self.assertEqual(afwWarpedExposure.getFilter().getName(), originalFilter.getName()) self.assertEqual(afwWarpedExposure.getPhotoCalib(), originalPhotoCalib) self.assertEqual(afwWarpedExposure.getInfo().getVisitInfo(), originalExposure.getInfo().getVisitInfo()) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() noDataBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-DATA pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels noDataMaskArr = afwWarpedMaskArr & noDataBitMask msg = "afw null-warped MaskedImage (all pixels, relaxed tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), doMask=False, skipMask=noDataMaskArr, atol=1e-5, msg=msg) # compare good pixels (mask=0) of image, mask and variance using full # tolerance msg = "afw null-warped MaskedImage (good pixels, max tolerance)" self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, originalExposure.getMaskedImage(), skipMask=afwWarpedMask, msg=msg)
def acsEventCallback(key, source, im, frame): """Callback for event handlers to find COSMOS ACS cutout. \param key Key struck \param source The Source under the cursor \param im The (HSC) image cutout displayed in frame \param frame The frame that the HSC data's displayed in (we'll use the next one) We also use the following static members of utils.EventHandler (if set): sizeCutout The size of the HSC cutout (arcsec; default: 4.0) scale Make the COSMOS image with pixel size scale*HSC's pixel size (default 0.25 => 0.42mas) Use as e.g. utils.eventCallbacks['c'] = cosmos.acsEventCallback """ sizeCutout = utils.EventHandler.sizeCutout if hasattr(utils.EventHandler, "sizeCutout") else 4.0 # arcsec scale = utils.EventHandler.scale if hasattr(utils.EventHandler, "scale") else 0.25 # Pixel size scaling pos = source.get("coord") exp = getCosmosCutout(*pos.getPosition(), sizeX=sizeCutout) if im and exp and exp.getWcs(): # # Resample and rotate to the HSC orientation # warpingControl = afwMath.WarpingControl("lanczos3") rat = im.getWcs().pixelScale().asArcseconds()/exp.getWcs().pixelScale().asArcseconds() hsize = int(0.5*exp.getWidth()/(scale*rat)) rexp = afwImage.ExposureF(2*hsize + 1, 2*hsize + 1) rexp.setWcs(afwImage.Wcs(pos.getPosition(), afwGeom.Point2D(hsize, hsize), im.getWcs().getCDMatrix()*scale)) afwMath.warpExposure(rexp, exp, warpingControl) else: print "\nI'm unable to remap the cosmos image to your coordinates, sorry" rexp = exp.getMaskedImage().getImage() frame += 1 rim = rexp if hasattr(rim, "getMaskedImage"): rim = rim.getMaskedImage().getImage() if hasattr(rim, "getImage"): rim = rim.getImage() disp = afwDisplay.Display(frame=frame) disp.mtv(rim) if hasattr(rexp, "getWcs"): cen = rexp.getWcs().skyToPixel(pos) - afwGeom.PointD(rexp.getXY0()) disp.pan(*cen) disp.dot('+', *cen)
def testSmallSrc(self): """Verify that a source image that is too small will not raise an exception This tests another bug that was fixed in ticket #2441 """ fromWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*lsst.geom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(358, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.1e-8*lsst.geom.degrees), ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0) imArr, maskArr, varArr = toExp.getMaskedImage().getArrays() self.assertTrue(np.all(np.isnan(imArr))) self.assertTrue(np.all(np.isinf(varArr))) noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA") self.assertTrue(np.all(maskArr == noDataBitMask))
def testSmallSrc(self): """Verify that a source image that is too small will not raise an exception This tests another bug that was fixed in ticket #2441 """ fromWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8 * lsst.geom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(358, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.1e-8 * lsst.geom.degrees), ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0) imArr, maskArr, varArr = toExp.getMaskedImage().getArrays() self.assertTrue(np.all(np.isnan(imArr))) self.assertTrue(np.all(np.isinf(varArr))) noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA") self.assertTrue(np.all(maskArr == noDataBitMask))
def testSmallSrc(self): """Verify that a source image that is too small will not raise an exception This tests another bug that was fixed in ticket #2441 """ fromWcs = makeWcs( pixelScale=afwGeom.Angle(1.0e-8, afwGeom.degrees), projection="TAN", crPixPos=(0, 0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(359, 0), afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs) toWcs = makeWcs( pixelScale=afwGeom.Angle(1.1e-8, afwGeom.degrees), projection="TAN", crPixPos=(0, 0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(358, 0), afwGeom.degrees), ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0) imArr, maskArr, varArr = toExp.getMaskedImage().getArrays() self.assertTrue(np.all(np.isnan(imArr))) self.assertTrue(np.all(np.isinf(varArr))) noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA") self.assertTrue(np.all(maskArr == noDataBitMask))
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = makeWcs( pixelScale=afwGeom.Angle(1.0e-8, afwGeom.degrees), projection="TAN", crPixPos=(0, 0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(359, 0), afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = makeWcs( pixelScale=afwGeom.Angle(0.00011, afwGeom.degrees), projection="CEA", crPixPos=(410000.0, 11441.0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(45, 0), afwGeom.degrees), doFlipX=True, ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def testSmallSrc(self): """Verify that a source image that is too small will not raise an exception This tests another bug that was fixed in ticket #2441 """ fromWcs = makeWcs( pixelScale = afwGeom.Angle(1.0e-8, afwGeom.degrees), projection = "TAN", crPixPos = (0, 0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(359, 0), afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs) toWcs = makeWcs( pixelScale = afwGeom.Angle(1.1e-8, afwGeom.degrees), projection = "TAN", crPixPos = (0, 0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(358, 0), afwGeom.degrees), ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(10,10), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0) imArr, maskArr, varArr = toExp.getMaskedImage().getArrays() self.assertTrue(numpy.alltrue(numpy.isnan(imArr))) self.assertTrue(numpy.alltrue(numpy.isinf(varArr))) edgeMask = afwImage.MaskU.getPlaneBitMask("NO_DATA") self.assertTrue(numpy.alltrue(maskArr == edgeMask))
def testNullWcs(self, interpLength=10): """Cannot warp from or into an exposure without a Wcs. """ exposureWithWcs = afwImage.ExposureF(originalExposurePath) mi = exposureWithWcs.getMaskedImage() exposureWithoutWcs = afwImage.ExposureF(mi.getDimensions()) warpingKernel = afwMath.BilinearWarpingKernel() try: afwMath.warpExposure(exposureWithWcs, exposureWithoutWcs, warpingKernel, interpLength) self.fail("warping from a source Exception with no Wcs should fail") except Exception: pass try: afwMath.warpExposure(exposureWithoutWcs, exposureWithWcs, warpingKernel, interpLength) self.fail("warping into a destination Exception with no Wcs should fail") except Exception: pass
def main(): DefKernel = "lanczos4" DefVerbosity = 1 usage = """usage: %%prog [options] srcExposure refExposure destExposure Computes destExposure = srcExposure warped to match refExposure's WCS and bounding box, where exposure arguments are paths to Exposure fits files""" parser = optparse.OptionParser(usage) parser.add_option( "-k", "--kernel", type=str, default=DefKernel, help="kernel type: bilinear or lancszosN where N = order; default=%s" % (DefKernel, )) parser.add_option( "-v", "--verbosity", type=int, default=DefVerbosity, help= "verbosity of diagnostic trace messages; 1 for just TRACE1, more for more" + " information; default=%s" % (DefVerbosity, )) (opt, args) = parser.parse_args() log.configure() kernelName = opt.kernel.lower() if len(args) != 3: parser.error("You must supply three arguments") srcExposurePath = args[0] refExposurePath = args[1] destExposurePath = args[2] print("Remapping exposure :", srcExposurePath) print("to match wcs and bbox of:", refExposurePath) print("using", kernelName, "kernel") warpingControl = afwMath.WarpingControl(kernelName) srcExposure = afwImage.ExposureF(srcExposurePath) destExposure = afwImage.ExposureF(refExposurePath) if opt.verbosity > 0: print("Verbosity =", opt.verbosity) logUtils.traceSetAt("afw.math.warp", opt.verbosity) numGoodPixels = afwMath.warpExposure(destExposure, srcExposure, warpingControl) print("Warped exposure has %s good pixels" % (numGoodPixels)) print("Writing warped exposure to %s" % (destExposurePath, )) destExposure.writeFits(destExposurePath)
def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ wcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(0, 0), crval=afwGeom.SpherePoint(359, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(1.0e-8*afwGeom.degrees), ) exposure = afwImage.ExposureF(afwGeom.Extent2I(100, 100), wcs) maskedImage = exposure.getMaskedImage() warpingControl = afwMath.WarpingControl( "bilinear", "", 0, interpLength) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposure, exposure, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage, wcs, maskedImage, wcs, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage.getImage(), wcs, maskedImage.getImage(), wcs, warpingControl)
def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ wcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(1.0e-8*lsst.geom.degrees), ) exposure = afwImage.ExposureF(lsst.geom.Extent2I(100, 100), wcs) maskedImage = exposure.getMaskedImage() warpingControl = afwMath.WarpingControl( "bilinear", "", 0, interpLength) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposure, exposure, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage, wcs, maskedImage, wcs, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage.getImage(), wcs, maskedImage.getImage(), wcs, warpingControl)
def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ originalExposure = afwImage.ExposureF(afwGeom.Extent2I(100, 100)) warpingKernel = afwMath.BilinearWarpingKernel() try: afwMath.warpExposure(originalExposure, originalExposure, warpingKernel, interpLength) self.fail("warpExposure in place (dest is src) should fail") except Exception: pass try: afwMath.warpImage(originalExposure.getMaskedImage(), originalExposure.getWcs(), originalExposure.getMaskedImage(), originalExposure.getWcs(), warpingKernel, interpLength) self.fail("warpImage<MaskedImage> in place (dest is src) should fail") except Exception: pass try: afwMath.warpImage(originalExposure.getImage(), originalExposure.getWcs(), originalExposure.getImage(), originalExposure.getWcs(), warpingKernel, interpLength) self.fail("warpImage<Image> in place (dest is src) should fail") except Exception: pass
def testNullWcs(self, interpLength=10): """Cannot warp from or into an exposure without a Wcs. """ exposureWithWcs = afwImage.ExposureF(originalExposurePath) mi = exposureWithWcs.getMaskedImage() exposureWithoutWcs = afwImage.ExposureF(mi.getDimensions()) warpingControl = afwMath.WarpingControl("bilinear", "", 0, interpLength) try: afwMath.warpExposure(exposureWithWcs, exposureWithoutWcs, warpingControl) self.fail( "warping from a source Exception with no Wcs should fail") except Exception: pass try: afwMath.warpExposure(exposureWithoutWcs, exposureWithWcs, warpingControl) self.fail( "warping into a destination Exception with no Wcs should fail") except Exception: pass
def main(): DefKernel = "lanczos4" DefVerbosity = 1 usage = """usage: %%prog [options] srcExposure refExposure destExposure Computes destExposure = srcExposure warped to match refExposure's WCS and bounding box, where exposure arguments are paths to Exposure fits files""" parser = optparse.OptionParser(usage) parser.add_option("-k", "--kernel", type=str, default=DefKernel, help="kernel type: bilinear or lancszosN where N = order; default=%s" % (DefKernel,)) parser.add_option("-v", "--verbosity", type=int, default=DefVerbosity, help="verbosity of diagnostic trace messages; 1 for just TRACE1, more for more" " information; default=%s" % (DefVerbosity,)) (opt, args) = parser.parse_args() log.configure() kernelName = opt.kernel.lower() if len(args) != 3: parser.error("You must supply three arguments") srcExposurePath = args[0] refExposurePath = args[1] destExposurePath = args[2] print("Remapping exposure :", srcExposurePath) print("to match wcs and bbox of:", refExposurePath) print("using", kernelName, "kernel") warpingControl = afwMath.WarpingControl(kernelName) srcExposure = afwImage.ExposureF(srcExposurePath) destExposure = afwImage.ExposureF(refExposurePath) if opt.verbosity > 0: print("Verbosity =", opt.verbosity) logUtils.traceSetAt("afw.math.warp", opt.verbosity) numGoodPixels = afwMath.warpExposure( destExposure, srcExposure, warpingControl) print("Warped exposure has %s good pixels" % (numGoodPixels)) print("Writing warped exposure to %s" % (destExposurePath,)) destExposure.writeFits(destExposurePath)
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - edge pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ originalExposure = afwImage.ExposureF(originalExposurePath) afwWarpedExposure = afwImage.ExposureF(originalExposurePath) warpingKernel = afwMath.LanczosWarpingKernel(4) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingKernel, interpLength) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull") afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-edge pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels edgeMaskArr = afwWarpedMaskArr & edgeBitMask originalMaskedImageArrSet = originalExposure.getMaskedImage().getArrays() errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doMask=False, skipMaskArr=edgeMaskArr, atol=1e-5) if errStr: self.fail("afw null-warped MaskedImage (all pixels, relaxed tolerance): %s" % (errStr,)) # compare good pixels of image, mask and variance using full tolerance errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doImage=False, doVariance=False, skipMaskArr=afwWarpedMaskArr) if errStr: self.fail("afw null-warped MaskedImage (good pixels, max tolerance): %s" % (errStr,))
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*lsst.geom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(410000, 11441), crval=lsst.geom.SpherePoint(45, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.00011*lsst.geom.degrees, flipX=True), projection="CEA", ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(0, 0), crval=afwGeom.SpherePoint(359, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(410000, 11441), crval=afwGeom.SpherePoint(45, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.00011*afwGeom.degrees, flipX=True), projection="CEA", ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = makeWcs( pixelScale = afwGeom.Angle(1.0e-8, afwGeom.degrees), projection = "TAN", crPixPos = (0, 0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(359, 0), afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = makeWcs( pixelScale = afwGeom.Angle(0.00011, afwGeom.degrees), projection = "CEA", crPixPos = (410000.0, 11441.0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(45, 0), afwGeom.degrees), doFlipX = True, ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0,0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def timeWarp(destExposure, srcExposure, warpingControl): """Time warpExposure int warpExposure( DestExposureT &destExposure, SrcExposureT const &srcExposure, SeparableKernel &warpingKernel, int const interpLength=0); @param destExposure: output exposure (including a WCS) @param srcExposure: input exposure (including a WCS) @param warpingKernel: warping kernel @param interpLength: interpolation length (0 for no interpolation) @return (elapsed time in seconds, number of iterations) """ startTime = time.time(); for nIter in range(1, MaxIter + 1): goodPix = afwMath.warpExposure(destExposure, srcExposure, warpingControl) endTime = time.time() if endTime - startTime > MaxTime: break return (endTime - startTime, nIter, goodPix)
def timeWarp(destExposure, srcExposure, warpingKernel, interpLength): """Time warpExposure int warpExposure( DestExposureT &destExposure, SrcExposureT const &srcExposure, SeparableKernel &warpingKernel, int const interpLength=0); @param destExposure: output exposure (including a WCS) @param srcExposure: input exposure (including a WCS) @param warpingKernel: warping kernel @param interpLength: interpolation length (0 for no interpolation) @return (elapsed time in seconds, number of iterations) """ startTime = time.time(); for nIter in range(1, MaxIter + 1): goodPix = afwMath.warpExposure(destExposure, srcExposure, warpingKernel, interpLength) endTime = time.time() if endTime - startTime > MaxTime: break return (endTime - startTime, nIter, goodPix)
def verifyMaskWarp(self, kernelName, maskKernelName, growFullMask, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Verify that using a separate mask warping kernel produces the correct results Inputs: - kernelName: name of warping kernel in the form used by afwImage.makeKernel - maskKernelName: name of mask warping kernel in the form used by afwImage.makeKernel - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by np.allclose - atol: absolute tolerance as used by np.allclose """ srcWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(10, 11), crval=lsst.geom.SpherePoint(41.7, 32.9, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.2*lsst.geom.degrees), ) destWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(9, 10), crval=lsst.geom.SpherePoint(41.65, 32.95, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.17*lsst.geom.degrees), ) srcMaskedImage = afwImage.MaskedImageF(100, 101) srcExposure = afwImage.ExposureF(srcMaskedImage, srcWcs) srcArrays = srcMaskedImage.getArrays() shape = srcArrays[0].shape srcArrays[0][:] = np.random.normal(10000, 1000, size=shape) srcArrays[2][:] = np.random.normal(9000, 900, size=shape) srcArrays[1][:] = np.reshape( np.arange(0, shape[0] * shape[1], 1, dtype=np.uint16), shape) warpControl = afwMath.WarpingControl( kernelName, maskKernelName, cacheSize, interpLength, growFullMask ) destMaskedImage = afwImage.MaskedImageF(110, 121) destExposure = afwImage.ExposureF(destMaskedImage, destWcs) afwMath.warpExposure(destExposure, srcExposure, warpControl) # now compute with two separate mask planes warpControl.setGrowFullMask(0) narrowMaskedImage = afwImage.MaskedImageF(110, 121) narrowExposure = afwImage.ExposureF(narrowMaskedImage, destWcs) afwMath.warpExposure(narrowExposure, srcExposure, warpControl) narrowArrays = narrowExposure.getMaskedImage().getArrays() warpControl.setMaskWarpingKernelName("") broadMaskedImage = afwImage.MaskedImageF(110, 121) broadExposure = afwImage.ExposureF(broadMaskedImage, destWcs) afwMath.warpExposure(broadExposure, srcExposure, warpControl) broadArrays = broadExposure.getMaskedImage().getArrays() if (kernelName != maskKernelName) and (growFullMask != 0xFFFF): # we expect the mask planes to differ if np.all(narrowArrays[1] == broadArrays[1]): self.fail("No difference between broad and narrow mask") predMask = (broadArrays[1] & growFullMask) | ( narrowArrays[1] & ~growFullMask).astype(np.uint16) predArraySet = (broadArrays[0], predMask, broadArrays[2]) predExposure = afwImage.makeMaskedImageFromArrays(*predArraySet) msg = "Separate mask warping failed; warpingKernel=%s; maskWarpingKernel=%s" % \ (kernelName, maskKernelName) self.assertMaskedImagesAlmostEqual(destExposure.getMaskedImage(), predExposure, doImage=True, doMask=True, doVariance=True, rtol=rtol, atol=atol, msg=msg)
def main(): DefDataDir = eups.productDir("afwdata") or "" DefOriginalExposurePath = os.path.join(DefDataDir, "med") DefWcsImageOrExposurePath = os.path.join(DefDataDir, "medswarp1lanczos4.fits") DefOutputExposurePath = "warpedExposure" DefKernel = "lanczos4" DefVerbosity = 6 # change to 0 once this all works to hide all messages usage = """usage: %%prog [options] [originalExposure [warpedWcsImageOrExposure [outputExposure]]] Computes outputExposure = originalExposure warped to match warpedWcsExposure's WCS and size Note: - exposure arguments are paths to Exposure fits files; they must NOT include the final _img.fits|_var.fits|_msk.fits if warpedWcsImageOrExposure ends in .fits then it specifies an image - default originalExposure = %s - default warpedWcsImageOrExposure = %s - default outputExposure = %s """ % (DefOriginalExposurePath, DefWcsImageOrExposurePath, DefOutputExposurePath) parser = optparse.OptionParser(usage) parser.add_option("-k", "--kernel", type=str, default=DefKernel, help="kernel type: bilinear or lancszosN where N = order; default=%s" % (DefKernel,)) parser.add_option("-v", "--verbosity", type=int, default=DefVerbosity, help="verbosity of diagnostic trace messages; 1 for just warnings, more for more" + \ " information; default=%s" % (DefVerbosity,)) (opt, args) = parser.parse_args() kernelName = opt.kernel.lower() kernel = afwMath.makeWarpingKernel(kernelName) def getArg(ind, defValue): if ind < len(args): return args[ind] return defValue originalExposurePath = getArg(0, DefOriginalExposurePath) warpedWcsImageOrExposurePath = getArg(1, DefWcsImageOrExposurePath) outputExposurePath = getArg(2, DefOutputExposurePath) print "Remapping masked image ", originalExposurePath print "to match wcs and size of", warpedWcsImageOrExposurePath print "using", kernelName, "kernel" originalExposure = afwImage.ExposureF(originalExposurePath) if warpedWcsImageOrExposurePath.lower().endswith(".fits"): # user specified an image, not an exposure warpedDI = afwImage.DecoratedImageF(warpedWcsImageOrExposurePath) warpedWcs = afwImage.makeWcs(warpedDI.getMetadata()) warpedMI = afwImage.MaskedImageF(afwGeom.Extent2I(warpedDI.getWidth(), warpedDI.getHeight())) warpedExposure = afwImage.ExposureF(warpedMI, warpedWcs) else: warpedExposure = afwImage.ExposureF(warpedWcsImageOrExposurePath) if opt.verbosity > 0: print "Verbosity =", opt.verbosity lsst.pex.logging.Trace_setVerbosity("lsst.afw.math", opt.verbosity) numGoodPixels = afwMath.warpExposure(warpedExposure, originalExposure, kernel) print "Warped exposure has %s good pixels" % (numGoodPixels) print "Writing warped exposure to %s" % (outputExposurePath,) warpedExposure.writeFits(outputExposurePath)
def verifyMaskWarp(self, kernelName, maskKernelName, growFullMask, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Verify that using a separate mask warping kernel produces the correct results Inputs: - kernelName: name of warping kernel in the form used by afwImage.makeKernel - maskKernelName: name of mask warping kernel in the form used by afwImage.makeKernel - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by numpy.allclose - atol: absolute tolerance as used by numpy.allclose """ srcWcs = makeWcs( pixelScale=afwGeom.Angle(0.2, afwGeom.degrees), crPixPos=(10.0, 11.0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(41.7, 32.9), afwGeom.degrees), ) destWcs = makeWcs( pixelScale=afwGeom.Angle(0.17, afwGeom.degrees), crPixPos=(9.0, 10.0), crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(41.65, 32.95), afwGeom.degrees), posAng=afwGeom.Angle(31, afwGeom.degrees), ) srcMaskedImage = afwImage.MaskedImageF(100, 101) srcExposure = afwImage.ExposureF(srcMaskedImage, srcWcs) destMaskedImage = afwImage.MaskedImageF(110, 121) destExposure = afwImage.ExposureF(destMaskedImage, destWcs) srcArrays = srcMaskedImage.getArrays() shape = srcArrays[0].shape numpy.random.seed(0) srcArrays[0][:] = numpy.random.normal(10000, 1000, size=shape) srcArrays[2][:] = numpy.random.normal(9000, 900, size=shape) srcArrays[1][:] = numpy.reshape( numpy.arange(0, shape[0] * shape[1], 1, dtype=numpy.uint16), shape) warpControl = afwMath.WarpingControl(kernelName, maskKernelName, cacheSize, interpLength, afwGpu.DEFAULT_DEVICE_PREFERENCE, growFullMask) afwMath.warpExposure(destExposure, srcExposure, warpControl) afwArrays = [ numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays() ] # now compute with two separate mask planes warpControl.setGrowFullMask(0) afwMath.warpExposure(destExposure, srcExposure, warpControl) narrowArrays = [ numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays() ] warpControl.setMaskWarpingKernelName("") afwMath.warpExposure(destExposure, srcExposure, warpControl) broadArrays = [ numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays() ] if (kernelName != maskKernelName) and (growFullMask != 0xFFFF): # we expect the mask planes to differ if numpy.allclose(broadArrays[1], narrowArrays[1]): self.fail("No difference between broad and narrow mask") predMask = (broadArrays[1] & growFullMask) | (narrowArrays[1] & ~growFullMask) predArraySet = (broadArrays[0], predMask, broadArrays[2]) errStr = imageTestUtils.maskedImagesDiffer(afwArrays, predArraySet, doImage=True, doMask=True, doVariance=True, rtol=rtol, atol=atol) if errStr: self.fail("Separate mask warping failed; warpingKernel=%s; maskWarpingKernel=%s; error=%s" % \ (kernelName, maskKernelName, errStr))
def verifyMaskWarp(self, kernelName, maskKernelName, growFullMask, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Verify that using a separate mask warping kernel produces the correct results Inputs: - kernelName: name of warping kernel in the form used by afwImage.makeKernel - maskKernelName: name of mask warping kernel in the form used by afwImage.makeKernel - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by np.allclose - atol: absolute tolerance as used by np.allclose """ srcWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(10, 11), crval=lsst.geom.SpherePoint(41.7, 32.9, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.2 * lsst.geom.degrees), ) destWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(9, 10), crval=lsst.geom.SpherePoint(41.65, 32.95, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.17 * lsst.geom.degrees), ) srcMaskedImage = afwImage.MaskedImageF(100, 101) srcExposure = afwImage.ExposureF(srcMaskedImage, srcWcs) srcArrays = srcMaskedImage.getArrays() shape = srcArrays[0].shape srcArrays[0][:] = np.random.normal(10000, 1000, size=shape) srcArrays[2][:] = np.random.normal(9000, 900, size=shape) srcArrays[1][:] = np.reshape( np.arange(0, shape[0] * shape[1], 1, dtype=np.uint16), shape) warpControl = afwMath.WarpingControl(kernelName, maskKernelName, cacheSize, interpLength, growFullMask) destMaskedImage = afwImage.MaskedImageF(110, 121) destExposure = afwImage.ExposureF(destMaskedImage, destWcs) afwMath.warpExposure(destExposure, srcExposure, warpControl) # now compute with two separate mask planes warpControl.setGrowFullMask(0) narrowMaskedImage = afwImage.MaskedImageF(110, 121) narrowExposure = afwImage.ExposureF(narrowMaskedImage, destWcs) afwMath.warpExposure(narrowExposure, srcExposure, warpControl) narrowArrays = narrowExposure.getMaskedImage().getArrays() warpControl.setMaskWarpingKernelName("") broadMaskedImage = afwImage.MaskedImageF(110, 121) broadExposure = afwImage.ExposureF(broadMaskedImage, destWcs) afwMath.warpExposure(broadExposure, srcExposure, warpControl) broadArrays = broadExposure.getMaskedImage().getArrays() if (kernelName != maskKernelName) and (growFullMask != 0xFFFF): # we expect the mask planes to differ if np.all(narrowArrays[1] == broadArrays[1]): self.fail("No difference between broad and narrow mask") predMask = (broadArrays[1] & growFullMask) | ( narrowArrays[1] & ~growFullMask).astype(np.uint16) predArraySet = (broadArrays[0], predMask, broadArrays[2]) predExposure = afwImage.makeMaskedImageFromArrays(*predArraySet) msg = f"Separate mask warping failed; warpingKernel={kernelName}; maskWarpingKernel={maskKernelName}" self.assertMaskedImagesAlmostEqual(destExposure.getMaskedImage(), predExposure, doImage=True, doMask=True, doVariance=True, rtol=rtol, atol=atol, msg=msg)
def compareToSwarp(self, kernelName, useWarpExposure=True, useSubregion=False, useDeepCopy=False, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Compare warpExposure to swarp for given warping kernel. Note that swarp only warps the image plane, so only test that plane. Inputs: - kernelName: name of kernel in the form used by afwImage.makeKernel - useWarpExposure: if True, call warpExposure to warp an ExposureF, else call warpImage to warp an ImageF and also call the Transform version - useSubregion: if True then the original source exposure (from which the usual test exposure was extracted) is read and the correct subregion extracted - useDeepCopy: if True then the copy of the subimage is a deep copy, else it is a shallow copy; ignored if useSubregion is False - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by np.allclose - atol: absolute tolerance as used by np.allclose """ warpingControl = afwMath.WarpingControl( kernelName, "", # there is no point to a separate mask kernel since we aren't testing the mask plane cacheSize, interpLength, ) if useSubregion: originalFullExposure = afwImage.ExposureF(originalExposurePath) # "medsub" is a subregion of med starting at 0-indexed pixel (40, 150) of size 145 x 200 bbox = lsst.geom.Box2I(lsst.geom.Point2I(40, 150), lsst.geom.Extent2I(145, 200)) originalExposure = afwImage.ExposureF( originalFullExposure, bbox, afwImage.LOCAL, useDeepCopy) swarpedImageName = "medsubswarp1%s.fits" % (kernelName,) else: originalExposure = afwImage.ExposureF(originalExposurePath) swarpedImageName = "medswarp1%s.fits" % (kernelName,) swarpedImagePath = os.path.join(dataDir, swarpedImageName) swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath) swarpedImage = swarpedDecoratedImage.getImage() swarpedMetadata = swarpedDecoratedImage.getMetadata() warpedWcs = afwGeom.makeSkyWcs(swarpedMetadata) if useWarpExposure: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedExposure1%s.fits" % (kernelName,) afwWarpedMaskedImage = afwImage.MaskedImageF( swarpedImage.getDimensions()) afwWarpedExposure = afwImage.ExposureF( afwWarpedMaskedImage, warpedWcs) afwMath.warpExposure( afwWarpedExposure, originalExposure, warpingControl) afwWarpedMask = afwWarpedMaskedImage.getMask() if SAVE_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) if display: afwDisplay.Display(frame=1).mtv(afwWarpedExposure, title="Warped") swarpedMaskedImage = afwImage.MaskedImageF(swarpedImage) if display: afwDisplay.Display(frame=2).mtv(swarpedMaskedImage, title="SWarped") msg = "afw and swarp %s-warped differ (ignoring bad pixels)" % ( kernelName,) try: self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, swarpedMaskedImage, doImage=True, doMask=False, doVariance=False, skipMask=afwWarpedMask, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) print("Saved failed afw-warped exposure as: %s" % (afwWarpedImagePath,)) raise else: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedImage1%s.fits" % (kernelName,) afwWarpedImage2Path = "afwWarpedImage1%s_xyTransform.fits" % ( kernelName,) afwWarpedImage = afwImage.ImageF(swarpedImage.getDimensions()) originalImage = originalExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwMath.warpImage(afwWarpedImage, warpedWcs, originalImage, originalWcs, warpingControl) if display: afwDisplay.Display(frame=1).mtv(afwWarpedImage, title="Warped") afwDisplay.Display(frame=2).mtv(swarpedImage, title="SWarped") diff = swarpedImage.Factory(swarpedImage, True) diff -= afwWarpedImage afwDisplay.Display(frame=3).mtv(diff, title="swarp - afw") if SAVE_FITS_FILES: afwWarpedImage.writeFits(afwWarpedImagePath) afwWarpedImageArr = afwWarpedImage.getArray() noDataMaskArr = np.isnan(afwWarpedImageArr) msg = "afw and swarp %s-warped images do not match (ignoring NaN pixels)" % \ (kernelName,) try: self.assertImagesAlmostEqual(afwWarpedImage, swarpedImage, skipMask=noDataMaskArr, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImagePath) print("Saved failed afw-warped image as: %s" % (afwWarpedImagePath,)) raise afwWarpedImage2 = afwImage.ImageF(swarpedImage.getDimensions()) srcToDest = afwGeom.makeWcsPairTransform(originalWcs, warpedWcs) afwMath.warpImage(afwWarpedImage2, originalImage, srcToDest, warpingControl) msg = "afw transform-based and WCS-based %s-warped images do not match" % ( kernelName,) try: self.assertImagesAlmostEqual(afwWarpedImage2, afwWarpedImage, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImagePath) print("Saved failed afw-warped image as: %s" % (afwWarpedImage2Path,)) raise
def compareToSwarp(self, kernelName, useWarpExposure=True, useSubregion=False, useDeepCopy=False, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Compare warpExposure to swarp for given warping kernel. Note that swarp only warps the image plane, so only test that plane. Inputs: - kernelName: name of kernel in the form used by afwImage.makeKernel - useWarpExposure: if True, call warpExposure to warp an ExposureF, else call warpImage to warp an ImageF - useSubregion: if True then the original source exposure (from which the usual test exposure was extracted) is read and the correct subregion extracted - useDeepCopy: if True then the copy of the subimage is a deep copy, else it is a shallow copy; ignored if useSubregion is False - interpLength: interpLength argument for lsst.afw.math.warpExposure - cacheSize: cacheSize argument for lsst.afw.math.SeparableKernel.computeCache; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by numpy.allclose - atol: absolute tolerance as used by numpy.allclose """ warpingKernel = afwMath.makeWarpingKernel(kernelName) warpingKernel.computeCache(cacheSize) if useSubregion: originalFullExposure = afwImage.ExposureF(originalExposurePath) # "medsub" is a subregion of med starting at 0-indexed pixel (40, 150) of size 145 x 200 bbox = afwGeom.Box2I(afwGeom.Point2I(40, 150), afwGeom.Extent2I(145, 200)) originalExposure = afwImage.ExposureF(originalFullExposure, bbox, afwImage.LOCAL, useDeepCopy) swarpedImageName = "medsubswarp1%s.fits" % (kernelName,) else: originalExposure = afwImage.ExposureF(originalExposurePath) swarpedImageName = "medswarp1%s.fits" % (kernelName,) swarpedImagePath = os.path.join(dataDir, swarpedImageName) swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath) swarpedImage = swarpedDecoratedImage.getImage() swarpedMetadata = swarpedDecoratedImage.getMetadata() warpedWcs = afwImage.makeWcs(swarpedMetadata) if useWarpExposure: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedExposure1%s" % (kernelName,) afwWarpedMaskedImage = afwImage.MaskedImageF(swarpedImage.getDimensions()) afwWarpedExposure = afwImage.ExposureF(afwWarpedMaskedImage, warpedWcs) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingKernel, interpLength) if SAVE_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) if display: ds9.mtv(afwWarpedExposure, frame=1, title="Warped") afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] swarpedMaskedImage = afwImage.MaskedImageF(swarpedImage) swarpedMaskedImageArrSet = swarpedMaskedImage.getArrays() if display: ds9.mtv(swarpedMaskedImage, frame=2, title="SWarped") errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, swarpedMaskedImageArrSet, doImage=True, doMask=False, doVariance=False, skipMaskArr=afwWarpedMaskArr, rtol=rtol, atol=atol) if errStr: if SAVE_FAILED_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) print "Saved failed afw-warped exposure as: %s" % (afwWarpedImagePath,) self.fail("afw and swarp %s-warped %s (ignoring bad pixels)" % (kernelName, errStr)) else: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedImage1%s.fits" % (kernelName,) afwWarpedImage = afwImage.ImageF(swarpedImage.getDimensions()) originalImage = originalExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwMath.warpImage(afwWarpedImage, warpedWcs, originalImage, originalWcs, warpingKernel, interpLength) if display: ds9.mtv(afwWarpedImage, frame=1, title="Warped") ds9.mtv(swarpedImage, frame=2, title="SWarped") diff = swarpedImage.Factory(swarpedImage, True) diff -= afwWarpedImage ds9.mtv(diff, frame=3, title="swarp - afw") if SAVE_FITS_FILES: afwWarpedImage.writeFits(afwWarpedImagePath) afwWarpedImageArr = afwWarpedImage.getArray() swarpedImageArr = swarpedImage.getArray() edgeMaskArr = numpy.isnan(afwWarpedImageArr) errStr = imageTestUtils.imagesDiffer(afwWarpedImageArr, swarpedImageArr, skipMaskArr=edgeMaskArr, rtol=rtol, atol=atol) if errStr: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImagePath) print "Saved failed afw-warped image as: %s" % (afwWarpedImagePath,) self.fail("afw and swarp %s-warped images do not match (ignoring NaN pixels): %s" % \ (kernelName, errStr))
def testNullWarpExposure(self, interpLength=10): """Test that warpExposure maps an image onto itself. Note: - edge pixels must be ignored - bad mask pixels get smeared out so we have to excluded all bad mask pixels from the output image when comparing masks. """ filterPolicyFile = pexPolicy.DefaultPolicyFile("afw", "SdssFilters.paf", "tests") filterPolicy = pexPolicy.Policy.createPolicy( filterPolicyFile, filterPolicyFile.getRepositoryPath(), True) imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True) originalExposure = afwImage.ExposureF(originalExposurePath) originalFilter = afwImage.Filter("i") originalCalib = afwImage.Calib() originalCalib.setFluxMag0(1.0e5, 1.0e3) originalExposure.setFilter(originalFilter) originalExposure.setCalib(originalCalib) afwWarpedExposure = afwImage.ExposureF(originalExposure.getBBox(), originalExposure.getWcs()) warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits("afwWarpedExposureNull.fits") self.assertEquals(afwWarpedExposure.getFilter().getName(), originalFilter.getName()) self.assertEquals(afwWarpedExposure.getCalib().getFluxMag0(), originalCalib.getFluxMag0()) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] # compare all non-edge pixels of image and variance, but relax specs a bit # because of minor noise introduced by bad pixels edgeMaskArr = afwWarpedMaskArr & edgeBitMask originalMaskedImageArrSet = originalExposure.getMaskedImage( ).getArrays() errStr = imageTestUtils.maskedImagesDiffer(afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doMask=False, skipMaskArr=edgeMaskArr, atol=1e-5) if errStr: self.fail( "afw null-warped MaskedImage (all pixels, relaxed tolerance): %s" % (errStr, )) # compare good pixels of image, mask and variance using full tolerance errStr = imageTestUtils.maskedImagesDiffer( afwWarpedMaskedImageArrSet, originalMaskedImageArrSet, doImage=False, doVariance=False, skipMaskArr=afwWarpedMaskArr) if errStr: self.fail( "afw null-warped MaskedImage (good pixels, max tolerance): %s" % (errStr, ))
print " Compute coadd component" coaddComponent = coaddKaiser.CoaddComponent(exposure, psfKernel, normalizePsf) print " Divide exposure by sigma squared = %s" % (coaddComponent.getSigmaSq(),) blurredExposure = coaddComponent.getBlurredExposure() blurredMaskedImage = blurredExposure.getMaskedImage() sigmaSq = coaddComponent.getSigmaSq() if saveImages: blurredExposure.writeFits("blurred%s" % (fileName,)) blurredMaskedImage /= sigmaSq if saveImages: blurredExposure.writeFits("scaledBlurred%s" % (fileName,)) print " Remap blurred exposure to match coadd WCS" remappedBlurredMaskedImage = afwImage.MaskedImageD( coaddExposure.getWidth(), coaddExposure.getHeight()) remappedBlurredExposure = afwImage.ExposureD(remappedBlurredMaskedImage, coaddWcs) if saveImages: remappedBlurredExposure.writeFits("remappedBlurred%s" % (fileName,)) nGoodPix = afwMath.warpExposure(remappedBlurredExposure, blurredExposure, afwMath.LanczosWarpingKernel(3)) nPix = coaddExposure.getWidth() * coaddExposure.getHeight() print " Remapped image has %d good pixels (%0.0f %%)" % (nGoodPix, 100 * nGoodPix / float(nPix)) print " Add remapped blurred exposure to coadd and save updated coadd exposure" coaddUtils.addToCoadd(coaddMaskedImage, depthMap, remappedBlurredExposure.getMaskedImage(), coaddMask) coaddExposure.writeFits(outName) depthMap.writeFits(depthOutName) coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), depthMap) coaddExposure.writeFits(outName)
def verifyMaskWarp(self, kernelName, maskKernelName, growFullMask, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Verify that using a separate mask warping kernel produces the correct results Inputs: - kernelName: name of warping kernel in the form used by afwImage.makeKernel - maskKernelName: name of mask warping kernel in the form used by afwImage.makeKernel - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by numpy.allclose - atol: absolute tolerance as used by numpy.allclose """ srcWcs = makeWcs( pixelScale = afwGeom.Angle(0.2, afwGeom.degrees), crPixPos = (10.0, 11.0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(41.7, 32.9), afwGeom.degrees), ) destWcs = makeWcs( pixelScale = afwGeom.Angle(0.17, afwGeom.degrees), crPixPos = (9.0, 10.0), crValCoord = afwCoord.IcrsCoord(afwGeom.Point2D(41.65, 32.95), afwGeom.degrees), posAng = afwGeom.Angle(31, afwGeom.degrees), ) srcMaskedImage = afwImage.MaskedImageF(100, 101) srcExposure = afwImage.ExposureF(srcMaskedImage, srcWcs) destMaskedImage = afwImage.MaskedImageF(110, 121) destExposure = afwImage.ExposureF(destMaskedImage, destWcs) srcArrays = srcMaskedImage.getArrays() shape = srcArrays[0].shape numpy.random.seed(0) srcArrays[0][:] = numpy.random.normal(10000, 1000, size=shape) srcArrays[2][:] = numpy.random.normal( 9000, 900, size=shape) srcArrays[1][:] = numpy.reshape(numpy.arange(0, shape[0] * shape[1], 1, dtype=numpy.uint16), shape) warpControl = afwMath.WarpingControl( kernelName, maskKernelName, cacheSize, interpLength, afwGpu.DEFAULT_DEVICE_PREFERENCE, growFullMask ) afwMath.warpExposure(destExposure, srcExposure, warpControl) afwArrays = [numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays()] # now compute with two separate mask planes warpControl.setGrowFullMask(0) afwMath.warpExposure(destExposure, srcExposure, warpControl) narrowArrays = [numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays()] warpControl.setMaskWarpingKernelName("") afwMath.warpExposure(destExposure, srcExposure, warpControl) broadArrays = [numpy.copy(arr) for arr in destExposure.getMaskedImage().getArrays()] if (kernelName != maskKernelName) and (growFullMask != 0xFFFF): # we expect the mask planes to differ if numpy.allclose(broadArrays[1], narrowArrays[1]): self.fail("No difference between broad and narrow mask") predMask = (broadArrays[1] & growFullMask) | (narrowArrays[1] & ~growFullMask) predArraySet = (broadArrays[0], predMask, broadArrays[2]) errStr = imageTestUtils.maskedImagesDiffer(afwArrays, predArraySet, doImage=True, doMask=True, doVariance=True, rtol=rtol, atol=atol) if errStr: if SAVE_FAILED_FITS_FILES: computedExposure.writeFits(computedExposurePath) expectedExposure.writeFits(expectedExposurePath) print "Saved failed afw-warped exposures as: %s and %s" % \ (computedExposurePath, expectedExposure) self.fail("Separate mask warping failed; warpingKernel=%s; maskWarpingKernel=%s; error=%s" % \ (kernelName, maskKernelName, errStr))
def compareToSwarp(self, kernelName, useWarpExposure=True, useSubregion=False, useDeepCopy=False, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Compare warpExposure to swarp for given warping kernel. Note that swarp only warps the image plane, so only test that plane. Inputs: - kernelName: name of kernel in the form used by afwImage.makeKernel - useWarpExposure: if True, call warpExposure to warp an ExposureF, else call warpImage to warp an ImageF - useSubregion: if True then the original source exposure (from which the usual test exposure was extracted) is read and the correct subregion extracted - useDeepCopy: if True then the copy of the subimage is a deep copy, else it is a shallow copy; ignored if useSubregion is False - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by numpy.allclose - atol: absolute tolerance as used by numpy.allclose """ warpingControl = afwMath.WarpingControl( kernelName, "", # there is no point to a separate mask kernel since we aren't testing the mask plane cacheSize, interpLength, ) if useSubregion: originalFullExposure = afwImage.ExposureF(originalExposurePath) # "medsub" is a subregion of med starting at 0-indexed pixel (40, 150) of size 145 x 200 bbox = afwGeom.Box2I(afwGeom.Point2I(40, 150), afwGeom.Extent2I(145, 200)) originalExposure = afwImage.ExposureF(originalFullExposure, bbox, afwImage.LOCAL, useDeepCopy) swarpedImageName = "medsubswarp1%s.fits" % (kernelName, ) else: originalExposure = afwImage.ExposureF(originalExposurePath) swarpedImageName = "medswarp1%s.fits" % (kernelName, ) swarpedImagePath = os.path.join(dataDir, swarpedImageName) swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath) swarpedImage = swarpedDecoratedImage.getImage() swarpedMetadata = swarpedDecoratedImage.getMetadata() warpedWcs = afwImage.makeWcs(swarpedMetadata) if useWarpExposure: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedExposure1%s" % (kernelName, ) afwWarpedMaskedImage = afwImage.MaskedImageF( swarpedImage.getDimensions()) afwWarpedExposure = afwImage.ExposureF(afwWarpedMaskedImage, warpedWcs) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) if SAVE_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) if display: ds9.mtv(afwWarpedExposure, frame=1, title="Warped") afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays() afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1] swarpedMaskedImage = afwImage.MaskedImageF(swarpedImage) swarpedMaskedImageArrSet = swarpedMaskedImage.getArrays() if display: ds9.mtv(swarpedMaskedImage, frame=2, title="SWarped") errStr = imageTestUtils.maskedImagesDiffer( afwWarpedMaskedImageArrSet, swarpedMaskedImageArrSet, doImage=True, doMask=False, doVariance=False, skipMaskArr=afwWarpedMaskArr, rtol=rtol, atol=atol) if errStr: if SAVE_FAILED_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) print "Saved failed afw-warped exposure as: %s" % ( afwWarpedImagePath, ) self.fail("afw and swarp %s-warped %s (ignoring bad pixels)" % (kernelName, errStr)) else: # path for saved afw-warped image afwWarpedImagePath = "afwWarpedImage1%s.fits" % (kernelName, ) afwWarpedImage = afwImage.ImageF(swarpedImage.getDimensions()) originalImage = originalExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwMath.warpImage(afwWarpedImage, warpedWcs, originalImage, originalWcs, warpingControl) if display: ds9.mtv(afwWarpedImage, frame=1, title="Warped") ds9.mtv(swarpedImage, frame=2, title="SWarped") diff = swarpedImage.Factory(swarpedImage, True) diff -= afwWarpedImage ds9.mtv(diff, frame=3, title="swarp - afw") if SAVE_FITS_FILES: afwWarpedImage.writeFits(afwWarpedImagePath) afwWarpedImageArr = afwWarpedImage.getArray() swarpedImageArr = swarpedImage.getArray() edgeMaskArr = numpy.isnan(afwWarpedImageArr) errStr = imageTestUtils.imagesDiffer(afwWarpedImageArr, swarpedImageArr, skipMaskArr=edgeMaskArr, rtol=rtol, atol=atol) if errStr: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImagePath) print "Saved failed afw-warped image as: %s" % ( afwWarpedImagePath, ) self.fail("afw and swarp %s-warped images do not match (ignoring NaN pixels): %s" % \ (kernelName, errStr))
def compareToSwarp(self, kernelName, useWarpExposure=True, useSubregion=False, useDeepCopy=False, interpLength=10, cacheSize=100000, rtol=4e-05, atol=1e-2): """Compare warpExposure to swarp for given warping kernel. Note that swarp only warps the image plane, so only test that plane. Inputs: - kernelName: name of kernel in the form used by afwImage.makeKernel - useWarpExposure: if True, call warpExposure to warp an ExposureF, else call warpImage to warp an ImageF and also call the Transform version - useSubregion: if True then the original source exposure (from which the usual test exposure was extracted) is read and the correct subregion extracted - useDeepCopy: if True then the copy of the subimage is a deep copy, else it is a shallow copy; ignored if useSubregion is False - interpLength: interpLength argument for lsst.afw.math.WarpingControl - cacheSize: cacheSize argument for lsst.afw.math.WarpingControl; 0 disables the cache 10000 gives some speed improvement but less accurate results (atol must be increased) 100000 gives better accuracy but no speed improvement in this test - rtol: relative tolerance as used by np.allclose - atol: absolute tolerance as used by np.allclose """ warpingControl = afwMath.WarpingControl( kernelName, "", # there is no point to a separate mask kernel since we aren't testing the mask plane cacheSize, interpLength, ) if useSubregion: originalFullExposure = afwImage.ExposureF(originalExposurePath) # "medsub" is a subregion of med starting at 0-indexed pixel (40, 150) of size 145 x 200 bbox = lsst.geom.Box2I(lsst.geom.Point2I(40, 150), lsst.geom.Extent2I(145, 200)) originalExposure = afwImage.ExposureF(originalFullExposure, bbox, afwImage.LOCAL, useDeepCopy) swarpedImageName = f"medsubswarp1{kernelName}.fits" else: originalExposure = afwImage.ExposureF(originalExposurePath) swarpedImageName = f"medswarp1{kernelName}.fits" swarpedImagePath = os.path.join(dataDir, swarpedImageName) swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath) swarpedImage = swarpedDecoratedImage.getImage() swarpedMetadata = swarpedDecoratedImage.getMetadata() warpedWcs = afwGeom.makeSkyWcs(swarpedMetadata) if useWarpExposure: # path for saved afw-warped image afwWarpedImagePath = f"afwWarpedExposure1{kernelName}.fits" afwWarpedMaskedImage = afwImage.MaskedImageF( swarpedImage.getDimensions()) afwWarpedExposure = afwImage.ExposureF(afwWarpedMaskedImage, warpedWcs) afwMath.warpExposure(afwWarpedExposure, originalExposure, warpingControl) afwWarpedMask = afwWarpedMaskedImage.getMask() if SAVE_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) if display: afwDisplay.Display(frame=1).mtv(afwWarpedExposure, title="Warped") swarpedMaskedImage = afwImage.MaskedImageF(swarpedImage) if display: afwDisplay.Display(frame=2).mtv(swarpedMaskedImage, title="SWarped") msg = f"afw and swarp {kernelName}-warped differ (ignoring bad pixels)" try: self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage, swarpedMaskedImage, doImage=True, doMask=False, doVariance=False, skipMask=afwWarpedMask, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: afwWarpedExposure.writeFits(afwWarpedImagePath) print( f"Saved failed afw-warped exposure as: {afwWarpedImagePath}" ) raise else: # path for saved afw-warped image afwWarpedImagePath = f"afwWarpedImage1{kernelName}.fits" afwWarpedImage2Path = f"afwWarpedImage1{kernelName}_xyTransform.fits" afwWarpedImage = afwImage.ImageF(swarpedImage.getDimensions()) originalImage = originalExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwMath.warpImage(afwWarpedImage, warpedWcs, originalImage, originalWcs, warpingControl) if display: afwDisplay.Display(frame=1).mtv(afwWarpedImage, title="Warped") afwDisplay.Display(frame=2).mtv(swarpedImage, title="SWarped") diff = swarpedImage.Factory(swarpedImage, True) diff -= afwWarpedImage afwDisplay.Display(frame=3).mtv(diff, title="swarp - afw") if SAVE_FITS_FILES: afwWarpedImage.writeFits(afwWarpedImagePath) afwWarpedImageArr = afwWarpedImage.getArray() noDataMaskArr = np.isnan(afwWarpedImageArr) msg = f"afw and swarp {kernelName}-warped images do not match (ignoring NaN pixels)" try: self.assertImagesAlmostEqual(afwWarpedImage, swarpedImage, skipMask=noDataMaskArr, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImagePath) print( f"Saved failed afw-warped image as: {afwWarpedImagePath}" ) raise afwWarpedImage2 = afwImage.ImageF(swarpedImage.getDimensions()) srcToDest = afwGeom.makeWcsPairTransform(originalWcs, warpedWcs) afwMath.warpImage(afwWarpedImage2, originalImage, srcToDest, warpingControl) msg = f"afw transform-based and WCS-based {kernelName}-warped images do not match" try: self.assertImagesAlmostEqual(afwWarpedImage2, afwWarpedImage, rtol=rtol, atol=atol, msg=msg) except Exception: if SAVE_FAILED_FITS_FILES: # save the image anyway afwWarpedImage.writeFits(afwWarpedImage2) print( f"Saved failed afw-warped image as: {afwWarpedImage2Path}" ) raise
blurredMaskedImage = blurredExposure.getMaskedImage() sigmaSq = coaddComponent.getSigmaSq() if saveImages: blurredExposure.writeFits("blurred%s" % (fileName, )) blurredMaskedImage /= sigmaSq if saveImages: blurredExposure.writeFits("scaledBlurred%s" % (fileName, )) print " Remap blurred exposure to match coadd WCS" remappedBlurredMaskedImage = afwImage.MaskedImageD( coaddExposure.getWidth(), coaddExposure.getHeight()) remappedBlurredExposure = afwImage.ExposureD( remappedBlurredMaskedImage, coaddWcs) if saveImages: remappedBlurredExposure.writeFits("remappedBlurred%s" % (fileName, )) nGoodPix = afwMath.warpExposure(remappedBlurredExposure, blurredExposure, afwMath.LanczosWarpingKernel(3)) nPix = coaddExposure.getWidth() * coaddExposure.getHeight() print " Remapped image has %d good pixels (%0.0f %%)" % ( nGoodPix, 100 * nGoodPix / float(nPix)) print " Add remapped blurred exposure to coadd and save updated coadd exposure" coaddUtils.addToCoadd(coaddMaskedImage, depthMap, remappedBlurredExposure.getMaskedImage(), coaddMask) coaddExposure.writeFits(outName) depthMap.writeFits(depthOutName) coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), depthMap) coaddExposure.writeFits(outName)