Beispiel #1
0
    def testWarpingControl(self):
        """Test the basic mechanics of WarpingControl
        """
        for interpLength in (0, 1, 52):
            wc = afwMath.WarpingControl("lanczos3", "", 0, interpLength)
            self.assertFalse(wc.hasMaskWarpingKernel())
            self.assertEqual(wc.getInterpLength(), interpLength)
            for newInterpLength in (3, 7, 9):
                wc.setInterpLength(newInterpLength)
                self.assertEqual(wc.getInterpLength(), newInterpLength)

        for cacheSize in (0, 100):
            wc = afwMath.WarpingControl("lanczos3", "bilinear", cacheSize)
            self.assertTrue(wc.hasMaskWarpingKernel())
            self.assertEqual(wc.getCacheSize(), cacheSize)
            self.assertEqual(wc.getWarpingKernel().getCacheSize(), cacheSize)
            self.assertEqual(wc.getMaskWarpingKernel().getCacheSize(),
                             cacheSize)
            for newCacheSize in (1, 50):
                wc.setCacheSize(newCacheSize)
                self.assertEqual(wc.getCacheSize(), newCacheSize)
                self.assertEqual(wc.getWarpingKernel().getCacheSize(),
                                 newCacheSize)
                self.assertEqual(wc.getMaskWarpingKernel().getCacheSize(),
                                 newCacheSize)
    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(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 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
Beispiel #5
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 = 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 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)
Beispiel #7
0
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)
Beispiel #8
0
    def testWarpingControl(self):
        """Test the basic mechanics of WarpingControl
        """
        for interpLength in (0, 1, 52):
            wc = afwMath.WarpingControl("lanczos3", "", 0, interpLength)
            self.assertFalse(wc.hasMaskWarpingKernel())
            self.assertEqual(wc.getInterpLength(), interpLength)
            for newInterpLength in (3, 7, 9):
                wc.setInterpLength(newInterpLength)
                self.assertEqual(wc.getInterpLength(), newInterpLength)

        for cacheSize in (0, 100):
            wc = afwMath.WarpingControl("lanczos3", "bilinear", cacheSize)
            self.assertTrue(wc.hasMaskWarpingKernel())
            self.assertEqual(wc.getCacheSize(), cacheSize)
            self.assertEqual(wc.getWarpingKernel().getCacheSize(), cacheSize)
            self.assertEqual(wc.getMaskWarpingKernel().getCacheSize(),
                             cacheSize)
            for newCacheSize in (1, 50):
                wc.setCacheSize(newCacheSize)
                self.assertEqual(wc.getCacheSize(), newCacheSize)
                self.assertEqual(wc.getWarpingKernel().getCacheSize(),
                                 newCacheSize)
                self.assertEqual(wc.getMaskWarpingKernel().getCacheSize(),
                                 newCacheSize)

        wc = afwMath.WarpingControl("lanczos4", "nearest", 64, 7, 42)
        self.assertTrue(wc.isPersistable())
        with lsst.utils.tests.getTempFilePath(".fits",
                                              expectOutput=True) as tempFile:
            wc.writeFits(tempFile)
            wc2 = afwMath.WarpingControl.readFits(tempFile)
        self.assertEqual(wc.getCacheSize(), wc2.getCacheSize())
        self.assertEqual(wc.getInterpLength(), wc2.getInterpLength())
        self.assertEqual(wc.getWarpingKernel().getBBox(),
                         wc2.getWarpingKernel().getBBox())
        self.assertEqual(wc.getWarpingKernel().getKernelParameters(),
                         wc2.getWarpingKernel().getKernelParameters())
        self.assertEqual(wc.hasMaskWarpingKernel(), wc2.hasMaskWarpingKernel())
        self.assertEqual(wc.getMaskWarpingKernel().getBBox(),
                         wc2.getMaskWarpingKernel().getBBox())
        self.assertEqual(wc.getMaskWarpingKernel().getKernelParameters(),
                         wc2.getMaskWarpingKernel().getKernelParameters())
        self.assertEqual(wc.getGrowFullMask(), wc2.getGrowFullMask())
