diff --git a/python/lsst/ip/diffim/detectAndMeasure.py b/python/lsst/ip/diffim/detectAndMeasure.py index 6d794aa4..7d2b0bd6 100644 --- a/python/lsst/ip/diffim/detectAndMeasure.py +++ b/python/lsst/ip/diffim/detectAndMeasure.py @@ -121,6 +121,10 @@ class DetectAndMeasureConfig(pipeBase.PipelineTaskConfig, target=SourceDetectionTask, doc="Final source detection for diaSource measurement", ) + streakDetection = pexConfig.ConfigurableField( + target=SourceDetectionTask, + doc="Separate source detection used only for streak masking", + ) deblend = pexConfig.ConfigurableField( target=lsst.meas.deblender.SourceDeblendTask, doc="Task to split blended sources into their components." @@ -217,6 +221,29 @@ def setDefaults(self): "NO_DATA", ] + # Copy configs for binned streak detection from the base detection task + self.streakDetection.thresholdType = self.detection.thresholdType + self.streakDetection.reEstimateBackground = self.detection.reEstimateBackground + self.streakDetection.excludeMaskPlanes = self.detection.excludeMaskPlanes + self.streakDetection.thresholdValue = self.detection.thresholdValue + # Only detect positive streaks + self.streakDetection.thresholdPolarity = "positive" + # Do not grow detected mask for streaks + self.streakDetection.nSigmaToGrow = 0 + # Set the streak mask along the entire fit line, not only where the + # detected mask is set. + self.maskStreaks.onlyMaskDetected = False + # Restrict streak masking from growing too large + self.maskStreaks.maxStreakWidth = 100 + # Restrict the number of iterations allowed for fitting streaks + # When the fit is good it should solve quickly, and exit a bad fit quickly + self.maskStreaks.maxFitIter = 10 + # Only mask to 2 sigma in width + self.maskStreaks.nSigmaMask = 2 + # Threshold for including streaks after the Hough Transform. + # A lower value will detect more features that are less linear. + self.maskStreaks.absMinimumKernelHeight = 2 + self.measurement.plugins.names |= ["ext_trailedSources_Naive", "base_LocalPhotoCalib", "base_LocalWcs", @@ -240,10 +267,6 @@ def setDefaults(self): "STREAK", "INJECTED", "INJECTED_TEMPLATE"] self.skySources.avoidMask = ["DETECTED", "DETECTED_NEGATIVE", "BAD", "NO_DATA", "EDGE"] - # Set the streak mask along the entire fit line, not only where the - # detected mask is set. - self.maskStreaks.onlyMaskDetected = False - class DetectAndMeasureTask(lsst.pipe.base.PipelineTask): """Detect and measure sources on a difference image. @@ -295,6 +318,7 @@ def __init__(self, **kwargs): self.makeSubtask("skySources", schema=self.schema) if self.config.doMaskStreaks: self.makeSubtask("maskStreaks") + self.makeSubtask("streakDetection") # Check that the schema and config are consistent for flag in self.config.badSourceFlags: @@ -702,10 +726,13 @@ def _runStreakMasking(self, difference): self.config.streakBinFactor) binnedExposure = afwImage.ExposureF(binnedMaskedImage.getBBox()) binnedExposure.setMaskedImage(binnedMaskedImage) - binnedExposure.setPsf(difference.psf) # exposure must have a PSF + # Clear the DETECTED mask plane before streak detection + binnedExposure.mask &= ~binnedExposure.mask.getPlaneBitMask('DETECTED') # Rerun detection to set the DETECTED mask plane on binnedExposure - _table = afwTable.SourceTable.make(self.schema) - self.detection.run(table=_table, exposure=binnedExposure, doSmooth=True) + sigma = difference.psf.computeShape(difference.psf.getAveragePosition()).getDeterminantRadius() + _table = afwTable.SourceTable.make(afwTable.SourceTable.makeMinimalSchema()) + self.streakDetection.run(table=_table, exposure=binnedExposure, doSmooth=True, + sigma=sigma/self.config.streakBinFactor) binnedDetectedMaskPlane = binnedExposure.mask.array & binnedExposure.mask.getPlaneBitMask('DETECTED') rescaledDetectedMaskPlane = binnedDetectedMaskPlane.repeat(self.config.streakBinFactor, axis=0).repeat(self.config.streakBinFactor,