Coverage for tests/test_calibrate.py: 28%
88 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-21 02:32 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-21 02:32 -0800
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/>.
22"""Test ProcessCcdTask and its immediate subtasks.
23"""
24import shutil
25import tempfile
26import unittest
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
37class CalibrateTaskTestCaseWithButler(lsst.utils.tests.TestCase):
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:"
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(
54 "physical_filter",
55 {"instrument": "notACam", "name": "r", "band": "r"},
56 )
57 butler.registry.insertDimensionData(
58 "visit",
59 {"instrument": "notACam", "id": 101, "name": "101", "physical_filter": "r"},
60 )
61 butler.registry.insertDimensionData("detector",
62 {"instrument": "notACam", "id": 42, "full_name": "42"})
63 return butler
65 @classmethod
66 def setUpClass(cls):
67 super().setUpClass()
69 cls.root = tempfile.mkdtemp()
70 cls.repo = cls._makeTestRepo(cls.root)
72 butlerTests.addDatasetType(
73 cls.repo, "icExp", {"instrument", "visit", "detector"},
74 "ExposureF")
75 butlerTests.addDatasetType(
76 cls.repo, "icExpBackground", {"instrument", "visit", "detector"},
77 "Background")
78 butlerTests.addDatasetType(
79 cls.repo, "icSrc", {"instrument", "visit", "detector"},
80 "SourceCatalog")
81 butlerTests.addDatasetType(
82 cls.repo, "cal_ref_cat", {"htm7"},
83 "SimpleCatalog")
84 butlerTests.addDatasetType(
85 cls.repo, "calexp", {"instrument", "visit", "detector"},
86 "ExposureF")
87 butlerTests.addDatasetType(
88 cls.repo, "src", {"instrument", "visit", "detector"},
89 "SourceCatalog")
90 butlerTests.addDatasetType(
91 cls.repo, "calexpBackground", {"instrument", "visit", "detector"},
92 "Background")
93 butlerTests.addDatasetType(
94 cls.repo, "srcMatch", {"instrument", "visit", "detector"},
95 "Catalog")
96 butlerTests.addDatasetType(
97 cls.repo, "srcMatchFull", {"instrument", "visit", "detector"},
98 "Catalog")
100 @classmethod
101 def tearDownClass(cls):
102 shutil.rmtree(cls.root, ignore_errors=True)
103 super().tearDownClass()
105 def setUp(self):
106 super().setUp()
107 self.butler = butlerTests.makeTestCollection(self.repo)
109 self.dataId = {"instrument": "notACam", "visit": 101, "detector": 42}
110 # CalibrateTask absolutely requires an ExpandedDataCoordinate
111 self.dataId = self.butler.registry.expandDataId(self.dataId)
112 self.refcatId = {"htm7": 189584}
114 # Tests do no processing, so we don't need real data
115 self.exposure = lsst.afw.image.ExposureF(10, 10)
116 background = lsst.afw.math.BackgroundMI(self.exposure.getBBox(), self.exposure.getMaskedImage())
117 self.backgroundlist = lsst.afw.math.BackgroundList(
118 (background, lsst.afw.math.Interpolate.UNKNOWN, lsst.afw.math.UndersampleStyle.THROW_EXCEPTION,
119 lsst.afw.math.ApproximateControl.UNKNOWN, 0, 0, 1))
120 self.icSrc = lsst.afw.table.SourceCatalog()
121 self.refcat = lsst.afw.table.SimpleCatalog()
123 self.butler.put(self.exposure, "icExp", self.dataId)
124 self.butler.put(self.backgroundlist, "icExpBackground", self.dataId)
125 self.butler.put(self.icSrc, "icSrc", self.dataId)
126 self.butler.put(self.refcat, "cal_ref_cat", self.refcatId)
128 def testDoAstrometry(self):
129 """Ensure correct inputs passed to run whether or not doAstrometry
130 is set.
131 """
132 allIds = {key: self.dataId for key in {
133 "exposure", "background", "icSourceCat", "outputExposure", "outputCat", "outputBackground",
134 "matches", "matchesDenormalized"
135 }}
136 allIds.update({key: [self.refcatId] for key in {"astromRefCat", "photoRefCat"}})
138 self._checkDoRefcats(doAstrometry=True, doPhotoCal=True, ids=allIds)
139 self._checkDoRefcats(doAstrometry=False, doPhotoCal=True, ids=allIds)
141 def testDoPhotoCal(self):
142 """Ensure correct inputs passed to run whether or not doPhotoCal
143 is set.
144 """
145 allIds = {key: self.dataId for key in {
146 "exposure", "background", "icSourceCat", "outputExposure", "outputCat", "outputBackground",
147 "matches", "matchesDenormalized"
148 }}
149 allIds.update({key: [self.refcatId] for key in {"astromRefCat", "photoRefCat"}})
151 self._checkDoRefcats(doAstrometry=True, doPhotoCal=True, ids=allIds)
152 self._checkDoRefcats(doAstrometry=True, doPhotoCal=False, ids=allIds)
154 def _checkDoRefcats(self, doAstrometry, doPhotoCal, ids):
155 """Test whether run is called with the correct arguments.
157 In the case of `CalibrateTask`, the inputs should not depend on the
158 task configuration.
160 Parameters
161 ----------
162 doAstrometry, doPhotoCal : `bool`
163 Values of the config flags of the same name.
164 ids : `dict` [`str`]
165 A mapping from the input dataset type to the data ID of the
166 dataset to process.
167 """
168 config = CalibrateConfig()
169 config.doWriteMatches = False # no real output to write
170 config.doAstrometry = doAstrometry
171 config.doPhotoCal = doPhotoCal
172 config.connections.photoRefCat = "cal_ref_cat"
173 config.connections.astromRefCat = "cal_ref_cat"
174 task = CalibrateTask(config=config)
175 quantumId = ids["exposure"]
177 quantum = testUtils.makeQuantum(task, self.butler, quantumId, ids)
178 run = testUtils.runTestQuantum(task, self.butler, quantum)
180 run.assert_called_once()
181 self.assertEqual(run.call_args[0], ())
182 # Some arguments unprintable because we don't have a full environment
183 # So just check which ones were passed in
184 self.assertEqual(run.call_args[1].keys(),
185 {"exposure", "exposureIdInfo", "background", "icSourceCat"})
188def setup_module(module):
189 lsst.utils.tests.init()
192class MemoryTestCase(lsst.utils.tests.MemoryTestCase):
193 pass
196if __name__ == "__main__": 196 ↛ 197line 196 didn't jump to line 197, because the condition on line 196 was never true
197 lsst.utils.tests.init()
198 unittest.main()