LSSTApplications  11.0-13-gbb96280,12.1+18,12.1+7,12.1-1-g14f38d3+72,12.1-1-g16c0db7+5,12.1-1-g5961e7a+84,12.1-1-ge22e12b+23,12.1-11-g06625e2+4,12.1-11-g0d7f63b+4,12.1-19-gd507bfc,12.1-2-g7dda0ab+38,12.1-2-gc0bc6ab+81,12.1-21-g6ffe579+2,12.1-21-gbdb6c2a+4,12.1-24-g941c398+5,12.1-3-g57f6835+7,12.1-3-gf0736f3,12.1-37-g3ddd237,12.1-4-gf46015e+5,12.1-5-g06c326c+20,12.1-5-g648ee80+3,12.1-5-gc2189d7+4,12.1-6-ga608fc0+1,12.1-7-g3349e2a+5,12.1-7-gfd75620+9,12.1-9-g577b946+5,12.1-9-gc4df26a+10
LSSTDataManagementBasePackage
coaddHelpers.py
Go to the documentation of this file.
1 from builtins import zip
2 #
3 # LSST Data Management System
4 # Copyright 2008-2013 LSST Corporation.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <http://www.lsstcorp.org/LegalNotices/>.
22 #
23 
24 from lsst.pipe.base import Struct
25 
26 """Helper functions for coaddition.
27 
28 We often want to use a data reference as a key in a dict (e.g., inputs as a
29 function of data reference for a warp/tempExp), but neither data references
30 (lsst.daf.persistence.ButlerDataRef) nor data identifiers (dict) are hashable.
31 One solution is to use tuples (which are hashable) of the data identifier
32 values, and carry the data identifier keys separately. Doing the key/value
33 gymnastics can be annoying, so we provide these helper functions to do this.
34 """
35 
36 
37 def groupDataRefs(keys, dataRefIterable):
38  """Group data references by data identifier value-tuple.
39 
40  Value-tuples are built from the values of the given keys.
41  The effect is that the data references in each group have the same
42  values for the provided keys.
43 
44  @param keys: List of keys to consider when grouping (order is important)
45  @param dataRefIterable: Iterable of data references to group
46  @return Dict of <value-tuple>: <list of data references for group>
47  """
48  groupDict = dict()
49  for dataRef in dataRefIterable:
50  dataId = dataRef.dataId
51  values = tuple(dataId[key] for key in keys) # NOT dataId.values() as we must preserve order
52  group = groupDict.get(values)
53  if group:
54  group.append(dataRef)
55  else:
56  groupDict[values] = [dataRef]
57 
58  return groupDict
59 
60 
61 def groupPatchExposures(patchDataRef, calexpDataRefList, coaddDatasetType="deepCoadd",
62  tempExpDatasetType="deepCoadd_tempExp"):
63  """Group calibrated exposures overlapping a patch by the warped
64  (temporary) exposure they contribute to.
65 
66  For example, if the instrument has a mosaic camera, each group would
67  consist of the subset of CCD exposures from a single camera exposure
68  that potentially overlap the patch.
69 
70  @return Struct with:
71  - groups: Dict of <group tuple>: <list of data references for group>
72  - keys: List of keys for group tuple
73  """
74  butler = patchDataRef.getButler()
75  tempExpKeys = butler.getKeys(datasetType=tempExpDatasetType)
76  coaddKeys = sorted(butler.getKeys(datasetType=coaddDatasetType))
77  keys = sorted(set(tempExpKeys) - set(coaddKeys)) # Keys that will specify an exposure
78  patchId = patchDataRef.dataId
79  groups = groupDataRefs(keys, calexpDataRefList)
80 
81  # Supplement the groups with the coadd-specific information (e.g., tract, patch; these are constant)
82  coaddValues = tuple(patchId[k] for k in coaddKeys)
83  groups = dict((k + coaddValues, v) for k, v in groups.items())
84  keys += tuple(coaddKeys)
85 
86  return Struct(groups=groups, keys=keys)
87 
88 
89 def getGroupDataId(groupTuple, keys):
90  """Reconstitute a data identifier from a tuple and corresponding keys
91 
92  @param groupTuple: Tuple with values specifying a group
93  @param keys: List of keys for group tuple
94  @return Data identifier dict
95  """
96  if len(groupTuple) != len(keys):
97  raise RuntimeError("Number of values (%d) and keys (%d) do not match" % (len(groupTuple), len(keys)))
98  return dict(zip(keys, groupTuple))
99 
100 
101 def getGroupDataRef(butler, datasetType, groupTuple, keys):
102  """Construct a data reference from a tuple and corresponding keys
103 
104  @param butler: Data butler
105  @param datasetType: Name of dataset
106  @param groupTuple: Tuple with values specifying a group
107  @param keys: List of keys for group tuple
108  @return Data reference
109  """
110  dataId = getGroupDataId(groupTuple, keys)
111  return butler.dataRef(datasetType=datasetType, dataId=dataId)