Beispiel #9
0
    def testWarpingControlError(self):
        """Test error handling of WarpingControl
        """
        # error: mask kernel smaller than main kernel
        for kernelName, maskKernelName in (
            ("bilinear", "lanczos3"),
            ("bilinear", "lanczos4"),
            ("lanczos3", "lanczos4"),
        ):
            with self.assertRaises(pexExcept.InvalidParameterError):
                afwMath.WarpingControl(kernelName, maskKernelName)

        # error: new mask kernel larger than main kernel
        warpingControl = afwMath.WarpingControl("bilinear")
        for maskKernelName in ("lanczos3", "lanczos4"):
            with self.assertRaises(pexExcept.InvalidParameterError):
                warpingControl.setMaskWarpingKernelName(maskKernelName)

        # error: new kernel smaller than mask kernel
        warpingControl = afwMath.WarpingControl("lanczos4", "lanczos4")
        for kernelName in ("bilinear", "lanczos3"):
            with self.assertRaises(pexExcept.InvalidParameterError):
                warpingControl.setWarpingKernelName(kernelName)

        # OK: main kernel at least as big as mask kernel
        for kernelName, maskKernelName in (
            ("bilinear", "bilinear"),
            ("lanczos3", "lanczos3"),
            ("lanczos3", "bilinear"),
            ("lanczos4", "lanczos3"),
        ):
            # this should not raise any exception
            afwMath.WarpingControl(kernelName, maskKernelName)

        # invalid kernel names
        for kernelName, maskKernelName in (
            ("badname", ""),
            ("lanczos", ""),  # no digit after lanczos
            ("lanczos3", "badname"),
            ("lanczos3", "lanczos"),
        ):
            with self.assertRaises(pexExcept.InvalidParameterError):
                afwMath.WarpingControl(kernelName, maskKernelName)
Beispiel #10
0
    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)
Beispiel #11
0
    def testNonIcrs(self):
        """Test that warping to a non-ICRS-like coordinate system produces different results

        It would be better to also test that the results are as expected,
        but I have not been able to get swarp to perform this operation,
        so have not found an independent means of generating the expected results.
        """
        kernelName = "lanczos3"
        rtol = 4e-5
        atol = 1e-2
        warpingControl = afwMath.WarpingControl(kernelName, )

        originalExposure = afwImage.ExposureF(originalExposurePath)
        originalImage = originalExposure.getMaskedImage().getImage()
        originalWcs = originalExposure.getWcs()

        swarpedImageName = "medswarp1%s.fits" % (kernelName, )
        swarpedImagePath = os.path.join(dataDir, swarpedImageName)
        swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath)
        swarpedImage = swarpedDecoratedImage.getImage()

        for changeEquinox in (False, True):
            swarpedMetadata = swarpedDecoratedImage.getMetadata()
            if changeEquinox:
                swarpedMetadata.set("RADECSYS", "FK5")
                swarpedMetadata.set("EQUINOX",
                                    swarpedMetadata.get("EQUINOX") + 1)
            warpedWcs = afwImage.makeWcs(swarpedMetadata)

            afwWarpedImage = afwImage.ImageF(swarpedImage.getDimensions())
            originalImage = originalExposure.getMaskedImage().getImage()
            originalWcs = originalExposure.getWcs()
            numGoodPix = afwMath.warpImage(afwWarpedImage, warpedWcs,
                                           originalImage, originalWcs,
                                           warpingControl)
            self.assertGreater(numGoodPix, 50)

            afwWarpedImageArr = afwWarpedImage.getArray()
            noDataMaskArr = np.isnan(afwWarpedImageArr)
            if changeEquinox:
                with self.assertRaises(AssertionError):
                    self.assertImagesAlmostEqual(afwWarpedImage,
                                                 swarpedImage,
                                                 skipMask=noDataMaskArr,
                                                 rtol=rtol,
                                                 atol=atol)
            else:
                self.assertImagesAlmostEqual(afwWarpedImage,
                                             swarpedImage,
                                             skipMask=noDataMaskArr,
                                             rtol=rtol,
                                             atol=atol)
