Coverage for python/lsst/pipe/base/_dataset_handle.py: 27%

51 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-23 02:31 -0700

1# This file is part of pipe_base. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

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 GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21from __future__ import annotations 

22 

23__all__ = ["InMemoryDatasetHandle"] 

24 

25import dataclasses 

26from typing import Any, Optional 

27 

28from lsst.daf.butler import DataCoordinate, DimensionUniverse, StorageClass, StorageClassFactory 

29 

30 

31# Use an empty dataID as a default. 

32def _default_dataId() -> DataCoordinate: 

33 return DataCoordinate.makeEmpty(DimensionUniverse()) 

34 

35 

36@dataclasses.dataclass(frozen=True) 

37class InMemoryDatasetHandle: 

38 """An in-memory version of a `~lsst.daf.butler.DeferredDatasetHandle`.""" 

39 

40 def get( 

41 self, *, component: Optional[str] = None, parameters: Optional[dict] = None, **kwargs: dict 

42 ) -> Any: 

43 """Retrieves the dataset pointed to by this handle 

44 

45 This handle may be used multiple times, possibly with different 

46 parameters. 

47 

48 Parameters 

49 ---------- 

50 component : `str` or None 

51 If the deferred object is a component dataset type, this parameter 

52 may specify the name of the component to use in the get operation. 

53 parameters : `dict` or None 

54 The parameters argument will be passed to the butler get method. 

55 It defaults to None. If the value is not None, this dict will 

56 be merged with the parameters dict used to construct the 

57 `DeferredDatasetHandle` class. 

58 **kwargs 

59 This argument is deprecated and only exists to support legacy 

60 gen2 butler code during migration. It is completely ignored 

61 and will be removed in the future. 

62 

63 Returns 

64 ------- 

65 return : `object` 

66 The dataset pointed to by this handle. This is the actual object 

67 that was initially stored and not a copy. Modifying this object 

68 will modify the stored object. If the stored object is `None` this 

69 method always returns `None` regardless of any component request or 

70 parameters. 

71 

72 Raises 

73 ------ 

74 KeyError 

75 Raised if a component or parameters are used but no storage 

76 class can be found. 

77 """ 

78 if self.inMemoryDataset is None: 

79 return None 

80 

81 if self.parameters is not None: 

82 mergedParameters = self.parameters.copy() 

83 if parameters is not None: 

84 mergedParameters.update(parameters) 

85 elif parameters is not None: 

86 mergedParameters = parameters 

87 else: 

88 mergedParameters = {} 

89 

90 if component or mergedParameters: 

91 # This requires a storage class look up to locate the delegate 

92 # class. 

93 storageClass = self._getStorageClass() 

94 inMemoryDataset = self.inMemoryDataset 

95 

96 # Parameters for derived components are applied against the 

97 # composite. 

98 if component in storageClass.derivedComponents: 

99 storageClass.validateParameters(parameters) 

100 

101 # Process the parameters (hoping this never modified the 

102 # original object). 

103 inMemoryDataset = storageClass.delegate().handleParameters(inMemoryDataset, mergedParameters) 

104 mergedParameters = {} # They have now been used 

105 

106 readStorageClass = storageClass.derivedComponents[component] 

107 else: 

108 if component: 

109 readStorageClass = storageClass.components[component] 

110 else: 

111 readStorageClass = storageClass 

112 readStorageClass.validateParameters(mergedParameters) 

113 

114 if component: 

115 inMemoryDataset = storageClass.delegate().getComponent(inMemoryDataset, component) 

116 

117 if mergedParameters: 

118 inMemoryDataset = readStorageClass.delegate().handleParameters( 

119 inMemoryDataset, mergedParameters 

120 ) 

121 

122 return inMemoryDataset 

123 else: 

124 # If there are no parameters or component requests the object 

125 # can be returned as is. 

126 return self.inMemoryDataset 

127 

128 def _getStorageClass(self) -> StorageClass: 

129 """Return the relevant storage class. 

130 

131 Returns 

132 ------- 

133 storageClass : `StorageClass` 

134 The storage class associated with this handle, or one derived 

135 from the python type of the stored object. 

136 

137 Raises 

138 ------ 

139 KeyError 

140 Raised if the storage class could not be found. 

141 """ 

142 factory = StorageClassFactory() 

143 if self.storageClass: 

144 return factory.getStorageClass(self.storageClass) 

145 

146 # Need to match python type. 

147 pytype = type(self.inMemoryDataset) 

148 return factory.findStorageClass(pytype) 

149 

150 inMemoryDataset: Any 

151 """The object to store in this dataset handle for later retrieval. 

152 """ 

153 

154 storageClass: Optional[str] = None 

155 """The name of the `~lsst.daf.butler.StorageClass` associated with this 

156 dataset. 

157 

158 If `None`, the storage class will be looked up from the factory. 

159 """ 

160 

161 parameters: Optional[dict] = None 

162 """Optional parameters that may be used to specify a subset of the dataset 

163 to be loaded (`dict` or `None`). 

164 """ 

165 

166 dataId: DataCoordinate = dataclasses.field(default_factory=_default_dataId) 

167 """The `~lsst.daf.butler.DataCoordinate` associated with this dataset 

168 handle. 

169 """