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# This file is part of pipe_tasks. 

2# 

3# LSST Data Management System 

4# This product includes software developed by the 

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

6# See COPYRIGHT file at the top of the source tree. 

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 <https://www.lsstcorp.org/LegalNotices/>. 

21# 

22"""Test AssembleCoaddTask and its variants. 

23 

24This uses 

25""" 

26import unittest 

27 

28import lsst.utils.tests 

29 

30from lsst.pipe.tasks.assembleCoadd import (AssembleCoaddTask, AssembleCoaddConfig, 

31 SafeClipAssembleCoaddTask, SafeClipAssembleCoaddConfig, 

32 CompareWarpAssembleCoaddTask, CompareWarpAssembleCoaddConfig) 

33from lsst.pipe.tasks.dcrAssembleCoadd import DcrAssembleCoaddTask, DcrAssembleCoaddConfig 

34from assembleCoaddTestUtils import makeMockSkyInfo, MockCoaddTestData 

35 

36__all__ = ["MockAssembleCoaddConfig", "MockAssembleCoaddTask", 

37 "MockCompareWarpAssembleCoaddConfig", "MockCompareWarpAssembleCoaddTask"] 

38 

39 

40class MockAssembleCoaddConfig(AssembleCoaddConfig): 

41 

42 def setDefaults(self): 

43 super().setDefaults() 

44 self.doWrite = False 

45 

46 

47class MockAssembleCoaddTask(AssembleCoaddTask): 

48 """Lightly modified version of `AssembleCoaddTask` for use with unit tests. 

49 

50 The modifications bypass the usual middleware for loading data and setting 

51 up the Task, and instead supply in-memory mock data references to the `run` 

52 method so that the coaddition algorithms can be tested without a Butler. 

53 """ 

54 ConfigClass = MockAssembleCoaddConfig 

55 

56 def __init__(self, **kwargs): 

57 super().__init__(**kwargs) 

58 self.warpType = self.config.warpType 

59 self.makeSubtask("interpImage") 

60 self.makeSubtask("scaleZeroPoint") 

61 

62 def processResults(self, *args, **kwargs): 

63 "This should be tested separately." 

64 pass 

65 

66 def _dataRef2DebugPath(self, *args, **kwargs): 

67 raise NotImplementedError("This lightweight version of the task is not " 

68 "meant to test debugging options.") 

69 

70 def runQuantum(self, mockSkyInfo, warpRefList, *args): 

71 """Modified interface for testing coaddition algorithms without a Butler. 

72 

73 Parameters 

74 ---------- 

75 mockSkyInfo : `lsst.pipe.base.Struct` 

76 A simple container that supplies a bounding box and WCS in the 

77 same format as the output of 

78 `lsst.pipe.tasks.CoaddBaseTask.getSkyInfo` 

79 warpRefList : `list` of `lsst.pipe.tasks.MockExposureReference` 

80 Data references to the test exposures that will be coadded, 

81 using the Gen 3 API. 

82 

83 Returns 

84 ------- 

85 retStruct : `lsst.pipe.base.Struct` 

86 The coadded exposure and associated metadata. 

87 """ 

88 inputs = self.prepareInputs(warpRefList) 

89 supplementaryData = self.makeSupplementaryData(mockSkyInfo, warpRefList=inputs.tempExpRefList) 

90 

91 retStruct = self.run(mockSkyInfo, inputs.tempExpRefList, inputs.imageScalerList, 

92 inputs.weightList, supplementaryData=supplementaryData) 

93 return retStruct 

94 

95 def runDataRef(self, mockSkyInfo, selectDataList=None, warpRefList=None): 

