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-42012: Enable reading sub-regions and components for MaskedImage #474

Merged
merged 2 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 50 additions & 2 deletions tests/test_butlerFits.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is part of daf_butler.
# This file is part of obs_base.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
Expand Down Expand Up @@ -33,7 +33,7 @@
import lsst.pex.config
import lsst.utils.tests
from lsst.afw.fits import readMetadata
from lsst.afw.image import LOCAL, ExposureFitsReader
from lsst.afw.image import LOCAL, ExposureFitsReader, MaskedImageFitsReader
from lsst.afw.math import flipImage
from lsst.daf.base import PropertyList, PropertySet
from lsst.daf.butler import Config, DatasetType, StorageClassFactory
Expand Down Expand Up @@ -125,6 +125,7 @@ def setUpClass(cls):
# Create dataset types used by the tests
for datasetTypeName, storageClassName in (
("calexp", "ExposureF"),
("noise", "MaskedImageF"),
("unknown", "ExposureCompositeF"),
("testCatalog", "SourceCatalog"),
("lossless", "ExposureF"),
Expand Down Expand Up @@ -431,6 +432,53 @@ def testExposureFormatterAmpParameter(self):
self.assertImagesEqual(test_t3_untrimmed.image, untrimmed_full[amp.getRawBBox()].image)
self.assertAmplifiersEqual(test_t3_trimmed.getDetector()[0], amp_t3)

def testMaskedImageFormatter(self):
"""Test that a MaskedImage can be persisted and read from a Butler."""
# Read in an Exposure as MaskedImage using MaskedImageFitsReader.
reader = MaskedImageFitsReader(os.path.join(TESTDIR, "data", "calexp.fits"))
mi = reader.read()

# Put the MaskedImage into the Butler and get a reference to it.
dataId = {"visit": 42, "instrument": "DummyCam", "physical_filter": "d-r"}
ref = self.butler.put(mi, "noise", dataId)

# Check that the MaskedImage can be retrieved from the butler.
maskedImage = self.butler.get(ref)
self.assertImagesEqual(maskedImage.image, mi.image)
self.assertImagesEqual(maskedImage.mask, mi.mask)
self.assertImagesEqual(maskedImage.variance, mi.variance)

# Get a DeferredDatasetHandle to load parts of the MaskedImage.
handle = self.butler.getDeferred(ref)
Copy link
Member

Choose a reason for hiding this comment

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

Can you also do a butler.get(ref) to make sure you really do get the original masked image back?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a test. I had initially avoided it thinking it checks a more generic butler capability and had nothing specific to do with MaskedImage.


for parameters in (
{},
{"bbox": reader.readBBox()},
{"bbox": Box2I(minimum=Point2I(3, 3), maximum=Point2I(21, 16))},
{"bbox": Box2I(minimum=Point2I(3, 3), maximum=Point2I(21, 16)), "origin": LOCAL},
):
bbox = parameters.get("bbox", reader.readBBox())
with self.subTest(parameters=parameters):
# Check that the reader supports reading sub-regions.
subMaskedImage = reader.read(**parameters)
self.assertImagesEqual(subMaskedImage.image, mi.image[bbox])
self.assertImagesEqual(subMaskedImage.mask, mi.mask[bbox])
self.assertImagesEqual(subMaskedImage.variance, mi.variance[bbox])

# Get a maskedImage within a bounding box from the butler.
subMaskedImage = handle.get(parameters=parameters)
self.assertImagesEqual(subMaskedImage.image, mi.image[bbox])
self.assertImagesEqual(subMaskedImage.mask, mi.mask[bbox])
self.assertImagesEqual(subMaskedImage.variance, mi.variance[bbox])

# Get one component at a time from the butler.
subImage = handle.get(parameters=parameters, component="image")
subMask = handle.get(parameters=parameters, component="mask")
subVariance = handle.get(parameters=parameters, component="variance")
self.assertImagesEqual(subImage, mi.image[bbox])
self.assertImagesEqual(subMask, mi.mask[bbox])
self.assertImagesEqual(subVariance, mi.variance[bbox])


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion tests/test_cliCmdDefineVisits.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is part of daf_butler.
# This file is part of obs_base.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cliCmdTestIngest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is part of daf_butler.
# This file is part of obs_base.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cliCmdWriteCuratedCalibrations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is part of daf_butler.
# This file is part of obs_base.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cliLog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is part of daf_butler.
# This file is part of obs_base.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
Expand Down