Skip to content

Commit

Permalink
Added flagging of sources near the INJECTED mask plane
Browse files Browse the repository at this point in the history
Added requested test. Modified a test from subtract and migrated it to detectandmeasure
  • Loading branch information
BrunoSanchez committed Jan 22, 2024
1 parent 2b38363 commit 43b4832
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 13 deletions.
18 changes: 10 additions & 8 deletions python/lsst/ip/diffim/detectAndMeasure.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,12 @@ def setDefaults(self):
self.detection.excludeMaskPlanes = ["EDGE"]

# Add filtered flux measurement, the correct measurement for pre-convolved images.
self.measurement.algorithms.names.add('base_PeakLikelihoodFlux')
self.measurement.plugins.names |= ['ext_trailedSources_Naive',
'base_LocalPhotoCalib',
'base_LocalWcs',
'ext_shapeHSM_HsmSourceMoments',
'ext_shapeHSM_HsmPsfMoments',
self.measurement.algorithms.names.add("base_PeakLikelihoodFlux")
self.measurement.plugins.names |= ["ext_trailedSources_Naive",
"base_LocalPhotoCalib",
"base_LocalWcs",
"ext_shapeHSM_HsmSourceMoments",
"ext_shapeHSM_HsmPsfMoments",
]
self.measurement.slots.psfShape = "ext_shapeHSM_HsmPsfMoments"
self.measurement.slots.shape = "ext_shapeHSM_HsmSourceMoments"
Expand All @@ -174,8 +174,10 @@ def setDefaults(self):
self.forcedMeasurement.slots.shape = None

# Keep track of which footprints contain streaks
self.measurement.plugins['base_PixelFlags'].masksFpAnywhere = ['STREAK']
self.measurement.plugins['base_PixelFlags'].masksFpCenter = ['STREAK']
self.measurement.plugins["base_PixelFlags"].masksFpAnywhere = [
"STREAK", "INJECTED", "INJECTED_TEMPLATE"]
self.measurement.plugins["base_PixelFlags"].masksFpCenter = [
"STREAK", "INJECTED", "INJECTED_TEMPLATE"]


class DetectAndMeasureTask(lsst.pipe.base.PipelineTask):
Expand Down
9 changes: 4 additions & 5 deletions python/lsst/ip/diffim/subtractImages.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,16 +628,15 @@ def updateMasks(self, template, science, difference):
mask = difference.mask
mask &= ~(mask.getPlaneBitMask("DETECTED") | mask.getPlaneBitMask("DETECTED_NEGATIVE"))

self.log.info("Adding injected mask planes")
mask.addMaskPlane("INJECTED")
mask.addMaskPlane("INJECTED_TEMPLATE")

if "FAKE" in science.mask.getMaskPlaneDict().keys():
# propagate the mask plane related to Fake source injection
# NOTE: the fake source injection sets FAKE plane, but it should be INJECTED
# NOTE: This can be removed in DM-40796

self.log.info("Adding injected mask planes")
mask.addMaskPlane("INJECTED")
diffInjectedBitMask = mask.getPlaneBitMask("INJECTED")

mask.addMaskPlane("INJECTED_TEMPLATE")
diffInjTmpltBitMask = mask.getPlaneBitMask("INJECTED_TEMPLATE")

scienceFakeBitMask = science.mask.getPlaneBitMask('FAKE')
Expand Down
3 changes: 3 additions & 0 deletions python/lsst/ip/diffim/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,9 @@ def detectTestSources(exposure):
doSmooth=True
)
exposure.mask.addMaskPlane("STREAK") # add empty streak mask plane in lieu of maskStreaksTask
exposure.mask.addMaskPlane("INJECTED") # add empty injected mask plane
exposure.mask.addMaskPlane("INJECTED_TEMPLATE") # add empty injected template mask plane

selectSources = detRet.sources
selectMeasurement.run(measCat=selectSources, exposure=exposure)

Expand Down
81 changes: 81 additions & 0 deletions tests/test_detectAndMeasure.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,87 @@ def _detection_wrapper(setFlags=True):
_detection_wrapper(setFlags=False)
_detection_wrapper(setFlags=True)