96 """Modified interface for testing coaddition algorithms without a Butler. 

97 

98 Notes 

99 ----- 

100 This tests the coaddition algorithms using Gen 2 Butler data references, 

101 and can be removed once that is fully deprecated. 

102 

103 Both `runDataRef` and `runQuantum` are needed even those their 

104 implementation here is identical, because the Gen 2 and Gen 3 versions 

105 of `makeSupplementaryData` call `runDataRef` and `runQuantum` to build 

106 initial templates, respectively. 

107 

108 Parameters 

109 ---------- 

110 mockSkyInfo : `lsst.pipe.base.Struct` 

111 A simple container that supplies a bounding box and WCS in the 

112 same format as the output of 

113 `lsst.pipe.tasks.CoaddBaseTask.getSkyInfo` 

114 warpRefList : `list` of `lsst.pipe.tasks.MockGen2ExposureReference` 

115 Data references to the test exposures that will be coadded, 

116 using the Gen 2 API. 

117 

118 Returns 

119 ------- 

120 retStruct : `lsst.pipe.base.Struct` 

121 The coadded exposure and associated metadata. 

122 """ 

123 inputData = self.prepareInputs(warpRefList) 

124 supplementaryData = self.makeSupplementaryData(mockSkyInfo, warpRefList=inputData.tempExpRefList) 

125 retStruct = self.run(mockSkyInfo, inputData.tempExpRefList, inputData.imageScalerList, 

126 inputData.weightList, supplementaryData=supplementaryData) 

127 return retStruct 

128 

129 

130class MockSafeClipAssembleCoaddConfig(SafeClipAssembleCoaddConfig): 

131 

132 def setDefaults(self): 

133 super().setDefaults() 

134 self.assembleMeanCoadd.retarget(MockAssembleCoaddTask) 

135 self.assembleMeanClipCoadd.retarget(MockAssembleCoaddTask) 

136 self.doWrite = False 

137 

138 

139class MockSafeClipAssembleCoaddTask(MockAssembleCoaddTask, SafeClipAssembleCoaddTask): 

140 """Lightly modified version of `SafeClipAssembleCoaddTask` 

141 for use with unit tests. 

142 

143 The modifications bypass the usual middleware for loading data and setting 

144 up the Task, and instead supply in-memory mock data references to the `run` 

145 method so that the coaddition algorithms can be tested without a Butler. 

146 """ 

147 ConfigClass = MockSafeClipAssembleCoaddConfig 

148 _DefaultName = "safeClipAssembleCoadd" 

149 

150 def __init__(self, *args, **kwargs): 

151 SafeClipAssembleCoaddTask.__init__(self, *args, **kwargs) 

152 

153 

154class MockCompareWarpAssembleCoaddConfig(CompareWarpAssembleCoaddConfig): 

155 

156 def setDefaults(self): 

157 super().setDefaults() 

158 self.assembleStaticSkyModel.retarget(MockAssembleCoaddTask) 

159 self.assembleStaticSkyModel.doWrite = False 

160 self.doWrite = False 

161 

162 

163class MockCompareWarpAssembleCoaddTask(MockAssembleCoaddTask, CompareWarpAssembleCoaddTask): 

164 """Lightly modified version of `CompareWarpAssembleCoaddTask` 

165 for use with unit tests. 

166 

167 The modifications bypass the usual middleware for loading data and setting 

168 up the Task, and instead supply in-memory mock data references to the `run` 

169 method so that the coaddition algorithms can be tested without a Butler. 

170 """ 

171 ConfigClass = MockCompareWarpAssembleCoaddConfig 

172 _DefaultName = "compareWarpAssembleCoadd" 

173 

174 def __init__(self, *args, **kwargs): 

175 CompareWarpAssembleCoaddTask.__init__(self, *args, **kwargs) 

176 

177 

178class MockDcrAssembleCoaddConfig(DcrAssembleCoaddConfig): 

179 

180 def setDefaults(self): 

181 super().setDefaults() 

182 self.assembleStaticSkyModel.retarget(MockCompareWarpAssembleCoaddTask) 

183 self.assembleStaticSkyModel.doWrite = False 

184 self.doWrite = False 

185 self.effectiveWavelength = 476.31 # Use LSST g band values for the test. 

186 self.bandwidth = 552. - 405. 

187 

188 

189class MockDcrAssembleCoaddTask(MockAssembleCoaddTask, DcrAssembleCoaddTask): 

190 """Lightly modified version of `DcrAssembleCoaddTask` 

191 for use with unit tests. 

192 

193 The modifications bypass the usual middleware for loading data and setting 

194 up the Task, and instead supply in-memory mock data references to the `run` 

195 method so that the coaddition algorithms can be tested without a Butler. 

196 """ 

