Exemplo n.º 1
0
 def testCast(self):
     for instance in (afwMath.Chebyshev1Function1F(2),
                      afwMath.GaussianFunction1F(1.0),
                      afwMath.LanczosFunction1F(3),
                      afwMath.NullFunction1F(),
                      afwMath.PolynomialFunction1F(2)):
         Class = type(instance)
         base = instance.clone()
         self.assertEqual(type(base), afwMath.Function1F)
         derived = Class.cast(base)
         self.assertEqual(type(derived), Class)
     for instance in (afwMath.Chebyshev1Function1D(2),
                      afwMath.GaussianFunction1D(1.0),
                      afwMath.LanczosFunction1D(3),
                      afwMath.NullFunction1D(),
                      afwMath.PolynomialFunction1D(2)):
         Class = type(instance)
         base = instance.clone()
         self.assertEqual(type(base), afwMath.Function1D)
         derived = Class.cast(base)
         self.assertEqual(type(derived), Class)
     for instance in (afwMath.Chebyshev1Function2F(2),
                      afwMath.GaussianFunction2F(1.0, 1.0),
                      afwMath.DoubleGaussianFunction2F(1.0),
                      afwMath.LanczosFunction2F(3),
                      afwMath.NullFunction2F(),
                      afwMath.PolynomialFunction2F(2)):
         Class = type(instance)
         base = instance.clone()
         self.assertEqual(type(base), afwMath.Function2F)
         derived = Class.cast(base)
         self.assertEqual(type(derived), Class)
     for instance in (afwMath.Chebyshev1Function2D(2),
                      afwMath.GaussianFunction2D(1.0, 1.0),
                      afwMath.DoubleGaussianFunction2D(1.0),
                      afwMath.LanczosFunction2D(3),
                      afwMath.NullFunction2D(),
                      afwMath.PolynomialFunction2D(2)):
         Class = type(instance)
         base = instance.clone()
         self.assertEqual(type(base), afwMath.Function2D)
         derived = Class.cast(base)
         self.assertEqual(type(derived), Class)
Exemplo n.º 2
0
    def testChebyshev1Function2DTruncate(self):
        """A test for Chebyshev1Function2D.truncate"""
        maxOrder = 6
        deltaParam = 0.3
        ranges = ((-1, 1), (-17, -2), (-65.3, 2.132))
        xRangeIter = itertools.cycle(ranges)
        yRangeIter = itertools.cycle(ranges)
        yRangeIter.next()  # make x and y ranges off from each other
        nPoints = 7  # number of points in x and y at which to test the functions

        for order in range(maxOrder + 1):
            xMin, xMax = xRangeIter.next()
            xMean = (xMin + xMax) / 2.0
            xDelta = (xMax - xMin) / float(nPoints - 1)

            yMin, yMax = yRangeIter.next()
            yMean = (yMin + yMax) / 2.0
            yDelta = (yMax - yMin) / float(nPoints - 1)

            xyRange = afwGeom.Box2D(afwGeom.Point2D(xMin, yMin),
                                    afwGeom.Point2D(xMax, yMax))

            fullNParams = afwMath.Chebyshev1Function2D.nParametersFromOrder(
                order)
            fullParams = nrange(fullNParams, deltaParam, deltaParam)
            fullPoly = afwMath.Chebyshev1Function2D(fullParams, xyRange)

            for tooBigTruncOrder in range(order + 1, order + 3):
                self.assertRaises(Exception, fullPoly.truncate,
                                  tooBigTruncOrder)

            for truncOrder in range(order + 1):
                truncNParams = fullPoly.nParametersFromOrder(truncOrder)

                f = fullPoly.truncate(truncOrder)
                self.assertEqual(f.getNParameters(), truncNParams)

                g = afwMath.Chebyshev1Function2D(fullParams[0:truncNParams],
                                                 xyRange)

                self.assertEqual(f.getNParameters(), g.getNParameters())

                self.assertEqual(f.getOrder(), truncOrder)
                self.assertEqual(f.getXYRange(), xyRange)

                self.assertEqual(g.getOrder(), truncOrder)
                self.assertEqual(g.getXYRange(), xyRange)

                minXNorm = None
                maxXNorm = None
                for x in numpy.arange(xMin, xMax + xDelta / 2.0, xDelta):
                    xNorm = 2.0 * (x - xMean) / float(xMax - xMin)
                    if minXNorm == None or xNorm < minXNorm:
                        minXNorm = xNorm
                    if maxXNorm == None or xNorm > maxXNorm:
                        maxXNorm = xNorm

                    minYNorm = None
                    maxYNorm = None
                    for y in numpy.arange(yMin, yMax + yDelta / 2.0, yDelta):
                        yNorm = 2.0 * (y - yMean) / float(yMax - yMin)
                        if minYNorm == None or yNorm < minYNorm:
                            minYNorm = yNorm
                        if maxYNorm == None or yNorm > maxYNorm:
                            maxYNorm = yNorm

                            if not numpy.allclose(f(x, y), g(x, y)):
                                self.fail(
                                "%s = %s != %s = %s for x=%s, xMin=%s, xMax=%s, xNorm=%s, yMin=%s, yMax=%s, yNorm=%s, params=%s; order constructor" % \
    (type(f).__name__, f(x, y), g(x, y), type(g).__name__, x, xMin, xMax, xNorm, yMin, yMax, yNorm, params))

                    if not numpy.allclose((minYNorm, maxYNorm), (-1.0, 1.0)):
                        raise RuntimeError(
                            "Invalid y normalization: yMin=%s, yMax=%s, min/max yNorm=(%s, %s) != (-1, 1)"
                            % (yMin, yMax, minYNorm, maxYNorm))

                if not numpy.allclose((minXNorm, maxXNorm), (-1.0, 1.0)):
                    raise RuntimeError(
                        "Invalid x normalization: xMin=%s, xMax=%s, min/max xNorm=(%s, %s) != (-1, 1)"
                        % (xMin, xMax, minXNorm, maxXNorm))