Beispiel #12
0
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)
Beispiel #13
0
    def testWarpingControlError(self):
        """Test error handling of WarpingControl
        """
        # error: mask kernel smaller than main kernel
        for kernelName, maskKernelName in (
            ("bilinear", "lanczos3"),
            ("bilinear", "lanczos4"),
            ("lanczos3", "lanczos4"),
        ):
            self.assertRaises(pexExcept.LsstCppException,
                              afwMath.WarpingControl, kernelName,
                              maskKernelName)

        # error: new mask kernel larger than main kernel
        warpingControl = afwMath.WarpingControl("bilinear")
        for maskKernelName in ("lanczos3", "lanczos4"):
            self.assertRaises(pexExcept.LsstCppException,
                              warpingControl.setMaskWarpingKernelName,
                              maskKernelName)

        # error: new kernel smaller than mask kernel
        warpingControl = afwMath.WarpingControl("lanczos4", "lanczos4")
        for kernelName in ("bilinear", "lanczos3"):
            self.assertRaises(pexExcept.LsstCppException,
                              warpingControl.setWarpingKernelName, kernelName)

        # error: GPU only works with Lanczos kernels
        self.assertRaises(pexExcept.LsstCppException, afwMath.WarpingControl,
                          "bilinear", "", 0, 0, afwGpu.USE_GPU)
        warpingControl = afwMath.WarpingControl("bilinear")
        self.assertRaises(pexExcept.LsstCppException,
                          warpingControl.setDevicePreference, afwGpu.USE_GPU)

        # OK: GPU works with Lanczos kernels
        for kernelName in ("lanczos3", "lanczos4"):
            afwMath.WarpingControl(kernelName, "", 0, 0, afwGpu.USE_GPU)
            warpingControl = afwMath.WarpingControl(kernelName)
            warpingControl.setDevicePreference(afwGpu.USE_GPU)

        # OK: main kernel at least as big as mask kernel
        for kernelName, maskKernelName in (
            ("bilinear", "bilinear"),
            ("lanczos3", "lanczos3"),
            ("lanczos3", "bilinear"),
            ("lanczos4", "lanczos3"),
        ):
            # this should not raise any exception
            afwMath.WarpingControl(kernelName, maskKernelName)

        # invalid kernel names
        for kernelName, maskKernelName in (
            ("badname", ""),
            ("lanczos", ""),  # no digit after lanczos
            ("lanczos3", "badname"),
            ("lanczos3", "lanczos"),
        ):
            self.assertRaises(pexExcept.LsstCppException,
                              afwMath.WarpingControl, kernelName,
                              maskKernelName)
