LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
LSSTDataManagementBasePackage
Background

Using the Background class; the code's in estimateBackground.py.

The basic strategy is

Start by importing needed packages

import os
import eups
import lsst.afw.image as afwImage
import lsst.afw.math as afwMath
Read an Image
def getImage():
imagePath = os.path.join(eups.productDir("afwdata"),
"DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci_img.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)

statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage()

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

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

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.MaskU.getPlaneBitMask(["INTRP", "EDGE"]))
sctrl.setNoGoodPixelsMask(afwImage.MaskU.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 = afwMath.cast_BackgroundMI(bkgd).getStatsImage()
ds9.mtv(statsImage.getVariance())

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

bkdgImages = dict(SPLINE = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE),
LINEAR = bkgd.getImageF(afwMath.Interpolate.LINEAR))

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 with (in this case 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)