Exemplo n.º 3
0
    def testChebyshev1Function2D(self):
        """A test for Chebyshev1Function2D"""
        maxOrder = 6
        deltaParam = 0.3
        ranges = ((-1, 1), (-1, 0), (0, 1), (-17, -2), (-65.3, 2.132))
        xRangeIter = itertools.cycle(ranges)
        yRangeIter = itertools.cycle(ranges)
        yRangeIter.next()  # make x and y ranges off from each other
        nPoints = 7  # number of points in x and y at which to test the functions

        for order in range(maxOrder + 1):
            xMin, xMax = xRangeIter.next()
            xMean = (xMin + xMax) / 2.0
            xDelta = (xMax - xMin) / float(nPoints - 1)

            yMin, yMax = yRangeIter.next()
            yMean = (yMin + yMax) / 2.0
            yDelta = (yMax - yMin) / float(nPoints - 1)

            xyRange = afwGeom.Box2D(afwGeom.Point2D(xMin, yMin),
                                    afwGeom.Point2D(xMax, yMax))

            f = afwMath.Chebyshev1Function2D(order, xyRange)
            numParams = f.getNParameters()
            params = nrange(numParams, deltaParam, deltaParam)
            f.setParameters(params)
            g = afwMath.Chebyshev1Function2D(params, xyRange)
            h = f.clone()

            self.assertEqual(f.getNParameters(), g.getNParameters())
            self.assertEqual(f.getNParameters(), h.getNParameters())

            self.assertEqual(f.getXYRange(), xyRange)
            self.assertEqual(f.getOrder(), order)

            self.assertEqual(g.getXYRange(), xyRange)
            self.assertEqual(g.getOrder(), order)

            #             self.assertEqual(h.getXYRange(), xyRange)
            #             self.assertEqual(h.getOrder(), order)

            # vary x in the inner loop to exercise the caching
            minYNorm = None
            maxYNorm = None
            for y in numpy.arange(yMin, yMax + yDelta / 2.0, yDelta):
                yNorm = 2.0 * (y - yMean) / float(yMax - yMin)
                if minYNorm == None or yNorm < minYNorm:
                    minYNorm = yNorm
                if maxYNorm == None or yNorm > maxYNorm:
                    maxYNorm = yNorm

                minXNorm = None
                maxXNorm = None
                for x in numpy.arange(xMin, xMax + xDelta / 2.0, xDelta):
                    xNorm = 2.0 * (x - xMean) / float(xMax - xMin)
                    if minXNorm == None or xNorm < minXNorm:
                        minXNorm = xNorm
                    if maxXNorm == None or xNorm > maxXNorm:
                        maxXNorm = xNorm

                        predVal = referenceChebyshev1Polynomial2(
                            xNorm, yNorm, params)
                        if not numpy.allclose(predVal, f(x, y)):
                            self.fail(
                                "%s = %s != %s for x=%s, xMin=%s, xMax=%s, xNorm=%s, yMin=%s, yMax=%s, yNorm=%s, params=%s; order constructor" % \
(type(f).__name__, f(x, y), predVal, x, xMin, xMax, xNorm, yMin, yMax, yNorm, params))
                        if not numpy.allclose(predVal, g(x, y)):
                            self.fail(
                                "%s = %s != %s for x=%s, xMin=%s, xMax=%s, xNorm=%s, yMin=%s, yMax=%s, yNorm=%s, params=%s; params constructor" % \
(type(g).__name__, g(x, y), predVal, x, xMin, xMax, xNorm, yMin, yMax, yNorm, params))
                        if not numpy.allclose(predVal, h(x, y)):
                            self.fail(
                                "%s = %s != %s for x=%s, xMin=%s, xMax=%s, xNorm=%s, yMin=%s, yMax=%s, yNorm=%s, params=%s; clone" % \
(type(h).__name__, h(x, y), predVal, x, xMin, xMax, xNorm, yMin, yMax, yNorm, params))

                if not numpy.allclose((minXNorm, maxXNorm), (-1.0, 1.0)):
                    raise RuntimeError(
                        "Invalid x normalization: xMin=%s, xMax=%s, min/max xNorm=(%s, %s) != (-1, 1)"
                        % (xMin, xMax, minXNorm, maxXNorm))

            if not numpy.allclose((minYNorm, maxYNorm), (-1.0, 1.0)):
                raise RuntimeError(
                    "Invalid y normalization: yMin=%s, yMax=%s, min/max yNorm=(%s, %s) != (-1, 1)"
                    % (yMin, yMax, minYNorm, maxYNorm))

        # test that the number of parameters is correct for the given order
        def numParamsFromOrder(order):
            return (order + 1) * (order + 2) / 2

        MaxOrder = 13
        for order in range(MaxOrder + 1):
            f = afwMath.Chebyshev1Function2D(order)
            predNParams = numParamsFromOrder(order)
            self.assertEqual(f.getNParameters(), predNParams)
            afwMath.Chebyshev1Function2D(numpy.zeros(predNParams, dtype=float))

        # test that the wrong number of parameters raises an exception
        validNumParams = set()
        for order in range(MaxOrder + 1):
            validNumParams.add(numParamsFromOrder(order))
        for numParams in range(numParamsFromOrder(MaxOrder)):
            if numParams in validNumParams:
                continue
            self.assertRaises(Exception, afwMath.Chebyshev1Function2D,
                              numpy.zeros(numParams, dtype=float))

        # test that changing parameters clears the cache
        # for simplicity use the xyRange that requires no normalization
        order = 3
        numParams = numParamsFromOrder(order)
        f = afwMath.Chebyshev1Function2D(order)
        xyRange = afwGeom.Box2D(afwGeom.Point2D(-1.0, -1.0),
                                afwGeom.Point2D(1.0, 1.0))
        x = 0.5
        y = -0.24
        for addValue in (0.0, 0.2):
            params = nrange(numParams, deltaParam + addValue, deltaParam)
            f.setParameters(params)
            predVal = referenceChebyshev1Polynomial2(x, y, params)
            if not numpy.allclose(predVal, f(x, y)):
                self.fail("%s = %s != %s for x=%s, y=%s, params=%s" % \
                    (type(f).__name__, f(x, y), predVal, x, y, params))
