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.doWrite = False 

135 

136 

137class MockSafeClipAssembleCoaddTask(MockAssembleCoaddTask, SafeClipAssembleCoaddTask): 

138 """Lightly modified version of `SafeClipAssembleCoaddTask` 

139 for use with unit tests. 

140 

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

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

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

144 """ 

145 ConfigClass = MockSafeClipAssembleCoaddConfig 

146 _DefaultName = "safeClipAssembleCoadd" 

147 

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

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

150 

151 

152class MockCompareWarpAssembleCoaddConfig(CompareWarpAssembleCoaddConfig): 

153 

154 def setDefaults(self): 

155 super().setDefaults() 

156 self.assembleStaticSkyModel.retarget(MockAssembleCoaddTask) 

157 self.assembleStaticSkyModel.doWrite = False 

158 self.doWrite = False 

159 

160 

161class MockCompareWarpAssembleCoaddTask(MockAssembleCoaddTask, CompareWarpAssembleCoaddTask): 

162 """Lightly modified version of `CompareWarpAssembleCoaddTask` 

163 for use with unit tests. 

164 

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

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

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

168 """ 

169 ConfigClass = MockCompareWarpAssembleCoaddConfig 

170 _DefaultName = "compareWarpAssembleCoadd" 

171 

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

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

174 

175 

176class MockDcrAssembleCoaddConfig(DcrAssembleCoaddConfig): 

177 

178 def setDefaults(self): 

179 super().setDefaults() 

180 self.assembleStaticSkyModel.retarget(MockCompareWarpAssembleCoaddTask) 

181 self.assembleStaticSkyModel.doWrite = False 

182 self.doWrite = False 

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

184 self.bandwidth = 552. - 405. 

185 

186 

187class MockDcrAssembleCoaddTask(MockAssembleCoaddTask, DcrAssembleCoaddTask): 

188 """Lightly modified version of `DcrAssembleCoaddTask` 

189 for use with unit tests. 

190 

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

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

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

194 """ 

195 ConfigClass = MockDcrAssembleCoaddConfig 

196 _DefaultName = "dcrAssembleCoadd" 

197 

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

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

200 

201 

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

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

204 

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

206 execution. 

207 """ 

208 

209 def setUp(self): 

210 patch = 42 

211 patchGen2 = "2,3" 

212 tract = 0 

213 testData = MockCoaddTestData(fluxRange=1e4) 

214 exposures = {} 

215 matchedExposures = {} 

216 for expId in range(100, 110): 

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

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

219 patch=patchGen2, tract=tract) 

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

221 'direct', patch=patch, tract=tract) 

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

223 'psfMatched', patch=patch, tract=tract) 

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

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

226 

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

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

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

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

231 coaddGen2 = resultsGen2.coaddExposure 

232 coaddGen3 = resultsGen3.coaddExposure 

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

234 

235 def testGen2Gen3Compatibility(self): 

236 config = MockAssembleCoaddConfig() 

237 config.validate() 

238 assembleTask = MockAssembleCoaddTask(config=config) 

239 self.checkGen2Gen3Compatibility(assembleTask) 

240 

241 def testPsfMatchedGen2Gen3Compatibility(self): 

242 config = MockAssembleCoaddConfig(warpType="psfMatched") 

243 config.validate() 

244 assembleTask = MockAssembleCoaddTask(config=config) 

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

246 

247 def testSafeClipGen2Gen3Compatibility(self): 

248 config = MockSafeClipAssembleCoaddConfig() 

249 config.validate() 

250 assembleTask = MockSafeClipAssembleCoaddTask(config=config) 

251 self.checkGen2Gen3Compatibility(assembleTask) 

252 

253 def testCompareWarpGen2Gen3Compatibility(self): 

254 config = MockCompareWarpAssembleCoaddConfig() 

255 config.validate() 

256 assembleTask = MockCompareWarpAssembleCoaddTask(config=config) 

257 self.checkGen2Gen3Compatibility(assembleTask) 

258 

259 def testDcrGen2Gen3Compatibility(self): 

260 config = MockDcrAssembleCoaddConfig() 

261 config.validate() 

262 assembleTask = MockDcrAssembleCoaddTask(config=config) 

263 self.checkGen2Gen3Compatibility(assembleTask) 

264 

265 

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

267 pass 

268 

269 

270def setup_module(module): 

271 lsst.utils.tests.init() 

272 

273 

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

275 lsst.utils.tests.init() 

276 unittest.main()