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-47901: Configure streak masking for ComCam #367

Merged
merged 4 commits into from
Dec 12, 2024
Merged
Changes from all 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
41 changes: 34 additions & 7 deletions python/lsst/ip/diffim/detectAndMeasure.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add docstring for the absMinimumKernelHeight config setting


self.measurement.plugins.names |= ["ext_trailedSources_Naive",
"base_LocalPhotoCalib",
"base_LocalWcs",
Expand All @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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())
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you specifically not want the self.schema we used previously that had some extra columns floating around? I assumed it was more efficient to pass along an existing schema than making a new one from scratch, but it probably doesn't matter much either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The minimal schema is trivial to create, and makes detection slightly faster since the resulting table has far fewer columns.

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,
Expand Down
Loading