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-29065: Sort all input lists by calexpList detector order in makeWarp #479

Merged
merged 1 commit into from
Mar 11, 2021
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
32 changes: 1 addition & 31 deletions python/lsst/pipe/tasks/assembleCoadd.py
Expand Up @@ -38,7 +38,7 @@
import lsstDebug
import lsst.utils as utils
from lsst.skymap import BaseSkyMap
from .coaddBase import CoaddBaseTask, SelectDataIdContainer, makeSkyInfo, makeCoaddSuffix
from .coaddBase import CoaddBaseTask, SelectDataIdContainer, makeSkyInfo, makeCoaddSuffix, reorderAndPadList
from .interpImage import InterpImageTask
from .scaleZeroPoint import ScaleZeroPointTask
from .coaddHelpers import groupPatchExposures, getGroupDataRef
Expand Down Expand Up @@ -2442,33 +2442,3 @@ def _dataRef2DebugPath(self, prefix, warpRef, coaddLevel=False):
directory = lsstDebug.Info(__name__).figPath if lsstDebug.Info(__name__).figPath else "."
filename = "%s-%s.fits" % (prefix, '-'.join([str(warpRef.dataId[k]) for k in keyList]))
return os.path.join(directory, filename)


def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None):
"""Match the order of one list to another, padding if necessary

Parameters
----------
inputList : list
List to be reordered and padded. Elements can be any type.
inputKeys : iterable
Iterable of values to be compared with outputKeys.
Length must match `inputList`
outputKeys : iterable
Iterable of values to be compared with inputKeys.
padWith :
Any value to be inserted where inputKey not in outputKeys

Returns
-------
list
Copy of inputList reordered per outputKeys and padded with `padWith`
so that the length matches length of outputKeys.
"""
outputList = []
for d in outputKeys:
if d in inputKeys:
outputList.append(inputList[inputKeys.index(d)])
else:
outputList.append(padWith)
return outputList
30 changes: 30 additions & 0 deletions python/lsst/pipe/tasks/coaddBase.py
Expand Up @@ -357,3 +357,33 @@ def makeCoaddSuffix(warpType="direct"):
"""
suffix = "" if warpType == "direct" else warpType[0].upper() + warpType[1:]
return suffix


def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None):
"""Match the order of one list to another, padding if necessary

Parameters
----------
inputList : list
List to be reordered and padded. Elements can be any type.
inputKeys : iterable
Iterable of values to be compared with outputKeys.
Length must match `inputList`
outputKeys : iterable
Iterable of values to be compared with inputKeys.
padWith :
Any value to be inserted where inputKey not in outputKeys

Returns
-------
list
Copy of inputList reordered per outputKeys and padded with `padWith`
so that the length matches length of outputKeys.
"""
outputList = []
for d in outputKeys:
if d in inputKeys:
outputList.append(inputList[inputKeys.index(d)])
else:
outputList.append(padWith)
return outputList
46 changes: 45 additions & 1 deletion python/lsst/pipe/tasks/makeCoaddTempExp.py
Expand Up @@ -32,9 +32,10 @@
import lsst.geom
from lsst.meas.algorithms import CoaddPsf, CoaddPsfConfig
from lsst.skymap import BaseSkyMap
from .coaddBase import CoaddBaseTask, makeSkyInfo
from .coaddBase import CoaddBaseTask, makeSkyInfo, reorderAndPadList
from .warpAndPsfMatch import WarpAndPsfMatchTask
from .coaddHelpers import groupPatchExposures, getGroupDataRef
from collections.abc import Iterable

__all__ = ["MakeCoaddTempExpTask", "MakeWarpTask", "MakeWarpConfig"]

Expand Down Expand Up @@ -736,6 +737,11 @@ def runQuantum(self, butlerQC, inputRefs, outputRefs):
PipelineTask (Gen3) entry point to warp and optionally PSF-match
calexps. This method is analogous to `runDataRef`.
"""

# Ensure all input lists are in same detector order as the calExpList
detectorOrder = [ref.datasetRef.dataId['detector'] for ref in inputRefs.calExpList]
inputRefs = reorderRefs(inputRefs, detectorOrder, dataIdKey='detector')

# Read in all inputs.
inputs = butlerQC.get(inputRefs)

Expand Down Expand Up @@ -875,3 +881,41 @@ def prepareCalibratedExposures(self, calExpList, backgroundList=None, skyCorrLis
# Apply skycorr
if self.config.doApplySkyCorr:
mi -= skyCorr.getImage()


def reorderRefs(inputRefs, outputSortKeyOrder, dataIdKey):
"""Reorder inputRefs per outputSortKeyOrder

Any inputRefs which are lists will be resorted per specified key e.g.,
'detector.' Only iterables will be reordered, and values can be of type
`lsst.pipe.base.connections.DeferredDatasetRef` or
`lsst.daf.butler.core.datasets.ref.DatasetRef`.
Returned lists of refs have the same length as the outputSortKeyOrder.
If an outputSortKey not in the inputRef, then it will be padded with None.
If an inputRef contains an inputSortKey that is not in the
outputSortKeyOrder it will be removed.

Parameters
----------
inputRefs : `lsst.pipe.base.connections.QuantizedConnection`
Input references to be reordered and padded.
outputSortKeyOrder : iterable
Iterable of values to be compared with inputRef's dataId[dataIdKey]
dataIdKey : `str`
dataIdKey in the dataRefs to compare with the outputSortKeyOrder.

Returns:
--------
inputRefs: `lsst.pipe.base.connections.QuantizedConnection`
Quantized Connection with sorted DatasetRef values sorted if iterable.
"""
for connectionName, refs in inputRefs:
if isinstance(refs, Iterable):
if hasattr(refs[0], "dataId"):
inputSortKeyOrder = [ref.dataId[dataIdKey] for ref in refs]
else:
inputSortKeyOrder = [ref.datasetRef.dataId[dataIdKey] for ref in refs]
if inputSortKeyOrder != outputSortKeyOrder:
setattr(inputRefs, connectionName,
reorderAndPadList(refs, inputSortKeyOrder, outputSortKeyOrder))
return inputRefs