Skip to content

Commit cb2ebc0

Browse files
committed
Remove parents and children of bad sources
1 parent 746b71c commit cb2ebc0

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

python/lsst/ip/diffim/detectAndMeasure.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ class DetectAndMeasureConnections(pipeBase.PipelineTaskConnections,
7676
storageClass="SourceCatalog",
7777
name="{fakesType}{coaddName}Diff_diaSrc",
7878
)
79+
badSources = pipeBase.connectionTypes.Output(
80+
doc="Sources and blends removed from the diaSources catalog.",
81+
dimensions=("instrument", "visit", "detector"),
82+
storageClass="SourceCatalog",
83+
name="{fakesType}{coaddName}Diff_diaSrc_removedSources",
84+
)
7985
subtractedMeasuredExposure = pipeBase.connectionTypes.Output(
8086
doc="Difference image with detection mask plane filled in.",
8187
dimensions=("instrument", "visit", "detector"),
@@ -386,7 +392,7 @@ def _measureSources(self, science, matchedTemplate, difference, initialDiaSource
386392
streakInfo = self._runStreakMasking(difference.maskedImage)
387393

388394
self.measureDiaSources(initialDiaSources, science, difference, matchedTemplate)
389-
diaSources = self._removeBadSources(initialDiaSources)
395+
diaSources, removedSources = self._removeBadSources(initialDiaSources)
390396

391397
if self.config.doForcedMeasurement:
392398
self.measureForcedSources(diaSources, science, difference.getWcs())
@@ -396,6 +402,7 @@ def _measureSources(self, science, matchedTemplate, difference, initialDiaSource
396402
measurementResults = pipeBase.Struct(
397403
subtractedMeasuredExposure=difference,
398404
diaSources=diaSources,
405+
removedSources=removedSources,
399406
)
400407
if self.config.doMaskStreaks and self.config.writeStreakInfo:
401408
measurementResults.mergeItems(streakInfo, 'maskedStreaks')
@@ -506,17 +513,33 @@ def _removeBadSources(self, diaSources):
506513
The updated catalog of detected sources, with any source that has a
507514
flag in ``config.badSourceFlags`` set removed.
508515
"""
509-
selector = np.ones(len(diaSources), dtype=bool)
516+
bad_sources = np.zeros(len(diaSources), dtype=bool)
510517
for flag in self.config.badSourceFlags:
511518
flags = diaSources[flag]
512519
nBad = np.count_nonzero(flags)
513520
if nBad > 0:
514521
self.log.debug("Found %d unphysical sources with flag %s.", nBad, flag)
515-
selector &= ~flags
516-
nBadTotal = np.count_nonzero(~selector)
522+
bad_sources |= flags
523+
# Remove parents of bad children, and children of bad parents.
524+
# This is due to the measurement plugins, where it is assumed that
525+
# parent blends have all of their children in the catalog, and vice versa.
526+
parents = (
527+
(diaSources["parent"] == 0)
528+
& (diaSources["deblend_nChild"] > 1)
529+
& (~diaSources["deblend_skipped"])
530+
)
531+
children = (diaSources["parent"] != 0)
532+
parents_to_remove = np.unique(diaSources["parent"][children & bad_sources])
533+
bad_parents = parents & bad_sources
534+
bad_parents |= np.in1d(diaSources["id"], parents_to_remove)
535+
children_to_remove = np.in1d(diaSources["parent"], diaSources["id"][bad_parents])
536+
bad_children = (bad_sources & children) | children_to_remove
537+
bad_sources |= bad_parents | bad_children
538+
539+
nBadTotal = np.count_nonzero(bad_sources)
517540
self.metadata.add("nRemovedBadFlaggedSources", nBadTotal)
518-
self.log.info("Removed %d unphysical sources.", nBadTotal)
519-
return diaSources[selector].copy(deep=True)
541+
self.log.info("Removed %d unphysical sources and blends.", nBadTotal)
542+
return diaSources[~bad_sources].copy(deep=True), diaSources[bad_sources]
520543

521544
def addSkySources(self, diaSources, mask, seed,
522545
subtask=None):

tests/test_detectAndMeasure.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,9 @@ def test_remove_unphysical(self):
247247
badDiaSrc = ~bbox.contains(diaSources.getX(), diaSources.getY())
248248
nBad = np.count_nonzero(badDiaSrc)
249249
self.assertEqual(nBad, nSetBad)
250-
diaSourcesNoBad = detectionTask._removeBadSources(diaSources)
250+
diaSourcesNoBad, removedSources = detectionTask._removeBadSources(diaSources)
251251
badDiaSrcNoBad = ~bbox.contains(diaSourcesNoBad.getX(), diaSourcesNoBad.getY())
252+
self.assertEqual(len(removedSources), nSetBad)
252253

253254
# Verify that no sources outside the image bounding box remain
254255
self.assertEqual(np.count_nonzero(badDiaSrcNoBad), 0)

0 commit comments

Comments
 (0)