Skip to content

Commit

Permalink
Add subtask to find and mask satellite trails
Browse files Browse the repository at this point in the history
This commit adds a new subtask in findSatellites.py and a call to
that task in CompareWarpAssembleCoaddTask, where it is used to
detect satellite trails or other linear features in difference
images. This will only run if the config option
doFilterMorphological is set to True.
  • Loading branch information
cmsaunders committed Jun 4, 2020
1 parent ec4c6e0 commit 74a215f
Show file tree
Hide file tree
Showing 5 changed files with 925 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.. lsst-task-topic:: lsst.pipe.tasks.findSatellites.FindSatellitesTask

##################
FindSatellitesTask
##################

.. _lsst.pipe.tasks.findSatellites.FindSatellitesTask
Python API summary
==================

.. lsst-task-api-summary:: lsst.pipe.tasks.findSatellites.FindSatellitesTask

.. _findSatellites.FindSatellitesTask-subtasks:

Retargetable subtasks
=====================

.. lsst-task-config-subtasks:: lsst.pipe.tasks.findSatellites.FindSatellitesTask

.. _lsst.pipe.tasks.findSatellites.FindSatellitesTask-configs:

Configuration fields
====================

.. lsst-task-config-fields:: lsst.pipe.tasks.findSatellites.FindSatellitesTask
26 changes: 26 additions & 0 deletions python/lsst/pipe/tasks/assembleCoadd.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from .scaleZeroPoint import ScaleZeroPointTask
from .coaddHelpers import groupPatchExposures, getGroupDataRef
from .scaleVariance import ScaleVarianceTask
from .findSatellites import FindSatellitesTask
from lsst.meas.algorithms import SourceDetectionTask
from lsst.daf.butler import DeferredDatasetHandle

Expand Down Expand Up @@ -1742,6 +1743,11 @@ class CompareWarpAssembleCoaddConfig(AssembleCoaddConfig,
target=SourceDetectionTask,
doc="Detect sources on static sky model. Only used if doPreserveContainedBySource is True"
)
findSatellites = pexConfig.ConfigurableField(
target=FindSatellitesTask,
doc="Detect satellite trails on difference between each psfMatched warp and static sky model. "
"Only used if doFilterMorphological is True."
)
maxNumEpochs = pexConfig.Field(
doc="Charactistic maximum local number of epochs/visits in which an artifact candidate can appear "
"and still be masked. The effective maxNumEpochs is a broken linear function of local "
Expand Down Expand Up @@ -1810,6 +1816,12 @@ class CompareWarpAssembleCoaddConfig(AssembleCoaddConfig,
dtype=float,
default=0.05
)
doFilterMorphological = pexConfig.Field(
doc="Filter artifact candidates based on morphological criteria, i.g. those that appear to "
"be satellite trails.",
dtype=bool,
default=False
)

def setDefaults(self):
AssembleCoaddConfig.setDefaults(self)
Expand Down Expand Up @@ -1991,6 +2003,8 @@ def __init__(self, *args, **kwargs):
self.makeSubtask("detectTemplate", schema=afwTable.SourceTable.makeMinimalSchema())
if self.config.doScaleWarpVariance:
self.makeSubtask("scaleWarpVariance")
if self.config.doFilterMorphological:
self.makeSubtask("findSatellites")

@utils.inheritDoc(AssembleCoaddTask)
def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs):
Expand Down Expand Up @@ -2172,6 +2186,7 @@ def findArtifacts(self, templateCoadd, tempExpRefList, imageScalerList):
spanSetArtifactList = []
spanSetNoDataMaskList = []
spanSetEdgeList = []
spanSetBadMorphoList = []
badPixelMask = self.getBadPixelMask()

# mask of the warp diffs should = that of only the warp
Expand Down Expand Up @@ -2201,6 +2216,12 @@ def findArtifacts(self, templateCoadd, tempExpRefList, imageScalerList):
spans.setImage(slateIm, 1, doClip=True)
epochCountImage += slateIm

if self.config.doFilterMorphological:
fitResult = self.findSatellites.run(warpDiffExp, slateIm)
satMask = afwImage.Mask(coaddBBox)
satMask.array[fitResult.mask] = 1
spanSetSatellite = afwGeom.SpanSet.fromMask(satMask)

# PSF-Matched warps have less available area (~the matching kernel) because the calexps
# undergo a second convolution. Pixels with data in the direct warp
# but not in the PSF-matched warp will not have their artifacts detected.
Expand All @@ -2217,12 +2238,15 @@ def findArtifacts(self, templateCoadd, tempExpRefList, imageScalerList):
nansMask = afwImage.MaskX(coaddBBox, 1)
spanSetList = []
spanSetEdgeMask = []
spanSetSatellite = afwGeom.SpanSet([])

spanSetNoDataMask = afwGeom.SpanSet.fromMask(nansMask).split()

spanSetNoDataMaskList.append(spanSetNoDataMask)
spanSetArtifactList.append(spanSetList)
spanSetEdgeList.append(spanSetEdgeMask)
if self.config.doFilterMorphological:
spanSetBadMorphoList.append(spanSetSatellite)

if lsstDebug.Info(__name__).saveCountIm:
path = self._dataRef2DebugPath("epochCountIm", tempExpRefList[0], coaddLevel=True)
Expand All @@ -2233,6 +2257,8 @@ def findArtifacts(self, templateCoadd, tempExpRefList, imageScalerList):
filteredSpanSetList = self.filterArtifacts(spanSetList, epochCountImage, nImage,
templateFootprints)
spanSetArtifactList[i] = filteredSpanSetList
if self.config.doFilterMorphological and (spanSetBadMorphoList[i].getArea() != 0):
spanSetArtifactList[i].append(spanSetBadMorphoList[i])

altMasks = []
for artifacts, noData, edge in zip(spanSetArtifactList, spanSetNoDataMaskList, spanSetEdgeList):
Expand Down

0 comments on commit 74a215f

Please sign in to comment.