Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion python/lsst/pipe/tasks/calibrateImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ class CalibrateImageConnections(pipeBase.PipelineTaskConnections,
)

# Optional outputs
mask = connectionTypes.Output(
doc="The mask plane of the calibrated exposure, written as a separate "
"output so that it can be passed to downstream tasks even if the "
"exposure is removed to save storage.",
name="preliminary_visit_mask",
storageClass="Mask",
dimensions=("instrument", "visit", "detector"),
)
psf_stars_footprints = connectionTypes.Output(
doc="Catalog of bright unresolved sources detected on the exposure used for PSF determination; "
"includes source footprints.",
Expand Down Expand Up @@ -230,6 +238,8 @@ def __init__(self, *, config=None):
del self.astrometry_matches
if "photometry_matches" not in config.optional_outputs:
del self.photometry_matches
if "mask" not in config.optional_outputs:
del self.mask
if not config.do_calibrate_pixels:
del self.applied_photo_calib
if not config.do_illumination_correction:
Expand All @@ -246,7 +256,7 @@ class CalibrateImageConfig(pipeBase.PipelineTaskConfig, pipelineConnections=Cali
dtype=str,
# TODO: note somewhere to disable this for benchmarking, but should
# we always have it on for production runs?
default=["psf_stars", "psf_stars_footprints", "astrometry_matches", "photometry_matches"],
default=["psf_stars", "psf_stars_footprints", "astrometry_matches", "photometry_matches", "mask"],
optional=False
)

Expand Down Expand Up @@ -848,6 +858,9 @@ def run(
``photometry_matches``
Reference catalog stars matches used in the photometric fit.
(`list` [`lsst.afw.table.ReferenceMatch`] or `lsst.afw.table.BaseCatalog`)
``mask``
Copy of the mask plane of `exposure`.
(`lsst.afw.image.Mask`)
"""
if result is None:
result = pipeBase.Struct()
Expand Down Expand Up @@ -967,6 +980,8 @@ def run(
photometry_meta)
if self.config.doMaskDiffractionSpikes:
self.diffractionSpikeMask.run(result.exposure)
if "mask" in self.config.optional_outputs:
result.mask = result.exposure.mask.clone()
except pipeBase.AlgorithmError:
if not have_fit_psf:
result.exposure.setPsf(None)
Expand Down
13 changes: 12 additions & 1 deletion tests/test_calibrateImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,10 @@ def setUp(self):
"initial_photometry_match_detector",
{"instrument", "visit", "detector"},
"Catalog")
butlerTests.addDatasetType(self.repo,
"preliminary_visit_mask",
{"instrument", "visit", "detector"},
"Mask")

# dataIds
self.exposure0_id = self.repo.registry.expandDataId(
Expand Down Expand Up @@ -776,6 +780,7 @@ def test_runQuantum(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
})
mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)

Expand Down Expand Up @@ -822,6 +827,7 @@ def test_runQuantum_illumination_correction(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
})
mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)

Expand Down Expand Up @@ -862,6 +868,7 @@ def test_runQuantum_2_snaps(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
})
mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)

Expand Down Expand Up @@ -899,10 +906,12 @@ def test_runQuantum_no_optional_outputs(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
}

# Check that we can turn off one output at a time.
for optional in ["psf_stars", "psf_stars_footprints", "astrometry_matches", "photometry_matches"]:
for optional in ["psf_stars", "psf_stars_footprints", "astrometry_matches", "photometry_matches",
"mask"]:
config = CalibrateImageTask.ConfigClass()
config.optional_outputs.remove(optional)
task = CalibrateImageTask(config=config)
Expand Down Expand Up @@ -944,6 +953,7 @@ def test_runQuantum_no_calibrate_pixels(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
})
mock_run = lsst.pipe.base.testUtils.runTestQuantum(task, self.butler, quantum)

Expand Down Expand Up @@ -992,6 +1002,7 @@ def test_runQuantum_exception(self):
"initial_pvi_background": self.visit_id,
"astrometry_matches": self.visit_id,
"photometry_matches": self.visit_id,
"mask": self.visit_id,
})

# A generic exception should raise directly.
Expand Down