Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-17426 #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions python/lsst/pipe/drivers/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import lsst.afw.image as afwImage
import lsst.afw.geom as afwGeom
import lsst.afw.cameraGeom as afwCameraGeom
import lsst.meas.algorithms as measAlg
import lsst.afw.table as afwTable

from lsst.pex.config import Config, Field, ListField, ChoiceField, ConfigField, RangeField
from lsst.pex.config import Config, Field, ListField, ChoiceField, ConfigField, RangeField, ConfigurableField
from lsst.pipe.base import Task


Expand Down Expand Up @@ -284,7 +286,9 @@ def measureScale(self, image, skyBackground):
statistic = afwMath.stringToStatisticsProperty(self.config.stats.statistic)
imageSamples = []
skySamples = []
for xStart, yStart, xStop, yStop in zip(xLimits[:-1], yLimits[:-1], xLimits[1:], yLimits[1:]):
for xIndex, yIndex in itertools.product(range(self.config.xNumSamples), range(self.config.yNumSamples)):
xStart, xStop = xLimits[xIndex : xIndex + 2]
yStart, yStop = yLimits[yIndex : yIndex + 2]
box = afwGeom.Box2I(afwGeom.Point2I(xStart, yStart), afwGeom.Point2I(xStop, yStop))
subImage = image.Factory(image, box)
subSky = sky.Factory(sky, box)
Expand Down Expand Up @@ -721,3 +725,63 @@ def getStatsImage(self):
return values


class MaskObjectsConfig(Config):
"""Configuration for MaskObjectsTask"""
nIter = Field(doc="Iteration for masking", dtype=int, default=3)
subtractBackground = ConfigurableField(target=measAlg.SubtractBackgroundTask, doc='Background configuration')
detection = ConfigurableField(target=measAlg.SourceDetectionTask, doc="Detection configuration")
detectSigma = Field(dtype=float, default=5., doc='Detection PSF gaussian sigmas')
doInterpolate = Field(dtype=bool, default=True, doc='Interpolate masked region?')
interpolate = ConfigurableField(target=measAlg.SubtractBackgroundTask, doc='Interpolate configuration')

def setDefaults(self):
self.detection.reEstimateBackground = False
self.detection.doTempLocalBackground = False
self.detection.doTempWideBackground = False
self.detection.thresholdValue = 2.5
# self.detection.thresholdPolarity = "both"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code.

self.subtractBackground.binSize = 1024
self.subtractBackground.useApprox = False
self.interpolate.binSize = 256
self.interpolate.useApprox = False

def validate(self):
assert not self.detection.reEstimateBackground
assert not self.detection.doTempLocalBackground
assert not self.detection.doTempWideBackground

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change these into RuntimeErrors with useful error messages?



class MaskObjectsTask(Task):
"""MaskObjectsTask

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a better short summary than the name of the task. Maybe "Iterative masking of objects on an image"?


This task makes more exhaustive object mask by iteratively doing detection and background-subtraction.
michitaro marked this conversation as resolved.
Show resolved Hide resolved
The purpose of this task is to get true background removing faint tails of large objects.
This is useful to make clean SKY from relatively small number of visits.

We deliberately use the specified 'detectSigma' instead of the PSF,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put detectSigma in double backticks instead of quotes:

``detectSigma``

in order to better pick up the faint wings of objects.
"""
ConfigClass = MaskObjectsConfig

def __init__(self, *args, **kwargs):
super(MaskObjectsTask, self).__init__(*args, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python 3, so just need super().__init__(*args, **kwargs).

# Disposable schema suppresses warning from SourceDetectionTask.__init__
self.makeSubtask("detection", schema=afwTable.Schema())
self.makeSubtask('interpolate')
self.makeSubtask('subtractBackground')

def run(self, exp):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for i in range(self.config.nIter):
self.log.info("Masking %d/%d", i + 1, self.config.nIter)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be self.log.debug.

bg = self.subtractBackground.run(exp).background
fp = self.detection.detectFootprints(exp, sigma=self.config.detectSigma, clearMask=True)
exp.maskedImage += bg.getImage()

if self.config.doInterpolate:
self.log.info("Interpolating")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.log.debug

smooth = self.interpolate.run(exp).background
exp.maskedImage += smooth.getImage()
mask = exp.maskedImage.mask
detected = mask.array & mask.getPlaneBitMask(['DETECTED']) > 0
exp.maskedImage.image.array[detected] = smooth.getImage().getArray()[detected]