Example of lsst.afw.math.Background¶
- The basic strategy is
Measure the properties of the image (e.g. the mean level) – the
Background
objectInterpolate
theBackground
to provide an estimate of the backgroundOr generate an approximation to the
Background
, and use that to estimate the background
Start by importing needed packages
import os
import lsst.afw.image as afwImage
import lsst.afw.math as afwMath
import lsst.utils
Read a test Image from the DC3a-Sim data set.
def get_image():
imagePath = os.path.join(
lsst.utils.getPackageDir("afwdata"),
"DC3a-Sim",
"sci",
"v5-e0",
"v5-e0-c011-a00.sci.fits",
)
return afwImage.MaskedImageF(imagePath)
image = get_image()
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 make_background_control(image, binsize=128, **kwargs):
nx = int(image.getWidth() / binsize) + 1
ny = int(image.getHeight() / binsize) + 1
bctrl = afwMath.BackgroundControl(nx, ny, **kwargs)
return bctrl
bctrl = make_background_control(image)
Estimate the background that corresponds to our image.
bkgd = afwMath.makeBackground(image, bctrl)
We can ask for the resulting heavily-binned image (the statistics image):
stats_image = bkgd.getStatsImage()
or subtract this background estimate from the input image, interpolating our estimated values using a NATURAL_SPLINE
:
image_bgsub = image.clone()
image_bgsub -= 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(image.mask.getPlaneBitMask(["INTRP", "EDGE"]))
sctrl.setNoGoodPixelsMask(image.mask.getPlaneBitMask("BAD"))
sctrl.setNanSafe(True)
(actually we could have set most of those options in the constructor, but this is clearer)
We then build the BackgroundControl
object, passing it sctrl
and also my desired statistic.
bctrl = make_background_control(image, sctrl=sctrl, prop=afwMath.MEANCLIP)
Making the Background
is the same as before
bkgd = afwMath.makeBackground(image, bctrl)
We can get the statistics image, and its variance:
stats_image = bkgd.getStatsImage()
stats_image_variance = statsImage.getVariance()
Finally, we can interpolate in a number of ways, e.g.
AKIMA_SPLINE
AKIMA_SPLINE_PERIODIC
CONSTANT
CUBIC_SPLINE
CUBIC_SPLINE_PERIODIC
LINEAR
NATURAL_SPLINE
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)