Skip to content

Commit

Permalink
Add subtractBackground to cutOutDonutsBase.
Browse files Browse the repository at this point in the history
Test for Donut bit in masks.
Test that background subtraction is applied.
  • Loading branch information
jbkalmbach committed Jan 24, 2024
1 parent 8b1a359 commit 2077b6f
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 25 deletions.
8 changes: 8 additions & 0 deletions doc/versionHistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
Version History
##################

.. _lsst.ts.wep-8.2.0:

-------------
8.2.0
-------------

* Add background subtraction to cutOutDonutsBase.

.. _lsst.ts.wep-8.1.1:

-------------
Expand Down
10 changes: 10 additions & 0 deletions python/lsst/ts/wep/task/cutOutDonutsBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ class CutOutDonutsBaseTaskConfig(
dtype=int,
default=6,
)
subtractBackground = pexConfig.ConfigurableField(
target=lsst.meas.algorithms.SubtractBackgroundTask,
doc="Task to perform background subtraction.",
)


class CutOutDonutsBaseTask(pipeBase.PipelineTask):
Expand Down Expand Up @@ -185,6 +189,8 @@ def __init__(self, **kwargs):
# Parameters for mask multiplication (for deblending)
self.multiplyMask = self.config.multiplyMask
self.maskGrowthIter = self.config.maskGrowthIter
# Set up background subtraction task
self.makeSubtask("subtractBackground")

def _checkAndSetOffset(self, dataOffsetValue):
"""Check offset in instParams dictionary and if it
Expand Down Expand Up @@ -384,6 +390,10 @@ def cutOutStamps(self, exposure, donutCatalog, defocalType, cameraName):
pixelScale = exposure.getWcs().getPixelScale().asArcseconds()
camType = getCamTypeFromButlerName(cameraName, detectorType)
bandpass = exposure.filter.bandLabel

# Run background subtraction
self.subtractBackground.run(exposure=exposure).background

# Get template
template = self.getTemplate(
detectorName,
Expand Down
15 changes: 6 additions & 9 deletions python/lsst/ts/wep/task/donutStamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,17 +269,14 @@ def makeMasks(self, inst, model, boundaryT, maskScalingFactorLocal):

self.comp_im.makeBlendedMask(inst, model, boundaryT, maskScalingFactorLocal)

# 0 flag in mask is part of image that is not donut
# 1 flag in mask means it is part of the model donut
maskDict = {"BKGRD": 0, "DONUT": 1}

# Set masks
self.mask_comp = afwImage.Mask(np.array(self.comp_im.mask_comp, dtype=np.int32))
self.mask_comp.clearMaskPlaneDict()
self.mask_comp.conformMaskPlanes(maskDict)
# Will inherit conformed MaskPlaneDict
afwImage.Mask.addMaskPlane("DONUT")
donutMaskVal = afwImage.Mask.getPlaneBitMask("DONUT")
self.mask_comp = afwImage.Mask(
np.array(self.comp_im.mask_comp, dtype=np.int32) * donutMaskVal
)
self.mask_pupil = afwImage.Mask(
np.array(self.comp_im.mask_pupil, dtype=np.int32)
np.array(self.comp_im.mask_pupil, dtype=np.int32) * donutMaskVal
)

def getLinearWCS(self):
Expand Down
53 changes: 43 additions & 10 deletions tests/task/test_cutOutDonutsBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,52 @@ def testCalculateFinalCentroid(self):
self.assertEqual(cornerX, 0)
self.assertEqual(cornerY, 0)

def testCutOutStamps(self):
def _getExpAndCatalog(self, defocalType):
"""
Helper function to get exposure and donutCatalog for
testing cutOutStamps.
Parameters
----------
defocalType : lsst.ts.wep.utils.DefocalType
Defocal type of stamp to cut out.
Returns
-------
lsst.afw.image.Exposure
Exposure related to given defocal type
pandas.DataFrame
Donut Catalog for exposure
"""

if defocalType is DefocalType.Extra:
dataId = self.dataIdExtra
else:
dataId = self.dataIdIntra

exposure = self.butler.get(
"postISRCCD", dataId=self.dataIdExtra, collections=[self.runName]
"postISRCCD", dataId=dataId, collections=[self.runName]
)
donutCatalog = self.butler.get(
"donutCatalog", dataId=self.dataIdExtra, collections=[self.runName]
"donutCatalog", dataId=dataId, collections=[self.runName]
)

return exposure, donutCatalog

def testBackgroundSubtractionApplied(self):
exposure, donutCatalog = self._getExpAndCatalog(DefocalType.Extra)
with self.assertRaises(KeyError):
exposure.getMetadata()["BGMEAN"]
self.task.cutOutStamps(
exposure, donutCatalog, DefocalType.Extra, self.cameraName
)
# cutOutStamps runs background subtraction which is automatically
# applied to the exposure. Thus, BGMEAN should now exist in the
# exposure metadata.
self.assertIsInstance(exposure.getMetadata()["BGMEAN"], float)

def testCutOutStamps(self):
exposure, donutCatalog = self._getExpAndCatalog(DefocalType.Extra)
donutStamps = self.task.cutOutStamps(
exposure, donutCatalog, DefocalType.Extra, self.cameraName
)
Expand Down Expand Up @@ -287,13 +326,7 @@ def testCutOutStamps(self):
)

def testCutOutStampsBlended(self):
exposure = self.butler.get(
"postISRCCD", dataId=self.dataIdExtra, collections=[self.runName]
)
donutCatalog = self.butler.get(
"donutCatalog", dataId=self.dataIdExtra, collections=[self.runName]
)

exposure, donutCatalog = self._getExpAndCatalog(DefocalType.Extra)
donutStampsNoBlend = self.task.cutOutStamps(
exposure, donutCatalog, DefocalType.Extra, self.cameraName
)
Expand Down
17 changes: 11 additions & 6 deletions tests/task/test_donutStamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,8 @@ def testMakeMasks(self):
donutStamp.makeMasks(inst, "offAxis", 0, 1)
self.assertEqual(afwImage.MaskX, type(donutStamp.mask_comp))
self.assertEqual(afwImage.MaskX, type(donutStamp.mask_pupil))
self.assertDictEqual(
{"BKGRD": 0, "DONUT": 1}, donutStamp.mask_comp.getMaskPlaneDict()
)
self.assertDictEqual(
{"BKGRD": 0, "DONUT": 1}, donutStamp.mask_pupil.getMaskPlaneDict()
)
self.assertIn("DONUT", list(donutStamp.mask_comp.getMaskPlaneDict().keys()))
self.assertIn("DONUT", list(donutStamp.mask_pupil.getMaskPlaneDict().keys()))
maskC = donutStamp.mask_comp.getArray()
maskP = donutStamp.mask_pupil.getArray()
# Donut should match
Expand All @@ -281,6 +277,15 @@ def testMakeMasks(self):
# Make sure not just an empty array
self.assertTrue(np.sum(maskC) > 0.0)
self.assertTrue(np.sum(maskP) > 0.0)
# Make sure bits set are donut bits
self.assertCountEqual(
[0, afwImage.Mask.getPlaneBitMask("DONUT")],
list(np.unique(donutStamp.mask_comp.array)),
)
self.assertCountEqual(
[0, afwImage.Mask.getPlaneBitMask("DONUT")],
list(np.unique(donutStamp.mask_pupil.array)),
)
# Donut at center of focal plane should be symmetric
np.testing.assert_array_equal(maskC[:63], maskC[-63:][::-1])
np.testing.assert_array_equal(maskP[:63], maskP[-63:][::-1])

0 comments on commit 2077b6f

Please sign in to comment.