Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# 

2# LSST Data Management System 

3# Copyright 2008-2013 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

21# 

22from lsst.pipe.base import Struct 

23 

24"""Helper functions for coaddition. 

25 

26We often want to use a data reference as a key in a dict (e.g., inputs as a 

27function of data reference for a warp/tempExp), but neither data references 

28(lsst.daf.persistence.ButlerDataRef) nor data identifiers (dict) are hashable. 

29One solution is to use tuples (which are hashable) of the data identifier 

30values, and carry the data identifier keys separately. Doing the key/value 

31gymnastics can be annoying, so we provide these helper functions to do this. 

32""" 

33 

34 

35def groupDataRefs(keys, dataRefIterable): 

36 """Group data references by data identifier value-tuple. 

37 

38 Value-tuples are built from the values of the given keys. 

39 The effect is that the data references in each group have the same 

40 values for the provided keys. 

41 

42 @param keys: List of keys to consider when grouping (order is important) 

43 @param dataRefIterable: Iterable of data references to group 

44 @return Dict of <value-tuple>: <list of data references for group> 

45 """ 

46 groupDict = dict() 

47 for dataRef in dataRefIterable: 

48 dataId = dataRef.dataId 

49 values = tuple(dataId[key] for key in keys) # NOT dataId.values() as we must preserve order 

50 group = groupDict.get(values) 

51 if group: 

52 group.append(dataRef) 

53 else: 

54 groupDict[values] = [dataRef] 

55 

56 return groupDict 

57 

58 

59def groupPatchExposures(patchDataRef, calexpDataRefList, coaddDatasetType="deepCoadd", 

60 tempExpDatasetType="deepCoadd_directWarp"): 

61 """Group calibrated exposures overlapping a patch by the warped 

62 (temporary) exposure they contribute to. 

63 

64 For example, if the instrument has a mosaic camera, each group would 

65 consist of the subset of CCD exposures from a single camera exposure 

66 that potentially overlap the patch. 

67 

68 @return Struct with: 

69 - groups: Dict of <group tuple>: <list of data references for group> 

70 - keys: List of keys for group tuple 

71 """ 

72 butler = patchDataRef.getButler() 

73 tempExpKeys = butler.getKeys(datasetType=tempExpDatasetType) 

74 coaddKeys = sorted(butler.getKeys(datasetType=coaddDatasetType)) 

75 keys = sorted(set(tempExpKeys) - set(coaddKeys)) # Keys that will specify an exposure 

76 patchId = patchDataRef.dataId 

77 groups = groupDataRefs(keys, calexpDataRefList) 

78 

79 # Supplement the groups with the coadd-specific information (e.g., tract, patch; these are constant) 

80 coaddValues = tuple(patchId[k] for k in coaddKeys) 

81 groups = dict((k + coaddValues, v) for k, v in groups.items()) 

82 keys += tuple(coaddKeys) 

83 

84 return Struct(groups=groups, keys=keys) 

85 

86 

87def getGroupDataId(groupTuple, keys): 

88 """Reconstitute a data identifier from a tuple and corresponding keys 

89 

90 @param groupTuple: Tuple with values specifying a group 

91 @param keys: List of keys for group tuple 

92 @return Data identifier dict 

93 """ 

94 if len(groupTuple) != len(keys): 94 ↛ 95line 94 didn't jump to line 95, because the condition on line 94 was never true

95 raise RuntimeError("Number of values (%d) and keys (%d) do not match" % (len(groupTuple), len(keys))) 

96 return dict(zip(keys, groupTuple)) 

97 

98 

99def getGroupDataRef(butler, datasetType, groupTuple, keys): 

100 """Construct a data reference from a tuple and corresponding keys 

101 

102 @param butler: Data butler 

103 @param datasetType: Name of dataset 

104 @param groupTuple: Tuple with values specifying a group 

105 @param keys: List of keys for group tuple 

106 @return Data reference 

107 """ 

108 dataId = getGroupDataId(groupTuple, keys) 

109 return butler.dataRef(datasetType=datasetType, dataId=dataId)