Exemple #1
0
    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,))
Exemple #2
0
    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"))
Exemple #3
0
    def runBasicConvolveEdgeTest(self, kernel, kernelDescr):
        """Verify that basicConvolve does not write to edge pixels for this kind of kernel
        """
        fullBox = afwGeom.Box2I(
            afwGeom.Point2I(0, 0),
            ShiftedBBox.getDimensions(),
        )
        goodBox = kernel.shrinkBBox(fullBox)
        cnvMaskedImage = afwImage.MaskedImageF(FullMaskedImage, ShiftedBBox, afwImage.LOCAL, True)
        cnvMaskedImageCopy = afwImage.MaskedImageF(cnvMaskedImage, fullBox, afwImage.LOCAL, True)
        cnvMaskedImageCopyViewOfGoodRegion = afwImage.MaskedImageF(cnvMaskedImageCopy, goodBox, afwImage.LOCAL, False)

        # convolve with basicConvolve, which should leave the edge pixels alone
        convControl = afwMath.ConvolutionControl()
        mathDetail.basicConvolve(cnvMaskedImage, self.maskedImage, kernel, convControl)

        # reset the good region to the original convolved image;
        # this should reset the entire convolved image to its original self
        cnvMaskedImageGoodView = afwImage.MaskedImageF(cnvMaskedImage, goodBox, afwImage.LOCAL, False)
        cnvMaskedImageGoodView <<= cnvMaskedImageCopyViewOfGoodRegion

        # assert that these two are equal
        cnvImMaskVarArr = cnvMaskedImage.getArrays()
        desCnvImMaskVarArr = cnvMaskedImageCopy.getArrays()
        errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, desCnvImMaskVarArr,
            doVariance = True, rtol=0, atol=0)
        shortKernelDescr = kernelDescr.translate(NullTranslator, GarbageChars)
        if errStr:
            cnvMaskedImage.writeFits("actBasicConvolve%s" % (shortKernelDescr,))
            cnvMaskedImageCopy.writeFits("desBasicConvolve%s" % (shortKernelDescr,))
            self.fail("basicConvolve(MaskedImage, kernel=%s) wrote to edge pixels:\n%s" % \
                (kernelDescr, errStr))
Exemple #4
0
    def runBasicConvolveEdgeTest(self, kernel, kernelDescr):
        """Verify that basicConvolve does not write to edge pixels for this kind of kernel
        """
        fullBox = afwGeom.Box2I(
            afwGeom.Point2I(0, 0),
            ShiftedBBox.getDimensions(),
        )
        goodBox = kernel.shrinkBBox(fullBox)
        cnvMaskedImage = afwImage.MaskedImageF(FullMaskedImage, ShiftedBBox, afwImage.LOCAL, True)
        cnvMaskedImageCopy = afwImage.MaskedImageF(cnvMaskedImage, fullBox, afwImage.LOCAL, True)
        cnvMaskedImageCopyViewOfGoodRegion = afwImage.MaskedImageF(cnvMaskedImageCopy, goodBox, afwImage.LOCAL, False)

        # convolve with basicConvolve, which should leave the edge pixels alone
        convControl = afwMath.ConvolutionControl()
        mathDetail.basicConvolve(cnvMaskedImage, self.maskedImage, kernel, convControl)

        # reset the good region to the original convolved image;
        # this should reset the entire convolved image to its original self
        cnvMaskedImageGoodView = afwImage.MaskedImageF(cnvMaskedImage, goodBox, afwImage.LOCAL, False)
        cnvMaskedImageGoodView <<= cnvMaskedImageCopyViewOfGoodRegion

        # assert that these two are equal
        cnvImMaskVarArr = cnvMaskedImage.getArrays()
        desCnvImMaskVarArr = cnvMaskedImageCopy.getArrays()
        errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, desCnvImMaskVarArr,
            doVariance = True, rtol=0, atol=0)
        shortKernelDescr = kernelDescr.translate(NullTranslator, GarbageChars)
        if errStr:
            cnvMaskedImage.writeFits("actBasicConvolve%s" % (shortKernelDescr,))
            cnvMaskedImageCopy.writeFits("desBasicConvolve%s" % (shortKernelDescr,))
            self.fail("basicConvolve(MaskedImage, kernel=%s) wrote to edge pixels:\n%s" % \
                (kernelDescr, errStr))
Exemple #5
0
    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"))
Exemple #6
0
    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,))
Exemple #7
0
    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,
                ))
Exemple #8
0
 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 testAdditionAllGood(self):
        """Test the case where all pixels are valid
        """
        config = SnapCombineTask.ConfigClass()
        config.doRepair = False
        config.doDiffIm = False
        task = SnapCombineTask(config=config)

        snap0 = makeRandomExposure(25, 25, 10000, 5000, 0)
        snap1 = makeRandomExposure(25, 25, 10000, 5000, 0)
        resExp = task.run(snap0, snap1).exposure
        resMi = resExp.getMaskedImage()

        predMi = snap0.getMaskedImage().Factory(snap0.getMaskedImage(), True)
        predMi += snap1.getMaskedImage()
        errMsg = afwTestUtils.maskedImagesDiffer(resMi.getArrays(), predMi.getArrays())
        if errMsg:
            self.fail(errMsg)
    def testAddition(self):
        """Test addition with bad pixels
        """
        config = SnapCombineTask.ConfigClass()
        config.doRepair = False
        config.doDiffIm = False
        config.badMaskPlanes = ("BAD", "SAT", "NO_DATA", "CR")
        badPixelMask = afwImage.MaskU.getPlaneBitMask(config.badMaskPlanes)
        task = SnapCombineTask(config=config)

        snap0 = makeRandomExposure(25, 25, 10000, 5000, badPixelMask)
        snap1 = makeRandomExposure(25, 25, 10000, 5000, badPixelMask)
        resExp = task.run(snap0, snap1).exposure
        resMi = resExp.getMaskedImage()
        
        predExp = simpleAdd(snap0, snap1, badPixelMask)
        predMi = predExp.getMaskedImage()
        errMsg = afwTestUtils.maskedImagesDiffer(resMi.getArrays(), predMi.getArrays())
        if errMsg:
            self.fail(errMsg)
Exemple #11
0
    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))
Exemple #12
0
    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))
Exemple #13
0
    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"))
Exemple #14
0
    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))
Exemple #15
0
    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"))
Exemple #16
0
    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))
Exemple #17
0
    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, ))