Exemplo n.º 4
0
    def testChebyshev1Function2DTruncate(self):
        errMsg = (
            "{} != {} = {} for x={}, xMin={}, xMax={}, xNorm={},"
            " yMin={}, yMax={}, yNorm={}, truncParams={}; order constructor")

        maxOrder = 6
        deltaParam = 0.3
        ranges = ((-1, 1), (-17, -2), (-65.3, 2.132))
        xRangeIter = itertools.cycle(ranges)
        yRangeIter = itertools.cycle(ranges)
        next(yRangeIter)  # make x and y ranges off from each other
        nPoints = 7  # number of points in x and y at which to test the functions

        for order in range(maxOrder + 1):
            xMin, xMax = next(xRangeIter)
            xMean = (xMin + xMax) / 2.0
            xDelta = (xMax - xMin) / float(nPoints - 1)

            yMin, yMax = next(yRangeIter)
            yMean = (yMin + yMax) / 2.0
            yDelta = (yMax - yMin) / float(nPoints - 1)

            xyRange = lsst.geom.Box2D(lsst.geom.Point2D(xMin, yMin),
                                      lsst.geom.Point2D(xMax, yMax))

            fullNParams = afwMath.Chebyshev1Function2D.nParametersFromOrder(
                order)
            fullParams = nrange(fullNParams, deltaParam, deltaParam)
            fullPoly = afwMath.Chebyshev1Function2D(fullParams, xyRange)

            for tooBigTruncOrder in range(order + 1, order + 3):
                with self.assertRaises(pexExceptions.InvalidParameterError):
                    fullPoly.truncate(tooBigTruncOrder)

            for truncOrder in range(order + 1):
                truncNParams = fullPoly.nParametersFromOrder(truncOrder)
                truncParams = fullParams[0:truncNParams]

                f = fullPoly.truncate(truncOrder)
                self.assertEqual(f.getNParameters(), truncNParams)

                g = afwMath.Chebyshev1Function2D(fullParams[0:truncNParams],
                                                 xyRange)

                self.assertEqual(f.getNParameters(), g.getNParameters())

                self.assertEqual(f.getOrder(), truncOrder)
                self.assertEqual(f.getXYRange(), xyRange)

                self.assertEqual(g.getOrder(), truncOrder)
                self.assertEqual(g.getXYRange(), xyRange)

                minXNorm = None
                maxXNorm = None
                for x in np.arange(xMin, xMax + xDelta / 2.0, xDelta):
                    xNorm = 2.0 * (x - xMean) / float(xMax - xMin)
                    if minXNorm is None or xNorm < minXNorm:
                        minXNorm = xNorm
                    if maxXNorm is None or xNorm > maxXNorm:
                        maxXNorm = xNorm

                    minYNorm = None
                    maxYNorm = None
                    for y in np.arange(yMin, yMax + yDelta / 2.0, yDelta):
                        yNorm = 2.0 * (y - yMean) / float(yMax - yMin)
                        if minYNorm is None or yNorm < minYNorm:
                            minYNorm = yNorm
                        if maxYNorm is None or yNorm > maxYNorm:
                            maxYNorm = yNorm

                            msg = errMsg.format(
                                type(f).__name__, f(x, y), g(x, y),
                                type(g).__name__, x, xMin, xMax, xNorm, yMin,
                                yMax, yNorm, truncParams)
                            self.assertFloatsAlmostEqual(f(x, y),
                                                         g(x, y),
                                                         msg=msg)

                    msg = self.normErr.format("y", yMin, yMax, minYNorm,
                                              maxYNorm)
                    self.assertFloatsAlmostEqual(minYNorm,
                                                 -1.0,
                                                 msg=msg,
                                                 atol=self.atol,
                                                 rtol=None)
                    self.assertFloatsAlmostEqual(maxYNorm,
                                                 1.0,
                                                 msg=msg,
                                                 atol=self.atol,
                                                 rtol=None)

                msg = self.normErr.format("x", xMin, xMax, minXNorm, maxXNorm)
                self.assertFloatsAlmostEqual(minXNorm,
                                             -1.0,
                                             msg=msg,
                                             atol=self.atol,
                                             rtol=None)
                self.assertFloatsAlmostEqual(maxXNorm,
                                             1.0,
                                             msg=msg,
                                             atol=self.atol,
                                             rtol=None)