def test_fake_mask_plane_propagation(self):
"""Test that we have the mask planes related to fakes in diffim images.
This is testing method called updateMasks
"""
xSize = 256
ySize = 256
science, sources = makeTestImage(psfSize=2.4, xSize=xSize, ySize=ySize, doApplyCalibration=True)
science_fake_img, science_fake_sources = makeTestImage(
psfSize=2.4, xSize=xSize, ySize=ySize, seed=5, nSrc=3, noiseLevel=0.25, fluxRange=1
)
template, _ = makeTestImage(psfSize=2.4, xSize=xSize, ySize=ySize, doApplyCalibration=True)
tmplt_fake_img, tmplt_fake_sources = makeTestImage(
psfSize=2.4, xSize=xSize, ySize=ySize, seed=9, nSrc=3, noiseLevel=0.25, fluxRange=1
)
# created fakes and added them to the images
science.image.array += science_fake_img.image.array
template.image.array += tmplt_fake_img.image.array

# TODO: DM-40796 update to INJECTED names when source injection gets refactored
# adding mask planes to both science and template images
science.mask.addMaskPlane("FAKE")
science_fake_bitmask = science.mask.getPlaneBitMask("FAKE")
template.mask.addMaskPlane("FAKE")
template_fake_bitmask = template.mask.getPlaneBitMask("FAKE")

for a_science_source in science_fake_sources:
# 3 x 3 masking of the source locations is fine
bbox = lsst.geom.Box2I(
lsst.geom.Point2I(a_science_source.getX(), a_science_source.getY()), lsst.geom.Extent2I(3, 3)
)
science[bbox].mask.array |= science_fake_bitmask

for a_template_source in tmplt_fake_sources:
# 3 x 3 masking of the source locations is fine
bbox = lsst.geom.Box2I(
lsst.geom.Point2I(a_template_source.getX(), a_template_source.getY()),
lsst.geom.Extent2I(3, 3)
)
template[bbox].mask.array |= template_fake_bitmask

science_fake_masked = (science.mask.array & science_fake_bitmask) > 0
template_fake_masked = (template.mask.array & template_fake_bitmask) > 0

subtractConfig = subtractImages.AlardLuptonSubtractTask.ConfigClass()
subtractTask = subtractImages.AlardLuptonSubtractTask(config=subtractConfig)
subtraction = subtractTask.run(template, science, sources)

# check subtraction mask plane is set where we set the previous masks
diff_mask = subtraction.difference.mask

# science mask should be now in INJECTED
inj_masked = (diff_mask.array & diff_mask.getPlaneBitMask("INJECTED")) > 0

# template mask should be now in INJECTED_TEMPLATE
injTmplt_masked = (diff_mask.array & diff_mask.getPlaneBitMask("INJECTED_TEMPLATE")) > 0

self.assertEqual(np.sum(inj_masked.astype(int)-science_fake_masked.astype(int)), 0)
self.assertEqual(np.sum(injTmplt_masked.astype(int)-template_fake_masked.astype(int)), 0)

# Now check that detection of fakes have the correct flag for injections
detectionTask = self._setup_detection()
excludeMaskPlanes = detectionTask.config.detection.excludeMaskPlanes
nBad = len(excludeMaskPlanes)
self.assertGreater(nBad, 0)

output = detectionTask.run(subtraction.matchedScience,
subtraction.matchedTemplate,
subtraction.difference)

sci_refIds = []
tmpl_refIds = []
for diaSrc in output.diaSources:
if diaSrc['base_PsfFlux_instFlux'] > 0:
self._check_diaSource(science_fake_sources, diaSrc, scale=1, refIds=sci_refIds)
self.assertTrue(diaSrc['base_PixelFlags_flag_injected'])
self.assertTrue(diaSrc['base_PixelFlags_flag_injectedCenter'])
else:
self._check_diaSource(tmplt_fake_sources, diaSrc, scale=-1, refIds=tmpl_refIds)
self.assertTrue(diaSrc['base_PixelFlags_flag_injected_template'])
self.assertTrue(diaSrc['base_PixelFlags_flag_injected_templateCenter'])


class DetectAndMeasureScoreTest(DetectAndMeasureTestBase):
detectionTask = detectAndMeasure.DetectAndMeasureScoreTask
Expand Down

0 comments on commit 43b4832

Please sign in to comment.