diff --git a/python/lsst/ip/diffim/detectAndMeasure.py b/python/lsst/ip/diffim/detectAndMeasure.py index 7d2b0bd6b..8119f2790 100644 --- a/python/lsst/ip/diffim/detectAndMeasure.py +++ b/python/lsst/ip/diffim/detectAndMeasure.py @@ -526,13 +526,35 @@ def makeFootprints(sources): footprints.setFootprints([src.getFootprint() for src in sources]) return footprints - def deblend(footprints): + def deblend(footprints, negative=False): """Deblend a positive or negative footprint set, and return the deblended children. + + Parameters + ---------- + footprints : `lsst.afw.detection.FootprintSet` + negative : `bool` + Set True if the footprints contain negative fluxes + + Returns + ------- + sources : `lsst.afw.table.SourceCatalog` """ sources = afwTable.SourceCatalog(self.schema) footprints.makeSources(sources) - self.deblend.run(exposure=difference, sources=sources) + if negative: + # Invert the image so the deblender can run on positive peaks + difference_inverted = difference.clone() + difference_inverted.image *= -1 + self.deblend.run(exposure=difference_inverted, sources=sources) + children = sources[sources["parent"] != 0] + # Set the heavy footprint pixel values back to reality + for child in children: + footprint = child.getFootprint() + array = footprint.getImageArray() + array *= -1 + else: + self.deblend.run(exposure=difference, sources=sources) self.setPrimaryFlags.run(sources) children = sources["detect_isDeblendedSource"] == 1 sources = sources[children].copy(deep=True) @@ -541,7 +563,7 @@ def deblend(footprints): return sources.copy(deep=True) positives = deblend(positiveFootprints) - negatives = deblend(negativeFootprints) + negatives = deblend(negativeFootprints, negative=True) sources = afwTable.SourceCatalog(self.schema) sources.reserve(len(positives) + len(negatives)) diff --git a/tests/test_detectAndMeasure.py b/tests/test_detectAndMeasure.py index 474318ebc..ebbe3b680 100644 --- a/tests/test_detectAndMeasure.py +++ b/tests/test_detectAndMeasure.py @@ -305,9 +305,33 @@ def test_detect_transients(self): kwargs["nSrc"] = 10 kwargs["fluxLevel"] = 1000 + blendedKwargs = kwargs + blendedKwargs["nSrc"] = 1 + # Run detection and check the results def _detection_wrapper(positive=True): transients, transientSources = makeTestImage(noiseLevel=noiseLevel, noiseSeed=8, **kwargs) + # Make a nearby transient source that doesn't fall off the image + # so we can test deblending + transientsBbox = transients.getBBox() + oneSourceX = transientSources[0].getX() + oneSourceY = transientSources[0].getY() + if oneSourceX < transientsBbox.getCenter()[0]: + blendedSourceX = oneSourceX + 10 + else: + blendedSourceX = oneSourceX - 10 + if oneSourceY < transientsBbox.getCenter()[1]: + blendedSourceY = oneSourceY + 10 + else: + blendedSourceY = oneSourceY - 10 + blendedTransients, blendedTransientSources = makeTestImage(noiseLevel=0, + noiseSeed=8, + xLoc=[blendedSourceX,], + yLoc=[blendedSourceY,], + **blendedKwargs) + blendedTransientSources["id"][0] = np.max(transientSources["id"]) + 1 + transientSources.extend(blendedTransientSources) + transients.maskedImage += blendedTransients.maskedImage difference = science.clone() difference.maskedImage -= matchedTemplate.maskedImage if positive: @@ -322,7 +346,7 @@ def _detection_wrapper(positive=True): refIds = [] scale = 1. if positive else -1. for diaSource in output.diaSources: - self._check_diaSource(transientSources, diaSource, refIds=refIds, scale=scale) + self._check_diaSource(transientSources.copy(deep=True), diaSource, refIds=refIds, scale=scale) _detection_wrapper(positive=True) _detection_wrapper(positive=False)