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

87 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""" 

24import shutil 

25import tempfile 

26import unittest 

27 

28import lsst.utils.tests 

29import lsst.afw.image 

30import lsst.afw.math 

31import lsst.afw.table 

32import lsst.daf.butler.tests as butlerTests 

33from lsst.pipe.base import testUtils 

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

35 

36 

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

38 

39 @classmethod 

40 def _makeTestRepo(cls, root): 

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

42 """ 

43 # In-memory for performance 

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

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

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

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

48 

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

50 butler.registry.insertDimensionData( 

51 "instrument", 

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

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

54 butler.registry.insertDimensionData("detector", 

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

56 return butler 

57 

58 @classmethod 

59 def setUpClass(cls): 

60 super().setUpClass() 

61 

62 cls.root = tempfile.mkdtemp() 

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

64 

65 butlerTests.addDatasetType( 

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

67 "ExposureF") 

68 butlerTests.addDatasetType( 

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

70 "Background") 

71 butlerTests.addDatasetType( 

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

73 "SourceCatalog") 

74 butlerTests.addDatasetType( 

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

76 "SimpleCatalog") 

77 butlerTests.addDatasetType( 

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

79 "ExposureF") 

80 butlerTests.addDatasetType( 

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

82 "SourceCatalog") 

83 butlerTests.addDatasetType( 

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

85 "Background") 

86 butlerTests.addDatasetType( 

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

88 "Catalog") 

89 butlerTests.addDatasetType( 

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

91 "Catalog") 

92 

93 @classmethod 

94 def tearDownClass(cls): 

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

96 super().tearDownClass() 

97 

98 def setUp(self): 

99 super().setUp() 

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

101 

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

103 # CalibrateTask absolutely requires an ExpandedDataCoordinate 

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

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

106 

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

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

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

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

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

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

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

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

115 

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

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

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

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

120 

121 def testDoAstrometry(self): 

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

123 is set. 

124 """ 

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

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

127 "matches", "matchesDenormalized" 

128 }} 

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

130 

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

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

133 

134 def testDoPhotoCal(self): 

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

136 is set. 

137 """ 

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

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

140 "matches", "matchesDenormalized" 

141 }} 

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

143 

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

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

146 

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

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

149 

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

151 task configuration. 

152 

153 Parameters 

154 ---------- 

155 doAstrometry, doPhotoCal : `bool` 

156 Values of the config flags of the same name. 

157 ids : `dict` [`str`] 

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

159 dataset to process. 

160 """ 

161 config = CalibrateConfig() 

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

163 config.doAstrometry = doAstrometry 

164 config.doPhotoCal = doPhotoCal 

165 config.connections.photoRefCat = "cal_ref_cat" 

166 config.connections.astromRefCat = "cal_ref_cat" 

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()