Coverage for tests/test_verifyToSasquatch.py: 21%
128 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-26 04:07 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-26 04:07 -0700
1# This file is part of analysis_tools.
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/>.
22import argparse
23import tempfile
24import unittest
26import astropy.units as u
27import lsst.daf.butler.tests as butlerTests
28from lsst.analysis.tools.bin.verifyToSasquatch import _AppendDict, _bundle_metrics
29from lsst.analysis.tools.interfaces import MetricMeasurementBundle
30from lsst.daf.butler import CollectionType, DataCoordinate
31from lsst.verify import Measurement
34class VerifyToSasquatchTestSuite(unittest.TestCase):
35 def setUp(self):
36 super().setUp()
38 repo = tempfile.TemporaryDirectory()
39 # TemporaryDirectory warns on leaks; addCleanup also keeps the TD from
40 # getting garbage-collected.
41 self.addCleanup(tempfile.TemporaryDirectory.cleanup, repo)
42 self.butler = butlerTests.makeTestRepo(repo.name)
44 butlerTests.addDataIdValue(self.butler, "instrument", "notACam")
45 for visit in [42, 43]:
46 butlerTests.addDataIdValue(self.butler, "visit", visit)
47 for detector in range(4):
48 butlerTests.addDataIdValue(self.butler, "detector", detector)
49 butlerTests.addDatasetType(
50 self.butler,
51 "metricvalue_nopackage_fancyMetric",
52 {"instrument", "visit", "detector"},
53 "MetricValue",
54 )
55 butlerTests.addDatasetType(
56 self.butler,
57 "metricvalue_nopackage_fancierMetric",
58 {"instrument", "visit", "detector"},
59 "MetricValue",
60 )
61 butlerTests.addDatasetType(
62 self.butler, "metricvalue_nopackage_plainMetric", {"instrument"}, "MetricValue"
63 )
64 self.butler.registry.registerCollection("run1", CollectionType.RUN)
65 self.butler.registry.registerCollection("run2", CollectionType.RUN)
67 def _standardize(self, dataId):
68 """Convert an arbitrary data ID to a DataCoordinate."""
69 return DataCoordinate.standardize(dataId, universe=self.butler.dimensions)
71 def test_bundle_metrics_nometrics(self):
72 refs = self.butler.registry.queryDatasets("metricvalue_nopackage_*", collections=...)
73 bundles = _bundle_metrics(self.butler, refs)
74 # MetricMeasurementBundle.equals ignores metadata
75 self.assertDictEqual(bundles, {})
77 def test_bundle_metrics_onemetric(self):
78 m = Measurement("nopackage.fancyMetric", 42.2 * u.s)
79 self.butler.put(
80 m, "metricvalue_nopackage_fancyMetric", run="run1", instrument="notACam", visit=42, detector=2
81 )
82 refs = self.butler.registry.queryDatasets("metricvalue_nopackage_fancyMetric", collections=...)
83 bundles = _bundle_metrics(self.butler, refs)
84 # MetricMeasurementBundle.equals ignores metadata
85 self.assertDictEqual(
86 bundles,
87 {
88 (
89 "run1",
90 "metricvalue_nopackage_fancyMetric",
91 self._standardize({"instrument": "notACam", "visit": 42, "detector": 2}),
92 ): MetricMeasurementBundle({"fancyMetric": [Measurement(m.metric_name.metric, m.quantity)]}),
93 },
94 )
96 def test_bundle_metrics_onemetrictwice(self):
97 m2 = Measurement("nopackage.fancyMetric", 42.2 * u.s)
98 self.butler.put(
99 m2, "metricvalue_nopackage_fancyMetric", run="run1", instrument="notACam", visit=42, detector=2
100 )
101 m1 = Measurement("nopackage.fancyMetric", 43.1 * u.m)
102 self.butler.put(
103 m1, "metricvalue_nopackage_fancyMetric", run="run1", instrument="notACam", visit=43, detector=1
104 )
105 refs = self.butler.registry.queryDatasets("metricvalue_nopackage_fancyMetric", collections=...)
106 bundles = _bundle_metrics(self.butler, refs)
107 # MetricMeasurementBundle.equals ignores metadata
108 self.assertDictEqual(
109 bundles,
110 {
111 (
112 "run1",
113 "metricvalue_nopackage_fancyMetric",
114 self._standardize({"instrument": "notACam", "visit": 42, "detector": 2}),
115 ): MetricMeasurementBundle(
116 {"fancyMetric": [Measurement(m2.metric_name.metric, m2.quantity)]}
117 ),
118 (
119 "run1",
120 "metricvalue_nopackage_fancyMetric",
121 self._standardize({"instrument": "notACam", "visit": 43, "detector": 1}),
122 ): MetricMeasurementBundle(
123 {"fancyMetric": [Measurement(m1.metric_name.metric, m1.quantity)]}
124 ),
125 },
126 )
128 def test_bundle_metrics_threemetrics(self):
129 m2 = Measurement("nopackage.fancyMetric", 42.2 * u.s)
130 self.butler.put(
131 m2, "metricvalue_nopackage_fancyMetric", run="run1", instrument="notACam", visit=42, detector=2
132 )
133 m1 = Measurement("nopackage.fancierMetric", 43.1 * u.m)
134 self.butler.put(
135 m1, "metricvalue_nopackage_fancierMetric", run="run2", instrument="notACam", visit=43, detector=1
136 )
137 m_ = Measurement("nopackage.plainMetric", 127.0 * u.kg)
138 self.butler.put(m_, "metricvalue_nopackage_plainMetric", run="run1", instrument="notACam")
139 refs = self.butler.registry.queryDatasets("metricvalue_nopackage_*", collections=...)
140 bundles = _bundle_metrics(self.butler, refs)
141 # MetricMeasurementBundle.equals ignores metadata
142 self.assertDictEqual(
143 bundles,
144 {
145 (
146 "run1",
147 "metricvalue_nopackage_fancyMetric",
148 self._standardize({"instrument": "notACam", "visit": 42, "detector": 2}),
149 ): MetricMeasurementBundle(
150 {"fancyMetric": [Measurement(m2.metric_name.metric, m2.quantity)]}
151 ),
152 (
153 "run2",
154 "metricvalue_nopackage_fancierMetric",
155 self._standardize({"instrument": "notACam", "visit": 43, "detector": 1}),
156 ): MetricMeasurementBundle(
157 {"fancierMetric": [Measurement(m1.metric_name.metric, m1.quantity)]}
158 ),
159 (
160 "run1",
161 "metricvalue_nopackage_plainMetric",
162 self._standardize({"instrument": "notACam"}),
163 ): MetricMeasurementBundle(
164 {"plainMetric": [Measurement(m_.metric_name.metric, m_.quantity)]}
165 ),
166 },
167 )
169 def test_bundle_metrics_badmetric(self):
170 butlerTests.addDatasetType(
171 self.butler, "metricvalue_nopackage_notAMetric", {"instrument", "visit"}, "StructuredDataDict"
172 )
173 self.butler.put(
174 {"foo": "bar"}, "metricvalue_nopackage_notAMetric", run="run1", instrument="notACam", visit=42
175 )
176 refs = self.butler.registry.queryDatasets("metricvalue_nopackage_notAMetric", collections=...)
177 with self.assertRaises(ValueError):
178 _bundle_metrics(self.butler, refs)
181class AppendDictTestSuite(unittest.TestCase):
182 def setUp(self):
183 super().setUp()
185 self.testbed = argparse.ArgumentParser()
187 def test_default_none_positional(self):
188 self.testbed.add_argument("test", action=_AppendDict, nargs="*")
190 namespace = self.testbed.parse_args([])
191 self.assertEqual(namespace.test, {})
193 namespace = self.testbed.parse_args("baz=bak".split())
194 self.assertEqual(namespace.test, {"baz": "bak"})
196 def test_default_none_keyword(self):
197 self.testbed.add_argument("--test", action=_AppendDict)
199 namespace = self.testbed.parse_args([])
200 self.assertEqual(namespace.test, {})
202 namespace = self.testbed.parse_args("--test baz=bak".split())
203 self.assertEqual(namespace.test, {"baz": "bak"})
205 def test_default_empty_positional(self):
206 self.testbed.add_argument("test", action=_AppendDict, default={}, nargs="*")
208 namespace = self.testbed.parse_args([])
209 self.assertEqual(namespace.test, {})
211 namespace = self.testbed.parse_args("baz=bak".split())
212 self.assertEqual(namespace.test, {"baz": "bak"})
214 def test_default_empty_keyword(self):
215 self.testbed.add_argument("--test", action=_AppendDict, default={})
217 namespace = self.testbed.parse_args([])
218 self.assertEqual(namespace.test, {})
220 namespace = self.testbed.parse_args("--test baz=bak".split())
221 self.assertEqual(namespace.test, {"baz": "bak"})
223 def test_default_non_empty_positional(self):
224 self.testbed.add_argument("test", action=_AppendDict, default={"foo": "bar"}, nargs="*")
226 namespace = self.testbed.parse_args([])
227 self.assertEqual(namespace.test, {"foo": "bar"})
229 namespace = self.testbed.parse_args("baz=bak".split())
230 self.assertEqual(namespace.test, {"foo": "bar", "baz": "bak"})
232 namespace = self.testbed.parse_args("foo=fum".split())
233 self.assertEqual(namespace.test, {"foo": "fum"})
235 def test_default_non_empty_keyword(self):
236 self.testbed.add_argument("--test", action=_AppendDict, default={"foo": "bar"})
238 namespace = self.testbed.parse_args([])
239 self.assertEqual(namespace.test, {"foo": "bar"})
241 namespace = self.testbed.parse_args("--test baz=bak".split())
242 self.assertEqual(namespace.test, {"foo": "bar", "baz": "bak"})
244 namespace = self.testbed.parse_args("--test foo=fum".split())
245 self.assertEqual(namespace.test, {"foo": "fum"})
247 def test_default_invalid(self):
248 with self.assertRaises(TypeError):
249 self.testbed.add_argument("test", action=_AppendDict, default="bovine")
250 with self.assertRaises(TypeError):
251 self.testbed.add_argument("test", action=_AppendDict, default=[])
253 def test_multi_append(self):
254 self.testbed.add_argument("--test", action=_AppendDict)
256 namespace = self.testbed.parse_args("--test foo=bar --test baz=bak".split())
257 self.assertEqual(namespace.test, {"foo": "bar", "baz": "bak"})
259 def test_multi_nargs_append(self):
260 self.testbed.add_argument("--test", action=_AppendDict, nargs="*")
262 namespace = self.testbed.parse_args("--test foo=bar fee=fum --test baz=bak --test".split())
263 self.assertEqual(namespace.test, {"foo": "bar", "fee": "fum", "baz": "bak"})
265 def test_emptyvalue(self):
266 self.testbed.add_argument("test", action=_AppendDict)
268 namespace = self.testbed.parse_args("foo=".split())
269 self.assertEqual(namespace.test, {"foo": ""})
271 def test_nopair(self):
272 self.testbed.add_argument("test", action=_AppendDict)
274 with self.assertRaises(ValueError):
275 self.testbed.parse_args("foo".split())
277 with self.assertRaises(ValueError):
278 self.testbed.parse_args("assertion=beauty=truth".split())