Beispiel #14
0
    def toCcdBackground(self, detector, bbox):
        """Produce a background model for a CCD

        The superpixel background model is warped back to the
        CCD frame, for application to the individual CCD.

        Parameters
        ----------
        detector : `lsst.afw.cameraGeom.Detector`
            CCD for which to produce background model.
        bbox : `lsst.geom.Box2I`
            Bounding box of CCD exposure.

        Returns
        -------
        bg : `lsst.afw.math.BackgroundList`
            Background model for CCD.
        """
        transform = detector.getTransformMap().getTransform(
            detector.makeCameraSys(afwCameraGeom.PIXELS),
            detector.makeCameraSys(afwCameraGeom.FOCAL_PLANE))
        binTransform = (
            geom.AffineTransform.makeScaling(self.config.binning) *
            geom.AffineTransform.makeTranslation(geom.Extent2D(0.5, 0.5)))

        # Binned image on CCD --> unbinned image on CCD --> focal plane --> binned focal plane
        toSample = afwGeom.makeTransform(binTransform).then(transform).then(
            self.transform)

        focalPlane = self.getStatsImage()
        fpNorm = afwImage.ImageF(focalPlane.getBBox())
        fpNorm.set(1.0)

        image = afwImage.ImageF(bbox.getDimensions() // self.config.binning)
        norm = afwImage.ImageF(image.getBBox())
        ctrl = afwMath.WarpingControl("bilinear")
        afwMath.warpImage(image, focalPlane, toSample.inverted(), ctrl)
        afwMath.warpImage(norm, fpNorm, toSample.inverted(), ctrl)
        image /= norm

        mask = afwImage.Mask(image.getBBox())
        isBad = numpy.isnan(image.getArray())
        mask.getArray()[isBad] = mask.getPlaneBitMask("BAD")
        image.getArray()[isBad] = image.getArray()[~isBad].mean()

        return afwMath.BackgroundList(
            (afwMath.BackgroundMI(bbox, afwImage.makeMaskedImage(image, mask)),
             afwMath.stringToInterpStyle(self.config.interpolation),
             afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"),
             afwMath.ApproximateControl.UNKNOWN, 0, 0, False))
    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)
Beispiel #16
0
    def testTransformBasedWarp(self):
        """Test warping using Transform<Point2Endpoint, Point2Endpoint>
        """
        for interpLength in (0, 1, 2, 4):
            kernelName = "lanczos3"
            rtol = 4e-5
            atol = 1e-2
            warpingControl = afwMath.WarpingControl(
                warpingKernelName=kernelName,
                interpLength=interpLength,
            )

            originalExposure = afwImage.ExposureF(originalExposurePath)
            originalMetadata = afwImage.DecoratedImageF(
                originalExposurePath).getMetadata()
            originalSkyWcs = afwGeom.SkyWcs(originalMetadata)

            swarpedImageName = "medswarp1%s.fits" % (kernelName, )
            swarpedImagePath = os.path.join(dataDir, swarpedImageName)
            swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath)
            swarpedImage = swarpedDecoratedImage.getImage()

            swarpedMetadata = swarpedDecoratedImage.getMetadata()
            warpedSkyWcs = afwGeom.SkyWcs(swarpedMetadata)

            # warped image is destination, original image is source
            # and WCS computes pixels to sky in the forward direction, so...
            destToSrc = warpedSkyWcs.then(originalSkyWcs.getInverse())

            afwWarpedMaskedImage = afwImage.MaskedImageF(
                swarpedImage.getDimensions())
            originalMaskedImage = originalExposure.getMaskedImage()

            numGoodPix = afwMath.warpImage(afwWarpedMaskedImage,
                                           originalMaskedImage, destToSrc,
                                           warpingControl)
            self.assertGreater(numGoodPix, 50)

            afwWarpedImage = afwWarpedMaskedImage.getImage()
            afwWarpedImageArr = afwWarpedImage.getArray()
            noDataMaskArr = np.isnan(afwWarpedImageArr)
            self.assertImagesAlmostEqual(afwWarpedImage,
                                         swarpedImage,
                                         skipMask=noDataMaskArr,
                                         rtol=rtol,
                                         atol=atol)
