Coverage for python/lsst/pipe/tasks/coaddBase.py: 50%

50 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-19 09:38 +0000

1# This file is part of pipe_tasks. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://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 <https://www.gnu.org/licenses/>. 

21 

22__all__ = ["CoaddBaseTask", "makeSkyInfo"] 

23 

24import lsst.pex.config as pexConfig 

25import lsst.afw.image as afwImage 

26import lsst.pipe.base as pipeBase 

27import lsst.meas.algorithms as measAlg 

28 

29from lsst.meas.algorithms import ScaleVarianceTask 

30from .selectImages import PsfWcsSelectImagesTask 

31from .coaddInputRecorder import CoaddInputRecorderTask 

32 

33 

34class CoaddBaseConfig(pexConfig.Config): 

35 """Configuration parameters for CoaddBaseTask 

36 

37 Configuration parameters shared between MakeCoaddTempExp and AssembleCoadd 

38 """ 

39 

40 coaddName = pexConfig.Field( 

41 doc="Coadd name: typically one of deep or goodSeeing.", 

42 dtype=str, 

43 default="deep", 

44 ) 

45 select = pexConfig.ConfigurableField( 

46 doc="Image selection subtask.", 

47 target=PsfWcsSelectImagesTask, 

48 ) 

49 badMaskPlanes = pexConfig.ListField( 

50 dtype=str, 

51 doc="Mask planes that, if set, the associated pixel should not be included in the coaddTempExp.", 

52 default=("NO_DATA",), 

53 ) 

54 inputRecorder = pexConfig.ConfigurableField( 

55 doc="Subtask that helps fill CoaddInputs catalogs added to the final Exposure", 

56 target=CoaddInputRecorderTask 

57 ) 

58 doPsfMatch = pexConfig.Field( 

59 dtype=bool, 

60 doc="Match to modelPsf? Sets makePsfMatched=True, makeDirect=False", 

61 deprecated="This field is no longer used. Will be removed after v27.", # TODO: DM-39841 

62 default=False 

63 ) 

64 modelPsf = measAlg.GaussianPsfFactory.makeField(doc="Model Psf factory") 

65 doApplyExternalPhotoCalib = pexConfig.Field( 

66 dtype=bool, 

67 default=False, 

68 doc=("Whether to apply external photometric calibration via an " 

69 "`lsst.afw.image.PhotoCalib` object. Uses the " 

70 "`externalPhotoCalibName` field to determine which calibration " 

71 "to load."), 

72 # TODO: remove on DM-39854. 

73 deprecated="Deprecated in favor of the 'visitSummary' connection. Will be removed after v26.", 

74 ) 

75 useGlobalExternalPhotoCalib = pexConfig.Field( 

76 dtype=bool, 

77 default=False, 

78 doc=("When using doApplyExternalPhotoCalib, use 'global' calibrations " 

79 "that are not run per-tract. When False, use per-tract photometric " 

80 "calibration files."), 

81 # TODO: remove on DM-39854. 

82 deprecated="Deprecated in favor of the 'visitSummary' connection. Will be removed after v26.", 

83 ) 

84 doApplyExternalSkyWcs = pexConfig.Field( 

85 dtype=bool, 

86 default=False, 

87 doc=("Whether to apply external astrometric calibration via an " 

88 "`lsst.afw.geom.SkyWcs` object. Uses `externalSkyWcsName` " 

89 "field to determine which calibration to load."), 

90 # TODO: remove on DM-39854. 

91 deprecated="Deprecated in favor of the 'visitSummary' connection. Will be removed after v26.", 

92 ) 

93 useGlobalExternalSkyWcs = pexConfig.Field( 

94 dtype=bool, 

95 default=False, 

96 doc=("When using doApplyExternalSkyWcs, use 'global' calibrations " 

97 "that are not run per-tract. When False, use per-tract wcs " 

98 "files."), 

99 # TODO: remove on DM-39854. 

100 deprecated="Deprecated in favor of the 'visitSummary' connection. Will be removed after v26.", 

101 ) 

102 includeCalibVar = pexConfig.Field( 

103 dtype=bool, 

104 doc="Add photometric calibration variance to warp variance plane.", 

105 default=False 

106 ) 

107 matchingKernelSize = pexConfig.Field( 107 ↛ exitline 107 didn't jump to the function exit

108 dtype=int, 

109 doc="Size in pixels of matching kernel. Must be odd.", 

110 default=21, 

111 check=lambda x: x % 2 == 1 

112 ) 

113 

114 

115class CoaddBaseTask(pipeBase.PipelineTask): 

116 """Base class for coaddition. 

117 

118 Subclasses must specify _DefaultName 

119 """ 

120 

121 ConfigClass = CoaddBaseConfig 

122 

123 def __init__(self, **kwargs): 

124 super().__init__(**kwargs) 

125 self.makeSubtask("select") 