197 ConfigClass = MockDcrAssembleCoaddConfig 

198 _DefaultName = "dcrAssembleCoadd" 

199 

200 def __init__(self, *args, **kwargs): 

201 DcrAssembleCoaddTask.__init__(self, *args, **kwargs) 

202 

203 

204class AssembleCoaddTestCase(lsst.utils.tests.TestCase): 

205 """Tests of AssembleCoaddTask and its derived classes. 

206 

207 These tests bypass the middleware used for accessing data and managing Task 

208 execution. 

209 """ 

210 

211 def setUp(self): 

212 patch = 42 

213 patchGen2 = "2,3" 

214 tract = 0 

215 testData = MockCoaddTestData(fluxRange=1e4) 

216 exposures = {} 

217 matchedExposures = {} 

218 for expId in range(100, 110): 

219 exposures[expId], matchedExposures[expId] = testData.makeTestImage(expId) 

220 self.gen2DataRefList = testData.makeGen2DataRefList(exposures, matchedExposures, 

221 patch=patchGen2, tract=tract) 

222 self.dataRefList = testData.makeDataRefList(exposures, matchedExposures, 

223 'direct', patch=patch, tract=tract) 

224 self.dataRefListPsfMatched = testData.makeDataRefList(exposures, matchedExposures, 

225 'psfMatched', patch=patch, tract=tract) 

226 self.skyInfoGen2 = makeMockSkyInfo(testData.bbox, testData.wcs, patch=patchGen2) 

227 self.skyInfo = makeMockSkyInfo(testData.bbox, testData.wcs, patch=patch) 

228 

229 def checkGen2Gen3Compatibility(self, assembleTask, warpType="direct"): 

230 dataRefList = self.dataRefListPsfMatched if warpType == "psfMatched" else self.dataRefList 

231 resultsGen3 = assembleTask.runQuantum(self.skyInfo, dataRefList) 

232 resultsGen2 = assembleTask.runDataRef(self.skyInfoGen2, warpRefList=self.gen2DataRefList) 

233 coaddGen2 = resultsGen2.coaddExposure 

234 coaddGen3 = resultsGen3.coaddExposure 

235 self.assertFloatsEqual(coaddGen2.image.array, coaddGen3.image.array) 

236 

237 def testGen2Gen3Compatibility(self): 

238 config = MockAssembleCoaddConfig() 

239 config.validate() 

240 assembleTask = MockAssembleCoaddTask(config=config) 

241 self.checkGen2Gen3Compatibility(assembleTask) 

242 

243 def testPsfMatchedGen2Gen3Compatibility(self): 

244 config = MockAssembleCoaddConfig(warpType="psfMatched") 

245 config.validate() 

246 assembleTask = MockAssembleCoaddTask(config=config) 

247 self.checkGen2Gen3Compatibility(assembleTask, warpType="psfMatched") 

248 

249 def testSafeClipGen2Gen3Compatibility(self): 

250 config = MockSafeClipAssembleCoaddConfig() 

251 config.validate() 

252 assembleTask = MockSafeClipAssembleCoaddTask(config=config) 

253 self.checkGen2Gen3Compatibility(assembleTask) 

254 

255 def testCompareWarpGen2Gen3Compatibility(self): 

256 config = MockCompareWarpAssembleCoaddConfig() 

257 config.validate() 

258 assembleTask = MockCompareWarpAssembleCoaddTask(config=config) 

259 self.checkGen2Gen3Compatibility(assembleTask) 

260 

261 def testDcrGen2Gen3Compatibility(self): 

262 config = MockDcrAssembleCoaddConfig() 

263 config.validate() 

264 assembleTask = MockDcrAssembleCoaddTask(config=config) 

265 self.checkGen2Gen3Compatibility(assembleTask) 

266 

267 

268class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

269 pass 

270 

271 

272def setup_module(module): 

273 lsst.utils.tests.init() 

274 

275 

276if __name__ == "__main__": 276 ↛ 277line 276 didn't jump to line 277, because the condition on line 276 was never true

277 lsst.utils.tests.init() 

278 unittest.main()