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-39861: Deprecate exposure connection in WriteRecalibratedSourceTableTask. #821

Merged
merged 1 commit into from
Aug 7, 2023
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
56 changes: 45 additions & 11 deletions python/lsst/pipe/tasks/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from lsst.utils.introspection import find_outside_stacklevel
from lsst.pipe.base import connectionTypes
import lsst.afw.table as afwTable
from lsst.afw.image import ExposureSummaryStats
from lsst.afw.image import ExposureSummaryStats, ExposureF
from lsst.meas.base import SingleFrameMeasurementTask, DetectorVisitIdGeneratorConfig
from lsst.skymap import BaseSkyMap

Expand Down Expand Up @@ -289,6 +289,11 @@ class WriteRecalibratedSourceTableConnections(WriteSourceTableConnections,
name="calexp",
storageClass="ExposureF",
dimensions=["instrument", "visit", "detector"],
# TODO: remove on DM-39584
deprecated=(
"Deprecated, as the `calexp` is not needed and just creates unnecessary i/o. "
"Will be removed after v26."
),
)
visitSummary = connectionTypes.Input(
doc="Input visit-summary catalog with updated calibration objects.",
Expand Down Expand Up @@ -343,7 +348,9 @@ def __init__(self, *, config=None):
# Global/Tract calibrations
# TODO: remove all of this on DM-39854.
keepSkyMap = False
keepExposure = False
if config.doApplyExternalSkyWcs and config.doReevaluateSkyWcs:
keepExposure = True
if config.useGlobalExternalSkyWcs:
self.inputs.remove("externalSkyWcsTractCatalog")
else:
Expand All @@ -353,6 +360,7 @@ def __init__(self, *, config=None):
self.inputs.remove("externalSkyWcsTractCatalog")
self.inputs.remove("externalSkyWcsGlobalCatalog")
if config.doApplyExternalPhotoCalib and config.doReevaluatePhotoCalib:
keepExposure = True
if config.useGlobalExternalPhotoCalib:
self.inputs.remove("externalPhotoCalibTractCatalog")
else:
Expand All @@ -363,6 +371,8 @@ def __init__(self, *, config=None):
self.inputs.remove("externalPhotoCalibGlobalCatalog")
if not keepSkyMap:
del self.skyMap
if not keepExposure:
del self.exposure


class WriteRecalibratedSourceTableConfig(WriteSourceTableConfig,
Expand Down Expand Up @@ -441,8 +451,13 @@ def runQuantum(self, butlerQC, inputRefs, outputRefs):
if self.config.doApplyExternalPhotoCalib or self.config.doApplyExternalSkyWcs:
inputs['exposure'] = self.attachCalibs(inputRefs, **inputs)
else:
# Create an empty exposure that will hold the calibrations.
exposure = ExposureF()
detectorId = butlerQC.quantum.dataId["detector"]
inputs['exposure'] = self.prepareCalibratedExposure(
exposure=inputs["exposure"], visitSummary=inputs["visitSummary"]
exposure=exposure,
detectorId=detectorId,
visitSummary=inputs["visitSummary"],
)
inputs['catalog'] = self.addCalibColumns(**inputs)

Expand Down Expand Up @@ -573,15 +588,22 @@ def getClosestTract(self, tracts, skyMap, bbox, wcs):
return np.argmin(sep)

def prepareCalibratedExposure(
self, exposure, externalSkyWcsCatalog=None, externalPhotoCalibCatalog=None, visitSummary=None
self,
exposure,
detectorId,
externalSkyWcsCatalog=None,
externalPhotoCalibCatalog=None,
visitSummary=None,
):
"""Prepare a calibrated exposure and apply external calibrations
if so configured.

Parameters
----------
exposure : `lsst.afw.image.exposure.Exposure`
Input exposure to adjust calibrations.
Input exposure to adjust calibrations. May be empty.
detectorId : `int`
Detector ID associated with the exposure.
externalSkyWcsCatalog : `lsst.afw.table.ExposureCatalog`, optional
Exposure catalog with external skyWcs to be applied
if config.doApplyExternalSkyWcs=True. Catalog uses the detector id
Expand All @@ -602,20 +624,20 @@ def prepareCalibratedExposure(
exposure : `lsst.afw.image.exposure.Exposure`
Exposure with adjusted calibrations.
"""
detectorId = exposure.getInfo().getDetector().getId()

if visitSummary is not None:
row = visitSummary.find(detectorId)
if row is None:
raise RuntimeError(f"Visit summary for detector {detectorId} is unexpectedly missing.")
if (photoCalib := row.getPhotoCalib()) is None:
self.log.warning("Detector id %s has None for photoCalib in visit summary; "
"using original photoCalib.", detectorId)
"skipping reevaluation of photoCalib.", detectorId)
exposure.setPhotoCalib(None)
else:
exposure.setPhotoCalib(photoCalib)
if (skyWcs := row.getWcs()) is None:
self.log.warning("Detector id %s has None for skyWcs in visit summary; "
"using original skyWcs.", detectorId)
"skipping reevaluation of skyWcs.", detectorId)
exposure.setWcs(None)
else:
exposure.setWcs(skyWcs)

Expand Down Expand Up @@ -692,10 +714,10 @@ def addCalibColumns(self, catalog, exposure, idGenerator, **kwargs):

measureConfig.plugins.names = []
if self.config.doReevaluateSkyWcs:
measureConfig.plugins.names.add('base_LocalWcs')
measureConfig.plugins.names.add("base_LocalWcs")
self.log.info("Re-evaluating base_LocalWcs plugin")
if self.config.doReevaluatePhotoCalib:
measureConfig.plugins.names.add('base_LocalPhotoCalib')
measureConfig.plugins.names.add("base_LocalPhotoCalib")
self.log.info("Re-evaluating base_LocalPhotoCalib plugin")
pluginsNotToCopy = tuple(measureConfig.plugins.names)

Expand All @@ -719,8 +741,20 @@ def addCalibColumns(self, catalog, exposure, idGenerator, **kwargs):
# sky and are used as such in sdm tables without transform
if self.config.doReevaluateSkyWcs and exposure.wcs is not None:
afwTable.updateSourceCoords(exposure.wcs, newCat)
wcsPlugin = measurement.plugins["base_LocalWcs"]
else:
wcsPlugin = None

if self.config.doReevaluatePhotoCalib and exposure.getPhotoCalib() is not None:
pcPlugin = measurement.plugins["base_LocalPhotoCalib"]
else:
pcPlugin = None

measurement.run(measCat=newCat, exposure=exposure, exposureId=idGenerator.catalog_id)
for row in newCat:
if wcsPlugin is not None:
wcsPlugin.measure(row, exposure)
if pcPlugin is not None:
pcPlugin.measure(row, exposure)

return newCat

Expand Down