126 self.makeSubtask("inputRecorder") 

127 

128 def getTempExpDatasetName(self, warpType="direct"): 

129 """Return warp name for given warpType and task config 

130 

131 Parameters 

132 ---------- 

133 warpType : `str` 

134 Either 'direct' or 'psfMatched'. 

135 

136 Returns 

137 ------- 

138 WarpDatasetName : `str` 

139 """ 

140 return self.config.coaddName + "Coadd_" + warpType + "Warp" 

141 

142 def getBadPixelMask(self): 

143 """Convenience method to provide the bitmask from the mask plane names 

144 """ 

145 return afwImage.Mask.getPlaneBitMask(self.config.badMaskPlanes) 

146 

147 

148def makeSkyInfo(skyMap, tractId, patchId): 

149 """Constructs SkyInfo used by coaddition tasks for multiple 

150 patchId formats. 

151 

152 Parameters 

153 ---------- 

154 skyMap : `lsst.skyMap.SkyMap` 

155 Sky map. 

156 tractId : `int` 

157 The ID of the tract. 

158 patchId : `str` or `int` or `tuple` of `int` 

159 Either Gen2-style comma delimited string (e.g. '4,5'), 

160 tuple of integers (e.g (4, 5), Gen3-style integer. 

161 

162 Returns 

163 ------- 

164 makeSkyInfo : `lsst.pipe.base.Struct` 

165 pipe_base Struct with attributes: 

166 

167 ``skyMap`` 

168 Sky map (`lsst.skyMap.SkyMap`). 

169 ``tractInfo`` 

170 Information for chosen tract of sky map (`lsst.skyMap.TractInfo`). 

171 ``patchInfo`` 

172 Information about chosen patch of tract (`lsst.skyMap.PatchInfo`). 

173 ``wcs`` 

174 WCS of tract (`lsst.afw.image.SkyWcs`). 

175 ``bbox`` 

176 Outer bbox of patch, as an geom Box2I (`lsst.afw.geom.Box2I`). 

177 """ 

178 tractInfo = skyMap[tractId] 

179 

180 if isinstance(patchId, str) and ',' in patchId: 

181 # patch format is "xIndex,yIndex" 

182 patchIndex = tuple(int(i) for i in patchId.split(",")) 

183 else: 

184 patchIndex = patchId 

185 

186 patchInfo = tractInfo.getPatchInfo(patchIndex) 

187 

188 return pipeBase.Struct( 

189 skyMap=skyMap, 

190 tractInfo=tractInfo, 

191 patchInfo=patchInfo, 

192 wcs=tractInfo.getWcs(), 

193 bbox=patchInfo.getOuterBBox(), 

194 ) 

195 

196 

197def scaleVariance(maskedImage, maskPlanes, log=None): 

198 """Scale the variance in a maskedImage 

199 

200 This is deprecated. Use the ScaleVarianceTask instead. 

201 

202 Parameters 

203 ---------- 

204 maskedImage : `lsst.afw.image.MaskedImage` 

205 MaskedImage to operate on; variance will be scaled. 

206 maskPlanes : `list` 

207 List of mask planes for pixels to reject. 

208 log : `Unknown` 

209 Log for reporting the renormalization factor; or None. 

210 

211 Returns 

212 ------- 

213 task.run : `Unknown` 

214 Renormalization factor. 

215 

216 Notes 

217 ----- 

218 The variance plane in a convolved or warped image (or a coadd derived 

219 from warped images) does not accurately reflect the noise properties of 

220 the image because variance has been lost to covariance. This function 

221 attempts to correct for this by scaling the variance plane to match 

222 the observed variance in the image. This is not perfect (because we're 

223 not tracking the covariance) but it's simple and is often good enough. 

224 """ 

225 config = ScaleVarianceTask.ConfigClass() 

226 config.maskPlanes = maskPlanes 

227 task = ScaleVarianceTask(config=config, name="scaleVariance", log=log) 

228 return task.run(maskedImage) 

229 

230 

231def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None): 

232 """Match the order of one list to another, padding if necessary 

233 

234 Parameters 

235 ---------- 

236 inputList : `list` 

237 List to be reordered and padded. Elements can be any type. 

238 inputKeys : `iterable` 

239 Iterable of values to be compared with outputKeys. Length must match `inputList`. 

240 outputKeys : `iterable` 

241 Iterable of values to be compared with inputKeys. 

242 padWith : `Unknown` 

243 Any value to be inserted where inputKey not in outputKeys. 

244 

245 Returns 

246 ------- 

247 outputList : `list` 

248 Copy of inputList reordered per outputKeys and padded with `padWith` 

249 so that the length matches length of outputKeys. 

250 """ 

251 outputList = [] 

252 for d in outputKeys: 

253 if d in inputKeys: 

254 outputList.append(inputList[inputKeys.index(d)]) 

255 else: 

256 outputList.append(padWith) 

257 return outputList