Beispiel #17
0
    def testTransformBasedWarp(self):
        """Test warping using TransformPoint2ToPoint2
        """
        for interpLength in (0, 1, 2, 4):
            kernelName = "lanczos3"
            rtol = 4e-5
            atol = 1e-2
            warpingControl = afwMath.WarpingControl(
                warpingKernelName=kernelName,
                interpLength=interpLength,
            )

            originalExposure = afwImage.ExposureF(originalExposurePath)
            originalMetadata = afwImage.DecoratedImageF(
                originalExposurePath).getMetadata()
            originalSkyWcs = afwGeom.makeSkyWcs(originalMetadata)

            swarpedImageName = f"medswarp1{kernelName}.fits"
            swarpedImagePath = os.path.join(dataDir, swarpedImageName)
            swarpedDecoratedImage = afwImage.DecoratedImageF(swarpedImagePath)
            swarpedImage = swarpedDecoratedImage.getImage()

            swarpedMetadata = swarpedDecoratedImage.getMetadata()
            warpedSkyWcs = afwGeom.makeSkyWcs(swarpedMetadata)

            # original image is source, warped image is destination
            srcToDest = afwGeom.makeWcsPairTransform(originalSkyWcs,
                                                     warpedSkyWcs)

            afwWarpedMaskedImage = afwImage.MaskedImageF(
                swarpedImage.getDimensions())
            originalMaskedImage = originalExposure.getMaskedImage()

            numGoodPix = afwMath.warpImage(afwWarpedMaskedImage,
                                           originalMaskedImage, srcToDest,
                                           warpingControl)
            self.assertGreater(numGoodPix, 50)

            afwWarpedImage = afwWarpedMaskedImage.getImage()
            afwWarpedImageArr = afwWarpedImage.getArray()
            noDataMaskArr = np.isnan(afwWarpedImageArr)
            self.assertImagesAlmostEqual(afwWarpedImage,
                                         swarpedImage,
                                         skipMask=noDataMaskArr,
                                         rtol=rtol,
                                         atol=atol)
    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 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()
     noDataMaskArr = np.isnan(afwWarpedImageArr)
     # relax specs a bit because of minor noise introduced by bad pixels
     msg = "afw null-warped Image"
     self.assertImagesAlmostEqual(originalImage, afwWarpedImage, skipMask=noDataMaskArr,
                                  atol=1e-5, msg=msg)
    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)
Beispiel #21
0
 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
Beispiel #22
0
 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, ))
Beispiel #23
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 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
Beispiel #24
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))
Beispiel #25
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))
Beispiel #26
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, ))
Beispiel #27
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 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 warpStamps(self, stamps, pixCenters):
        """Warps and shifts all given stamps so they are sampled on the same
        pixel grid and centered on the central pixel. This includes rotating
        the stamp depending on detector orientation.

        Parameters
        ----------
        stamps : `collections.abc.Sequence`
                     [`afwImage.exposure.exposure.ExposureF`]
            Image cutouts centered on a single object.
        pixCenters : `collections.abc.Sequence` [`geom.Point2D`]
            Positions of each object's center (as obtained from the refCat),
            in pixels.

        Returns
        -------
        warpedStars : `list` [`afwImage.maskedImage.maskedImage.MaskedImage`]
        """
        # warping control; only contains shiftingALg provided in config
        warpCont = afwMath.WarpingControl(self.config.warpingKernelName)
        # Compare model to star stamp sizes
        bufferPix = (self.modelStampSize[0] - self.config.stampSize[0],
                     self.modelStampSize[1] - self.config.stampSize[1])
        # Initialize detector instance (note all stars were extracted from an
        # exposure from the same detector)
        det = stamps[0].getDetector()
        # Define correction for optical distortions
        if self.config.doApplyTransform:
            pixToTan = det.getTransform(cg.PIXELS, cg.TAN_PIXELS)
        else:
            pixToTan = tFactory.makeIdentityTransform()
        # Array of all possible rotations for detector orientation:
        possibleRots = np.array([k*np.pi/2 for k in range(4)])
        # determine how many, if any, rotations are required
        yaw = det.getOrientation().getYaw()
        nb90Rots = np.argmin(np.abs(possibleRots - float(yaw)))

        # apply transformation to each star
        warpedStars = []
        for star, cent in zip(stamps, pixCenters):
            # (re)create empty destination image
            destImage = afwImage.MaskedImageF(*self.modelStampSize)
            bottomLeft = geom.Point2D(star.image.getXY0())
            newBottomLeft = pixToTan.applyForward(bottomLeft)
            newBottomLeft.setX(newBottomLeft.getX() - bufferPix[0]/2)
            newBottomLeft.setY(newBottomLeft.getY() - bufferPix[1]/2)
            # Convert to int
            newBottomLeft = geom.Point2I(newBottomLeft)
            # Set origin
            destImage.setXY0(newBottomLeft)

            # Define linear shifting to recenter stamps
            newCenter = pixToTan.applyForward(cent)  # center of warped star
            shift = self.modelCenter[0] + newBottomLeft[0] - newCenter[0],\
                self.modelCenter[1] + newBottomLeft[1] - newCenter[1]
            affineShift = geom.AffineTransform(shift)
            shiftTransform = tFactory.makeTransform(affineShift)

            # Define full transform (warp and shift)
            starWarper = pixToTan.then(shiftTransform)

            # Apply it
            goodPix = afwMath.warpImage(destImage, star.getMaskedImage(),
                                        starWarper, warpCont)
            if not goodPix:
                self.log.debug("Warping of a star failed: no good pixel in output")

            # Arbitrarily set origin of shifted star to 0
            destImage.setXY0(0, 0)

            # Apply rotation if apropriate
            if nb90Rots:
                destImage = afwMath.rotateImageBy90(destImage, nb90Rots)
            warpedStars.append(destImage.clone())
        return warpedStars
