Coverage for tests/test_calibrate.py: 31%

Shortcuts 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

85 statements  

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"""Test ProcessCcdTask and its immediate subtasks. 

23 

24Run the task on one obs_test image and perform various checks on the results 

25""" 

26import shutil 

27import tempfile 

28import unittest 

29 

30import lsst.utils.tests 

31import lsst.afw.image 

32import lsst.afw.math 

33import lsst.afw.table 

34import lsst.daf.butler.tests as butlerTests 

35from lsst.pipe.base import testUtils 

36from lsst.pipe.tasks.calibrate import CalibrateTask, CalibrateConfig 

37 

38 

39class CalibrateTaskTestCaseWithButler(lsst.utils.tests.TestCase): 

40 

41 @classmethod 

42 def _makeTestRepo(cls, root): 

43 """Create a repository with the metadata assumed by CalibrateTask. 

44 """ 

45 # In-memory for performance 

46 config = lsst.daf.butler.Config() 

47 config["datastore", "cls"] = "lsst.daf.butler.datastores.inMemoryDatastore.InMemoryDatastore" 

48 config["datastore", "checksum"] = False 

49 config["registry", "db"] = "sqlite:///:memory:" 

50 

51 butler = lsst.daf.butler.Butler(lsst.daf.butler.Butler.makeRepo(root, config=config), writeable=True) 

52 butler.registry.insertDimensionData( 

53 "instrument", 

54 {"name": "notACam", "visit_max": 256, "exposure_max": 256, "detector_max": 64}) 

55 butler.registry.insertDimensionData("visit", {"instrument": "notACam", "id": 101, "name": "101"}) 

56 butler.registry.insertDimensionData("detector", 

57 {"instrument": "notACam", "id": 42, "full_name": "42"}) 

58 return butler 

59 

60 @classmethod 

61 def setUpClass(cls): 

62 super().setUpClass() 

63 

64 cls.root = tempfile.mkdtemp() 

65 cls.repo = cls._makeTestRepo(cls.root) 

66 

67 butlerTests.addDatasetType( 

68 cls.repo, "icExp", {"instrument", "visit", "detector"}, 

69 "ExposureF") 

70 butlerTests.addDatasetType( 

71 cls.repo, "icExpBackground", {"instrument", "visit", "detector"}, 

72 "Background") 

73 butlerTests.addDatasetType( 

74 cls.repo, "icSrc", {"instrument", "visit", "detector"}, 

75 "SourceCatalog") 

76 butlerTests.addDatasetType( 

77 cls.repo, "cal_ref_cat", {"htm7"}, 

78 "SimpleCatalog") 

79 butlerTests.addDatasetType( 

80 cls.repo, "calexp", {"instrument", "visit", "detector"}, 

81 "ExposureF") 

82 butlerTests.addDatasetType( 

83 cls.repo, "src", {"instrument", "visit", "detector"}, 

84 "SourceCatalog") 

85 butlerTests.addDatasetType( 

86 cls.repo, "calexpBackground", {"instrument", "visit", "detector"}, 

87 "Background") 

88 butlerTests.addDatasetType( 

89 cls.repo, "srcMatch", {"instrument", "visit", "detector"}, 

90 "Catalog") 

91 butlerTests.addDatasetType( 

92 cls.repo, "srcMatchFull", {"instrument", "visit", "detector"}, 

93 "Catalog") 

94 

95 @classmethod 

96 def tearDownClass(cls): 

97 shutil.rmtree(cls.root, ignore_errors=True) 

98 super().tearDownClass() 

99 

100 def setUp(self): 

101 super().setUp() 

102 self.butler = butlerTests.makeTestCollection(self.repo) 

103 

104 self.dataId = {"instrument": "notACam", "visit": 101, "detector": 42} 

105 # CalibrateTask absolutely requires an ExpandedDataCoordinate 

106 self.dataId = self.butler.registry.expandDataId(self.dataId) 

107 self.refcatId = {"htm7": 189584} 

108 