Exemplo n.º 5
0
    def testChebyshev1Function2D(self):
        errMsg = ("{}: {} != {} for x={}, xMin={}, xMax={}, xNorm={}, "
                  "yMin={}, yMax={}, yNorm={}, params={}; {}")
        maxOrder = 6
        deltaParam = 0.3
        ranges = ((-1, 1), (-1, 0), (0, 1), (-17, -2), (-65.3, 2.132))
        xRangeIter = itertools.cycle(ranges)
        yRangeIter = itertools.cycle(ranges)
        next(yRangeIter)  # make x and y ranges off from each other
        nPoints = 7  # number of points in x and y at which to test the functions

        for order in range(maxOrder + 1):
            xMin, xMax = next(xRangeIter)
            xMean = (xMin + xMax) / 2.0
            xDelta = (xMax - xMin) / float(nPoints - 1)

            yMin, yMax = next(yRangeIter)
            yMean = (yMin + yMax) / 2.0
            yDelta = (yMax - yMin) / float(nPoints - 1)

            xyRange = lsst.geom.Box2D(lsst.geom.Point2D(xMin, yMin),
                                      lsst.geom.Point2D(xMax, yMax))

            f = afwMath.Chebyshev1Function2D(order, xyRange)
            numParams = f.getNParameters()
            params = nrange(numParams, deltaParam, deltaParam)
            f.setParameters(params)
            g = afwMath.Chebyshev1Function2D(params, xyRange)
            h = f.clone()

            self.assertEqual(f.getNParameters(), g.getNParameters())
            self.assertEqual(f.getNParameters(), h.getNParameters())

            self.assertEqual(f.getXYRange(), xyRange)
            self.assertEqual(f.getOrder(), order)

            self.assertEqual(g.getXYRange(), xyRange)
            self.assertEqual(g.getOrder(), order)

            # vary x in the inner loop to exercise the caching
            minYNorm = None
            maxYNorm = None
            for y in np.arange(yMin, yMax + yDelta / 2.0, yDelta):
                yNorm = 2.0 * (y - yMean) / float(yMax - yMin)
                if minYNorm is None or yNorm < minYNorm:
                    minYNorm = yNorm
                if maxYNorm is None or yNorm > maxYNorm:
                    maxYNorm = yNorm

                minXNorm = None
                maxXNorm = None
                for x in np.arange(xMin, xMax + xDelta / 2.0, xDelta):
                    xNorm = 2.0 * (x - xMean) / float(xMax - xMin)
                    if minXNorm is None or xNorm < minXNorm:
                        minXNorm = xNorm
                    if maxXNorm is None or xNorm > maxXNorm:
                        maxXNorm = xNorm

                        predVal = referenceChebyshev1Polynomial2(
                            xNorm, yNorm, params)

                        msg = errMsg.format(
                            type(f).__name__, f(x, y), predVal, x, xMin, xMax,
                            xNorm, yMin, yMax, yNorm, params,
                            "order constructor")
                        self.assertFloatsAlmostEqual(f(x, y),
                                                     predVal,
                                                     msg=msg,
                                                     atol=self.atol,
                                                     rtol=None)
                        msg = errMsg.format(
                            type(g).__name__, g(x, y), predVal, x, xMin, xMax,
                            xNorm, yMin, yMax, yNorm, params,
                            "params constructor")
                        self.assertFloatsAlmostEqual(g(x, y),
                                                     predVal,
                                                     msg=msg,
                                                     atol=self.atol,
                                                     rtol=None)
                        msg = errMsg.format(
                            type(h).__name__, h(x, y), predVal, x, xMin, xMax,
                            xNorm, yMin, yMax, yNorm, params, "order")
                        self.assertFloatsAlmostEqual(h(x, y),
                                                     predVal,
                                                     msg=msg,
                                                     atol=self.atol,
                                                     rtol=None)

                msg = self.normErr.format("x", xMin, xMax, minXNorm, maxXNorm)
                self.assertFloatsAlmostEqual(minXNorm,
                                             -1.,
                                             msg=msg,
                                             atol=self.atol)
                self.assertFloatsAlmostEqual(maxXNorm,
                                             1.,
                                             msg=msg,
                                             atol=self.atol)

            msg = self.normErr.format("y", yMin, yMax, minYNorm, maxYNorm)
            self.assertFloatsAlmostEqual(minYNorm,
                                         -1.,
                                         msg=msg,
                                         atol=self.atol)
            self.assertFloatsAlmostEqual(maxYNorm, 1., msg=msg, atol=self.atol)

        # test that the number of parameters is correct for the given order
        def numParamsFromOrder(order):
            return (order + 1) * (order + 2) // 2

        MaxOrder = 13
        for order in range(MaxOrder + 1):
            f = afwMath.Chebyshev1Function2D(order)
            predNParams = numParamsFromOrder(order)
            self.assertEqual(f.getNParameters(), predNParams)
            afwMath.Chebyshev1Function2D(np.zeros(predNParams, dtype=float))

        # test that the wrong number of parameters raises an exception
        validNumParams = set()
        for order in range(MaxOrder + 1):
            validNumParams.add(numParamsFromOrder(order))
        for numParams in range(numParamsFromOrder(MaxOrder)):
            if numParams in validNumParams:
                continue
            with self.assertRaises(pexExceptions.InvalidParameterError):
                afwMath.Chebyshev1Function2D(np.zeros(numParams, dtype=float))

        # test that changing parameters clears the cache
        # for simplicity use the xyRange that requires no normalization
        order = 3
        numParams = numParamsFromOrder(order)
        f = afwMath.Chebyshev1Function2D(order)
        xyRange = lsst.geom.Box2D(lsst.geom.Point2D(-1.0, -1.0),
                                  lsst.geom.Point2D(1.0, 1.0))
        x = 0.5
        y = -0.24
        for addValue in (0.0, 0.2):
            params = nrange(numParams, deltaParam + addValue, deltaParam)
            f.setParameters(params)
            predVal = referenceChebyshev1Polynomial2(x, y, params)
            msg = f"{f(x, y)} != {predVal} for x={x}, y={y}, params={params}"
            self.assertFloatsAlmostEqual(f(x, y),
                                         predVal,
                                         msg=msg,
                                         atol=self.atol,
                                         rtol=None)