def run():
    if len(sys.argv) < 2:
        srcExposure = afwImage.ExposureF(InputExposurePath)
        if WarpSubregion:
            bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                                 afwGeom.Extent2I(2000, 2000))
            srcExposure = afwImage.ExposureF(srcExposure, bbox, afwImage.LOCAL,
                                             False)
    else:
        srcExposure = afwImage.ExposureF(sys.argv[1])
    srcWcs = srcExposure.getWcs()
    srcDim = srcExposure.getDimensions()
    srcCtrInd = [int(d / 2) for d in srcDim]

    # make the destination exposure small enough that even after rotation and offset
    # (by reasonable amounts) there are no edge pixels
    destDim = afwGeom.Extent2I(*[int(sd * 0.5) for sd in srcDim])
    destExposure = afwImage.ExposureF(destDim)
    destCtrInd = [int(d / 2) for d in destDim]

    maskKernelName = ""
    cacheSize = 0

    print("Warping", InputExposurePath)
    print("Source (sub)image size:", srcDim)
    print("Destination image size:", destDim)
    print()

    print(
        "test# interp  scaleFac     skyOffset     rotAng   kernel   goodPix time/iter"
    )
    print(
        '       (pix)              (RA, Dec ")    (deg)                      (sec)'
    )
    testNum = 1
    for interpLength in (0, 1, 5, 10):
        for scaleFac in (1.2, ):  # (1.0, 1.5):
            # ((0.0, 0.0), (10.5, -5.5)):
            for skyOffsetArcSec in ((0.0, 0.0), ):
                skyOffset = [so / 3600.0 for so in skyOffsetArcSec]
                for rotAng, kernelName in (
                    (0.0, "bilinear"),
                    (0.0, "lanczos2"),
                    (0.0, "lanczos3"),
                    (45.0, "lanczos3"),
                ):
                    warpingControl = afwMath.WarpingControl(
                        kernelName,
                        maskKernelName,
                        cacheSize,
                        interpLength,
                    )
                    destWcs = makeWcs(
                        projName="TAN",
                        destCtrInd=destCtrInd,
                        skyOffset=skyOffset,
                        rotAng=rotAng,
                        scaleFac=scaleFac,
                        srcWcs=srcWcs,
                        srcCtrInd=srcCtrInd,
                    )
                    destExposure.setWcs(destWcs)
                    dTime, nIter, goodPix = timeWarp(destExposure, srcExposure,
                                                     warpingControl)
                    print(
                        "%4d  %5d  %8.1f  %6.1f, %6.1f  %7.1f %10s %8d %6.2f" %
                        (testNum, interpLength, scaleFac, skyOffsetArcSec[0],
                         skyOffsetArcSec[1], rotAng, kernelName, goodPix,
                         dTime / float(nIter)))

                    if SaveImages:
                        destExposure.writeFits("warpedExposure%03d.fits" %
                                               (testNum, ))
                    testNum += 1
