def runScaledAddTest(self, coeff0, coeff1): """Run one test of scaledPlus Inputs: - coeff0: coefficient of image 0 - coeff1: coefficient of image 1 """ im0ArrSet = self.maskedImage0.getArrays() im1ArrSet = self.maskedImage1.getArrays() desMaskedImage = afwImage.MaskedImageF(self.maskedImage0.getDimensions()) desMaskedImage <<= self.maskedImage0 desMaskedImage *= coeff0 desMaskedImage.scaledPlus(coeff1, self.maskedImage1) desImArrSet = desMaskedImage.getArrays() actMaskedImage = afwImage.MaskedImageF(afwGeom.Extent2I(self.imWidth, self.imHeight)) afwMath.randomUniformImage(actMaskedImage.getImage(), self.random) afwMath.randomUniformImage(actMaskedImage.getVariance(), self.random) afwMath.scaledPlus(actMaskedImage, coeff0, self.maskedImage0, coeff1, self.maskedImage1) actImArrSet = actMaskedImage.getArrays() actImage = afwImage.ImageF(afwGeom.Extent2I(self.imWidth, self.imHeight)) afwMath.randomUniformImage(actImage, self.random) afwMath.scaledPlus(actImage, coeff0, self.maskedImage0.getImage(), coeff1, self.maskedImage1.getImage()) actImArr = actImage.getArray() errStr = imTestUtils.imagesDiffer(actImArr, desImArrSet[0]) if errStr: self.fail("scaledPlus failed in images; coeff0=%s, coeff1=%s:\n%s" % (coeff0, coeff1, errStr,)) errStr = imTestUtils.maskedImagesDiffer(actImArrSet, desImArrSet) if errStr: self.fail("scaledPlus failed on masked images; coeff0=%s, coeff1=%s:\n%s" % (coeff0, coeff1, errStr,))
def testUnityConvolution(self): """Verify that convolution with a centered delta function reproduces the original. """ # create a delta function kernel that has 1,1 in the center kFunc = afwMath.IntegerDeltaFunction2D(0.0, 0.0) kernel = afwMath.AnalyticKernel(3, 3, kFunc) doNormalize = False doCopyEdge = False afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, doNormalize, doCopyEdge) cnvImArr = self.cnvImage.getArray() afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, doNormalize, doCopyEdge) cnvImMaskVarArr = self.cnvMaskedImage.getArrays() refCnvImMaskVarArr = self.maskedImage.getArrays() skipMaskArr = numpy.isnan(cnvImMaskVarArr[0]) kernelDescr = "Centered DeltaFunctionKernel (testing unity convolution)" errStr = imTestUtils.imagesDiffer(cnvImArr, refCnvImMaskVarArr[0], skipMaskArr=skipMaskArr) if errStr: self.fail("convolve(Image, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, errStr)) errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, refCnvImMaskVarArr, skipMaskArr=skipMaskArr) if errStr: self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, errStr)) self.assert_(sameMaskPlaneDicts(self.cnvMaskedImage, self.maskedImage), "convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, "convolved mask dictionary does not match input"))
def testExactImages(self): """Confirm that kernel image at each location is correct """ desImage = afwImage.ImageD( afwGeom.Extent2I(self.kernel.getWidth(), self.kernel.getHeight())) for doNormalize in (False, True): region = mathDetail.KernelImagesForRegion(self.kernel, self.bbox, self.xy0, doNormalize) for location in ( region.BOTTOM_LEFT, region.BOTTOM_RIGHT, region.TOP_LEFT, region.TOP_RIGHT, ): pixelIndex = region.getPixelIndex(location) xPos = afwImage.indexToPosition(pixelIndex[0] + self.xy0[0]) yPos = afwImage.indexToPosition(pixelIndex[1] + self.xy0[1]) self.kernel.computeImage(desImage, doNormalize, xPos, yPos) desImArr = desImage.getArray().transpose().copy() actImage = region.getImage(location) actImArr = actImage.getArray().transpose().copy() errStr = imTestUtils.imagesDiffer(actImArr, desImArr) if errStr: self.fail("exact image(%s) incorrect:\n%s" % (LocNameDict[location], errStr))
def compareToSwarp(self, kernelName, 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 - 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 """ warper = afwMath.Warper(kernelName) originalExposure, swarpedImage, swarpedWcs = self.getSwarpedImage( kernelName=kernelName, useSubregion=useSubregion, useDeepCopy=useDeepCopy) maxBBox = afwGeom.Box2I( afwGeom.Point2I(swarpedImage.getX0(), swarpedImage.getY0()), afwGeom.Extent2I(swarpedImage.getWidth(), swarpedImage.getHeight())) # path for saved afw-warped image afwWarpedImagePath = "afwWarpedExposure1%s" % (kernelName,) # warning: this test assumes that the swarped image is smaller than it needs to be # to hold all of the warped pixels afwWarpedExposure = warper.warpExposure( destWcs = swarpedWcs, srcExposure = originalExposure, maxBBox = maxBBox, ) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("EDGE") if edgeBitMask == 0: self.fail("warped mask has no EDGE bit") afwWarpedImagArr = afwWarpedMaskedImage.getImage().getArray() afwWarpedMaskArr = afwWarpedMaskedImage.getMask().getArray() swarpedImageArr = swarpedImage.getArray() errStr = imageTestUtils.imagesDiffer(afwWarpedImagArr, swarpedImage.getArray(), skipMaskArr=afwWarpedMaskArr, rtol=rtol, atol=atol) if errStr: self.fail("afw and swarp %s-warped %s (ignoring bad pixels)" % (kernelName, errStr))
def runScaledAddTest(self, coeff0, coeff1): """Run one test of scaledPlus Inputs: - coeff0: coefficient of image 0 - coeff1: coefficient of image 1 """ im0ArrSet = self.maskedImage0.getArrays() im1ArrSet = self.maskedImage1.getArrays() desMaskedImage = afwImage.MaskedImageF( self.maskedImage0.getDimensions()) desMaskedImage <<= self.maskedImage0 desMaskedImage *= coeff0 desMaskedImage.scaledPlus(coeff1, self.maskedImage1) desImArrSet = desMaskedImage.getArrays() actMaskedImage = afwImage.MaskedImageF( afwGeom.Extent2I(self.imWidth, self.imHeight)) afwMath.randomUniformImage(actMaskedImage.getImage(), self.random) afwMath.randomUniformImage(actMaskedImage.getVariance(), self.random) afwMath.scaledPlus(actMaskedImage, coeff0, self.maskedImage0, coeff1, self.maskedImage1) actImArrSet = actMaskedImage.getArrays() actImage = afwImage.ImageF( afwGeom.Extent2I(self.imWidth, self.imHeight)) afwMath.randomUniformImage(actImage, self.random) afwMath.scaledPlus(actImage, coeff0, self.maskedImage0.getImage(), coeff1, self.maskedImage1.getImage()) actImArr = actImage.getArray() errStr = imTestUtils.imagesDiffer(actImArr, desImArrSet[0]) if errStr: self.fail( "scaledPlus failed in images; coeff0=%s, coeff1=%s:\n%s" % ( coeff0, coeff1, errStr, )) errStr = imTestUtils.maskedImagesDiffer(actImArrSet, desImArrSet) if errStr: self.fail( "scaledPlus failed on masked images; coeff0=%s, coeff1=%s:\n%s" % ( coeff0, coeff1, errStr, ))
def testUnsignedImages(self): """Unsigned images can give incorrect differences unless the test code is careful """ image0 = np.zeros([5, 5], dtype=np.uint8) image1 = np.zeros([5, 5], dtype=np.uint8) image0[0, 0] = 1 image1[0, 1] = 2 # arrays differ by a maximum of 2 errMsg1 = imagesDiffer(image0, image1) match = re.match(r"maxDiff *= *(\d+)", errMsg1, re.IGNORECASE) self.assertIsNotNone(match) self.assertEqual(match.group(1), "2") # arrays are equal to within 5 self.assertImagesNearlyEqual(image0, image1, atol=5)
def testUnsignedImages(self): """Unsigned images can give incorrect differences unless the test code is careful """ image0 = np.zeros([5, 5], dtype=np.uint8) image1 = np.zeros([5, 5], dtype=np.uint8) image0[0, 0] = 1 image1[0, 1] = 2 # arrays differ by a maximum of 2 errMsg1 = imagesDiffer(image0, image1) match = re.match(r"maxDiff *= *(\d+)", errMsg1, re.IGNORECASE) self.assertIsNotNone(match) self.assertEqual(match.group(1), "2") # arrays are equal to within 5 self.assertImagesAlmostEqual(image0, image1, atol=5)
def testNullWarpImage(self, interpLength=10): """Test that warpImage maps an image onto itself. """ originalExposure = afwImage.ExposureF(originalExposurePath) afwWarpedExposure = afwImage.ExposureF(originalExposurePath) originalImage = originalExposure.getMaskedImage().getImage() afwWarpedImage = afwWarpedExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwWarpedWcs = afwWarpedExposure.getWcs() warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpImage(afwWarpedImage, afwWarpedWcs, originalImage, originalWcs, warpingControl) if SAVE_FITS_FILES: afwWarpedImage.writeFits("afwWarpedImageNull.fits") afwWarpedImageArr = afwWarpedImage.getArray() edgeMaskArr = numpy.isnan(afwWarpedImageArr) originalImageArr = originalImage.getArray() # relax specs a bit because of minor noise introduced by bad pixels errStr = imageTestUtils.imagesDiffer(originalImageArr, originalImageArr, skipMaskArr=edgeMaskArr) if errStr: self.fail("afw null-warped Image: %s" % (errStr,))
def testExactImages(self): """Confirm that kernel image at each location is correct """ desImage = afwImage.ImageD(afwGeom.Extent2I(self.kernel.getWidth(), self.kernel.getHeight())) for doNormalize in (False, True): region = mathDetail.KernelImagesForRegion(self.kernel, self.bbox, self.xy0, doNormalize) for location in ( region.BOTTOM_LEFT, region.BOTTOM_RIGHT, region.TOP_LEFT, region.TOP_RIGHT, ): pixelIndex = region.getPixelIndex(location) xPos = afwImage.indexToPosition(pixelIndex[0] + self.xy0[0]) yPos = afwImage.indexToPosition(pixelIndex[1] + self.xy0[1]) self.kernel.computeImage(desImage, doNormalize, xPos, yPos) desImArr = desImage.getArray().transpose().copy() actImage = region.getImage(location) actImArr = actImage.getArray().transpose().copy() errStr = imTestUtils.imagesDiffer(actImArr, desImArr) if errStr: self.fail("exact image(%s) incorrect:\n%s" % (LocNameDict[location], errStr))
def testNullWarpImage(self, interpLength=10): """Test that warpImage maps an image onto itself. """ originalExposure = afwImage.ExposureF(originalExposurePath) afwWarpedExposure = afwImage.ExposureF(originalExposurePath) originalImage = originalExposure.getMaskedImage().getImage() afwWarpedImage = afwWarpedExposure.getMaskedImage().getImage() originalWcs = originalExposure.getWcs() afwWarpedWcs = afwWarpedExposure.getWcs() warpingControl = afwMath.WarpingControl("lanczos4", "", 0, interpLength) afwMath.warpImage(afwWarpedImage, afwWarpedWcs, originalImage, originalWcs, warpingControl) if SAVE_FITS_FILES: afwWarpedImage.writeFits("afwWarpedImageNull.fits") afwWarpedImageArr = afwWarpedImage.getArray() edgeMaskArr = numpy.isnan(afwWarpedImageArr) originalImageArr = originalImage.getArray() # relax specs a bit because of minor noise introduced by bad pixels errStr = imageTestUtils.imagesDiffer(originalImageArr, originalImageArr, skipMaskArr=edgeMaskArr) if errStr: self.fail("afw null-warped Image: %s" % (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.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 runBasicTest(self, kernel, convControl, refKernel=None, kernelDescr="", rtol=1.0e-05, atol=1e-08): """Assert that afwMath::convolve gives the same result as reference convolution for a given kernel. Inputs: - kernel: convolution kernel - convControl: convolution control parameters (afwMath.ConvolutionControl) - refKernel: kernel to use for refConvolve (if None then kernel is used) - kernelDescr: description of kernel - rtol: relative tolerance (see below) - atol: absolute tolerance (see below) rtol and atol are positive, typically very small numbers. The relative difference (rtol * abs(b)) and the absolute difference "atol" are added together to compare against the absolute difference between "a" and "b". """ if refKernel == None: refKernel = kernel # strip garbage characters (whitespace and punctuation) to make a short description for saving files shortKernelDescr = kernelDescr.translate(NullTranslator, GarbageChars) doNormalize = convControl.getDoNormalize() doCopyEdge = convControl.getDoCopyEdge() maxInterpDist = convControl.getMaxInterpolationDistance() imMaskVar = self.maskedImage.getArrays() xy0 = self.maskedImage.getXY0() refCnvImMaskVarArr = refConvolve(imMaskVar, xy0, refKernel, doNormalize, doCopyEdge) afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, convControl) self.assertEqual(self.cnvImage.getXY0(), self.xy0) cnvImArr = self.cnvImage.getArray() afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, convControl) cnvImMaskVarArr = self.cnvMaskedImage.getArrays() if display and False: refMaskedImage = afwImage.makeMaskedImageFromArrays(*refCnvImMaskVarArr) ds9.mtv(displayUtils.Mosaic().makeMosaic([ self.maskedImage, refMaskedImage, self.cnvMaskedImage]), frame=0) if False: for (x, y) in ((0, 0), (1, 0), (0, 1), (50, 50)): print "Mask(%d,%d) 0x%x 0x%x" % (x, y, refMaskedImage.getMask().get(x, y), self.cnvMaskedImage.getMask().get(x, y)) errStr = imTestUtils.imagesDiffer(cnvImArr, refCnvImMaskVarArr[0], rtol=rtol, atol=atol) if errStr: self.cnvImage.writeFits("act%s.fits" % (shortKernelDescr,)) refMaskedImage = afwImage.makeMaskedImageFromArrays(*refCnvImMaskVarArr) refMaskedImage.getImage().writeFits("des%s.fits" % (shortKernelDescr,)) self.fail("convolve(Image, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, errStr)) errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, refCnvImMaskVarArr, doVariance = True, rtol=rtol, atol=atol) if errStr: self.cnvMaskedImage.writeFits("act%s" % (shortKernelDescr,)) refMaskedImage = afwImage.makeMaskedImageFromArrays(*refCnvImMaskVarArr) refMaskedImage.writeFits("des%s" % (shortKernelDescr,)) self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, errStr)) if not sameMaskPlaneDicts(self.cnvMaskedImage, self.maskedImage): self.cnvMaskedImage.writeFits("act%s" % (shortKernelDescr,)) refMaskedImage = afwImage.makeMaskedImageFromArrays(*refCnvImMaskVarArr) refMaskedImage.writeFits("des%s" % (shortKernelDescr,)) self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, "convolved mask dictionary does not match input"))
def runBasicTest(self, kernel, convControl, refKernel=None, kernelDescr="", rtol=1.0e-05, atol=1e-08): """Assert that afwMath::convolve gives the same result as reference convolution for a given kernel. Inputs: - kernel: convolution kernel - convControl: convolution control parameters (afwMath.ConvolutionControl) - refKernel: kernel to use for refConvolve (if None then kernel is used) - kernelDescr: description of kernel - rtol: relative tolerance (see below) - atol: absolute tolerance (see below) rtol and atol are positive, typically very small numbers. The relative difference (rtol * abs(b)) and the absolute difference "atol" are added together to compare against the absolute difference between "a" and "b". """ if refKernel == None: refKernel = kernel # strip garbage characters (whitespace and punctuation) to make a short description for saving files shortKernelDescr = kernelDescr.translate(NullTranslator, GarbageChars) doNormalize = convControl.getDoNormalize() doCopyEdge = convControl.getDoCopyEdge() maxInterpDist = convControl.getMaxInterpolationDistance() imMaskVar = self.maskedImage.getArrays() xy0 = self.maskedImage.getXY0() refCnvImMaskVarArr = refConvolve(imMaskVar, xy0, refKernel, doNormalize, doCopyEdge) afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, convControl) self.assertEqual(self.cnvImage.getXY0(), self.xy0) cnvImArr = self.cnvImage.getArray() afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, convControl) cnvImMaskVarArr = self.cnvMaskedImage.getArrays() if display and False: refMaskedImage = afwImage.makeMaskedImageFromArrays( *refCnvImMaskVarArr) ds9.mtv(displayUtils.Mosaic().makeMosaic( [self.maskedImage, refMaskedImage, self.cnvMaskedImage]), frame=0) if False: for (x, y) in ((0, 0), (1, 0), (0, 1), (50, 50)): print "Mask(%d,%d) 0x%x 0x%x" % ( x, y, refMaskedImage.getMask().get( x, y), self.cnvMaskedImage.getMask().get(x, y)) errStr = imTestUtils.imagesDiffer(cnvImArr, refCnvImMaskVarArr[0], rtol=rtol, atol=atol) if errStr: self.cnvImage.writeFits("act%s.fits" % (shortKernelDescr, )) refMaskedImage = afwImage.makeMaskedImageFromArrays( *refCnvImMaskVarArr) refMaskedImage.getImage().writeFits("des%s.fits" % (shortKernelDescr, )) self.fail("convolve(Image, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, errStr)) errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, refCnvImMaskVarArr, doVariance=True, rtol=rtol, atol=atol) if errStr: self.cnvMaskedImage.writeFits("act%s" % (shortKernelDescr, )) refMaskedImage = afwImage.makeMaskedImageFromArrays( *refCnvImMaskVarArr) refMaskedImage.writeFits("des%s" % (shortKernelDescr, )) self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, errStr)) if not sameMaskPlaneDicts(self.cnvMaskedImage, self.maskedImage): self.cnvMaskedImage.writeFits("act%s" % (shortKernelDescr, )) refMaskedImage = afwImage.makeMaskedImageFromArrays( *refCnvImMaskVarArr) refMaskedImage.writeFits("des%s" % (shortKernelDescr, )) self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, "convolved mask dictionary does not match input"))
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, 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 - 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 """ warper = afwMath.Warper(kernelName) originalExposure, swarpedImage, swarpedWcs = self.getSwarpedImage( kernelName=kernelName, useSubregion=useSubregion, useDeepCopy=useDeepCopy) maxBBox = afwGeom.Box2I( afwGeom.Point2I(swarpedImage.getX0(), swarpedImage.getY0()), afwGeom.Extent2I(swarpedImage.getWidth(), swarpedImage.getHeight())) # path for saved afw-warped image afwWarpedImagePath = "afwWarpedExposure1%s" % (kernelName, ) # warning: this test assumes that the swarped image is smaller than it needs to be # to hold all of the warped pixels afwWarpedExposure = warper.warpExposure( destWcs=swarpedWcs, srcExposure=originalExposure, maxBBox=maxBBox, ) afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage() afwWarpedMask = afwWarpedMaskedImage.getMask() edgeBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA") if edgeBitMask == 0: self.fail("warped mask has no NO_DATA bit") afwWarpedImagArr = afwWarpedMaskedImage.getImage().getArray() afwWarpedMaskArr = afwWarpedMaskedImage.getMask().getArray() swarpedImageArr = swarpedImage.getArray() errStr = imageTestUtils.imagesDiffer(afwWarpedImagArr, swarpedImage.getArray(), skipMaskArr=afwWarpedMaskArr, rtol=rtol, atol=atol) if errStr: self.fail("afw and swarp %s-warped %s (ignoring bad pixels)" % (kernelName, errStr))