Example of lsst.afw.math.Background

Using the Background class; the code’s in afw/examples/estimateBackground.py.

The basic strategy is
  • Measure the properties of the image (e.g. the mean level) – the Background object
  • Interpolate the Background to provide an estimate of the background
  • Or generate an approximation to the Background, and use that to estimate the background

Start by importing needed packages

import os
import lsst.utils
import lsst.afw.image as afwImage
import lsst.afw.math as afwMath

Read an Image

def getImage():
    imagePath = os.path.join(lsst.utils.getPackageDir("afwdata"),
                             "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci.fits")
    return afwImage.MaskedImageF(imagePath)
image = getImage()

We’ll do the simplest case first. Start by creating a BackgroundControl object that’s used to configure the algorithm that’s used to estimate the background levels.

def simpleBackground(image):
    binsize = 128
    nx = int(image.getWidth()/binsize) + 1
    ny = int(image.getHeight()/binsize) + 1
    bctrl = afwMath.BackgroundControl(nx, ny)

Estimate the background levels

bkgd = afwMath.makeBackground(image, bctrl)

We can ask for the resulting heavily-binned image (but only after casting the base class Background to one that includes such an image, a BackgroundMI)


or subtract this background estimate from the input image, interpolating our estimated values using a NATURAL_SPLINE

image -= bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE)

return bkgd

We actually have a lot more control over the whole process than that. We’ll start by building a StatisticsControl object, and telling it our desires:

sctrl = afwMath.StatisticsControl()
sctrl.setNumSigmaClip(3)
sctrl.setNumIter(4)
sctrl.setAndMask(afwImage.Mask[MaskPixel].getPlaneBitMask(["INTRP",
                                                           "EDGE"]))
sctrl.setNoGoodPixelsMask(afwImage.Mask[MaskPixel].getPlaneBitMask("BAD"))
sctrl.setNanSafe(True)

(actually I could have set most of those options in the ctor)

We then build the BackgroundControl object, passing it sctrl and also my desired statistic.

bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP)

Making the Background is the same as before

bkgd = afwMath.makeBackground(image, bctrl)

We can get the statistics image, and its variance:

statsImage = bkgd.getStatsImage()
ds9.mtv(statsImage.getVariance())

Finally, we can interpolate in a number of ways, e.g.


If we wish to use an approximation to the background (instead of interpolating the values) we proceed slightly differently. First we need an object to specify our interpolation strategy:

order = 2
actrl = afwMath.ApproximateControl(
    afwMath.ApproximateControl.CHEBYSHEV, order, order)

and then we can Approximate the Background (in this case with a Chebyshev polynomial)

approx = bkgd.getApproximate(actrl)

We can get an Image or MaskedImage from approx with

approx.getImage()
approx.getMaskedImage()

or truncate the expansion (as is often a good idea with a Chebyshev expansion); in this case to order one lower than the original fit.

approx.getImage(order - 1)