109 # Tests do no processing, so we don't need real data 

110 self.exposure = lsst.afw.image.ExposureF(10, 10) 

111 background = lsst.afw.math.BackgroundMI(self.exposure.getBBox(), self.exposure.getMaskedImage()) 

112 self.backgroundlist = lsst.afw.math.BackgroundList( 

113 (background, lsst.afw.math.Interpolate.UNKNOWN, lsst.afw.math.UndersampleStyle.THROW_EXCEPTION, 

114 lsst.afw.math.ApproximateControl.UNKNOWN, 0, 0, 1)) 

115 self.icSrc = lsst.afw.table.SourceCatalog() 

116 self.refcat = lsst.afw.table.SimpleCatalog() 

117 

118 self.butler.put(self.exposure, "icExp", self.dataId) 

119 self.butler.put(self.backgroundlist, "icExpBackground", self.dataId) 

120 self.butler.put(self.icSrc, "icSrc", self.dataId) 

121 self.butler.put(self.refcat, "cal_ref_cat", self.refcatId) 

122 

123 def testDoAstrometry(self): 

124 """Ensure correct inputs passed to run whether or not doAstrometry 

125 is set. 

126 """ 

127 allIds = {key: self.dataId for key in { 

128 "exposure", "background", "icSourceCat", "outputExposure", "outputCat", "outputBackground", 

129 "matches", "matchesDenormalized" 

130 }} 

131 allIds.update({key: [self.refcatId] for key in {"astromRefCat", "photoRefCat"}}) 

132 

133 self._checkDoRefcats(doAstrometry=True, doPhotoCal=True, ids=allIds) 

134 self._checkDoRefcats(doAstrometry=False, doPhotoCal=True, ids=allIds) 

135 

136 def testDoPhotoCal(self): 

137 """Ensure correct inputs passed to run whether or not doPhotoCal 

138 is set. 

139 """ 

140 allIds = {key: self.dataId for key in { 

141 "exposure", "background", "icSourceCat", "outputExposure", "outputCat", "outputBackground", 

142 "matches", "matchesDenormalized" 

143 }} 

144 allIds.update({key: [self.refcatId] for key in {"astromRefCat", "photoRefCat"}}) 

145 

146 self._checkDoRefcats(doAstrometry=True, doPhotoCal=True, ids=allIds) 

147 self._checkDoRefcats(doAstrometry=True, doPhotoCal=False, ids=allIds) 

148 

149 def _checkDoRefcats(self, doAstrometry, doPhotoCal, ids): 

150 """Test whether run is called with the correct arguments. 

151 

152 In the case of `CalibrateTask`, the inputs should not depend on the 

153 task configuration. 

154 

155 Parameters 

156 ---------- 

157 doAstrometry, doPhotoCal : `bool` 

158 Values of the config flags of the same name. 

159 ids : `dict` [`str`] 

160 A mapping from the input dataset type to the data ID of the 

161 dataset to process. 

162 """ 

163 config = CalibrateConfig() 

164 config.doWriteMatches = False # no real output to write 

165 config.doAstrometry = doAstrometry 

166 config.doPhotoCal = doPhotoCal 

167 task = CalibrateTask(config=config) 

168 quantumId = ids["exposure"] 

169 

170 quantum = testUtils.makeQuantum(task, self.butler, quantumId, ids) 

171 run = testUtils.runTestQuantum(task, self.butler, quantum) 

172 

173 run.assert_called_once() 

174 self.assertEqual(run.call_args[0], ()) 

175 # Some arguments unprintable because we don't have a full environment 

176 # So just check which ones were passed in 

177 self.assertEqual(run.call_args[1].keys(), 

178 {"exposure", "exposureIdInfo", "background", "icSourceCat"}) 

179 

180 

181def setup_module(module): 

182 lsst.utils.tests.init() 

183 

184 

185class MemoryTestCase(lsst.utils.tests.MemoryTestCase): 

186 pass 

187 

188 

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

190 lsst.utils.tests.init() 

191 unittest.main()