Beispiel #30
0
def run():
    if len(sys.argv) < 2:
        srcExposure = afwImage.ExposureF(InputExposurePath)
        if WarpSubregion:
            bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                                 afwGeom.Extent2I(2000, 2000))
            srcExposure = afwImage.ExposureF(srcExposure, bbox, afwImage.LOCAL,
                                             False)
    else:
        srcExposure = afwImage.ExposureF(sys.argv[1])
    srcMaskedImage = srcExposure.getMaskedImage()
    srcMetadata = afwImage.DecoratedImageF(InputExposurePath).getMetadata()
    srcWcs = afwGeom.SkyWcs(srcMetadata)
    srcDim = srcExposure.getDimensions()
    srcCtrPos = afwGeom.Box2D(srcMaskedImage.getBBox()).getCenter()
    srcCtrSky = srcWcs.applyForward(srcCtrPos)
    srcScale = srcWcs.getPixelScale()

    # make the destination exposure small enough that even after rotation and offset
    # (by reasonable amounts) there are no edge pixels
    destDim = afwGeom.Extent2I(*[int(sd * 0.5) for sd in srcDim])
    destMaskedImage = afwImage.MaskedImageF(destDim)
    destCrPix = afwGeom.Box2D(destMaskedImage.getBBox()).getCenter()

    maskKernelName = ""
    cacheSize = 0

    print("Warping", InputExposurePath)
    print("Source (sub)image size:", srcDim)
    print("Destination image size:", destDim)
    print()

    print(
        "test# interp  scaleFac    destSkyOff    rotAng   kernel   goodPix time/iter"
    )
    print(
        '       (pix)              (bear°, len")    (deg)                      (sec)'
    )
    testNum = 1
    for interpLength in (0, 1, 5, 10):
        for scaleFac in (1.2, ):
            destScale = srcScale / scaleFac
            for offsetOrientDegLenArcsec in ((
                    0.0, 0.0), ):  # ((0.0, 0.0), (-35.0, 10.5)):
                # offset (bearing, length) from sky at center of source to sky at center of dest
                offset = (offsetOrientDegLenArcsec[0] * afwGeom.degrees,
                          offsetOrientDegLenArcsec[1] * afwGeom.arcseconds)
                destCtrSky = srcCtrSky.offset(*offset)
                for rotAngDeg, kernelName in (
                    (0.0, "bilinear"),
                    (0.0, "lanczos2"),
                    (0.0, "lanczos3"),
                    (45.0, "lanczos3"),
                ):
                    warpingControl = afwMath.WarpingControl(
                        kernelName,
                        maskKernelName,
                        cacheSize,
                        interpLength,
                    )
                    destWcs = afwGeom.SkyWcs(
                        crpix=destCrPix,
                        crval=destCtrSky,
                        cdMatrix=afwGeom.makeCdMatrix(scale=destScale,
                                                      orientation=rotAngDeg *
                                                      afwGeom.degrees,
                                                      flipX=False))
                    destToSrc = destWcs.then(srcWcs.getInverse())
                    dTime, nIter, goodPix = timeWarp(destMaskedImage,
                                                     srcMaskedImage, destToSrc,
                                                     warpingControl)
                    print(
                        "%4d  %5d  %8.1f  %6.1f, %6.1f  %7.1f %10s %8d %6.2f" %
                        (testNum, interpLength, scaleFac,
                         offsetOrientDegLenArcsec[0],
                         offsetOrientDegLenArcsec[1], rotAngDeg, kernelName,
                         goodPix, dTime / float(nIter)))

                    if SaveImages:
                        destMaskedImage.writeFits(
                            "warpedMaskedImage%03d.fits" % (testNum, ))
                    testNum += 1