Exemplo n.º 6
0
    def test_background_subtraction(self):
        """Check that we can recover the background,
        and that it is subtracted correctly in the difference image.
        """
        noiseLevel = 1.
        xSize = 512
        ySize = 512
        x0 = 123
        y0 = 456
        template, _ = makeTestImage(psfSize=2.0,
                                    noiseLevel=noiseLevel,
                                    noiseSeed=7,
                                    templateBorderSize=20,
                                    xSize=xSize,
                                    ySize=ySize,
                                    x0=x0,
                                    y0=y0,
                                    doApplyCalibration=True)
        params = [2.2, 2.1, 2.0, 1.2, 1.1, 1.0]

        bbox2D = lsst.geom.Box2D(lsst.geom.Point2D(x0, y0),
                                 lsst.geom.Extent2D(xSize, ySize))
        background_model = afwMath.Chebyshev1Function2D(params, bbox2D)
        science, sources = makeTestImage(psfSize=2.0,
                                         noiseLevel=noiseLevel,
                                         noiseSeed=6,
                                         background=background_model,
                                         xSize=xSize,
                                         ySize=ySize,
                                         x0=x0,
                                         y0=y0)
        config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
        config.doSubtractBackground = True

        config.makeKernel.kernel.name = "AL"
        config.makeKernel.kernel.active.fitForBackground = True
        config.makeKernel.kernel.active.spatialKernelOrder = 1
        config.makeKernel.kernel.active.spatialBgOrder = 2
        statsCtrl = _makeStats()

        def _run_and_check_images(config, statsCtrl, mode):
            """Check that the fit background matches the input model.
            """
            config.mode = mode
            task = subtractImages.AlardLuptonSubtractTask(config=config)
            output = task.run(template.clone(), science.clone(), sources)

            # We should be fitting the same number of parameters as were in the input model
            self.assertEqual(output.backgroundModel.getNParameters(),
                             background_model.getNParameters())

            # The parameters of the background fit should be close to the input model
            self.assertFloatsAlmostEqual(np.array(
                output.backgroundModel.getParameters()),
                                         np.array(params),
                                         rtol=0.3)

            # stddev of difference image should be close to expected value.
            # This will fail if we have mis-subtracted the background.
            stdVal = _computeRobustStatistics(output.difference.image,
                                              output.difference.mask,
                                              statsCtrl,
                                              statistic=afwMath.STDEV)
            self.assertFloatsAlmostEqual(stdVal,
                                         np.sqrt(2) * noiseLevel,
                                         rtol=0.1)

        _run_and_check_images(config, statsCtrl, "convolveTemplate")
        _run_and_check_images(config, statsCtrl, "convolveScience")