Coverage for tests / test_metrics.py: 21%
88 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-06 09:07 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-06 09:07 +0000
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 <http://www.gnu.org/licenses/>.
21from __future__ import annotations
23from unittest import TestCase, main
25import numpy as np
27import lsst.utils.tests
28from lsst.analysis.tools.actions.vector import ConstantValue, MultiplyVector
29from lsst.analysis.tools.atools import (
30 MagnitudeTool,
31 MatchedRefCoaddCompurityTool,
32 MatchedRefCoaddDiffColorTool,
33 MatchedRefCoaddDiffDistanceTool,
34 MatchedRefCoaddDiffMagTool,
35 MatchedRefCoaddDiffPositionTool,
36 MatchedRefCoaddDiffTool,
37)
40class MatchedRefCoaddDiffToolMinimal(MatchedRefCoaddDiffTool):
41 """A bare-minimum implementation of a diff tool."""
43 def get_key_flux_y(self) -> str:
44 return self.mag_x
46 def finalize(self):
47 if not hasattr(self.process.buildActions, "diff"):
48 super().finalize()
49 self._set_actions()
51 self.process.buildActions.diff = MultiplyVector(
52 actionA=getattr(self.process.buildActions, f"mag_{self.mag_x}"),
53 actionB=ConstantValue(value=0.001),
54 )
57class TestDiffMatched(TestCase):
58 def setUp(self) -> None:
59 super().setUp()
60 self.band_default = "analysisTools"
62 def _testMatchedRefCoaddMetricDerived(
63 self,
64 type_metric: type[MatchedRefCoaddCompurityTool | MatchedRefCoaddDiffColorTool],
65 suffixes_configure: list[str] | None = None,
66 **kwargs,
67 ):
68 if suffixes_configure is None:
69 suffixes_configure = [""]
70 plotInfo = {key: "" for key in ("plotName", "run", "tableName")}
71 plotInfo["bands"] = []
73 tester = type_metric(**kwargs)
74 has_compute_chi = hasattr(tester, "compute_chi")
75 has_configureMetrics = hasattr(tester, "configureMetrics")
77 for compute_chi in (False, True) if has_compute_chi else (None,):
78 if has_compute_chi:
79 tester.compute_chi = compute_chi
80 # tester.getInputSchema won't work properly before finalizing
81 tester.finalize()
82 keys = list({k[0]: None for k in tester.getInputSchema()})
83 self.assertGreater(len(keys), 0)
84 if has_configureMetrics:
85 for suffix in suffixes_configure:
86 self.assertGreater(len(list(tester.configureMetrics(attr_suffix=suffix))), 0)
87 data = {}
88 n_data = 10
89 for key in keys:
90 if key.endswith("is_pointsource"):
91 values = (np.arange(0, n_data) % 2) == 1
92 else:
93 values = np.linspace(0.1, 15.0, n_data)
94 data[key.format(band=self.band_default)] = values
96 output = tester(data, skymap=None, plotInfo=plotInfo)
97 self.assertGreater(len(output), 0)
98 if has_compute_chi:
99 tester = type_metric(**kwargs)
101 def testMatchedRefCoaddMetric(self):
102 kwargs = {key: "" for key in ("unit", "name_prefix")}
103 # The metric can now be set up with default kwargs
104 # Pass one at a time to test
105 for kwarg in kwargs:
106 kwargs_init = {kwarg: ""}
107 tester = MatchedRefCoaddDiffToolMinimal(**kwargs_init)
108 tester.validate()
109 with self.assertRaises(KeyError):
110 tester.configureMetrics()
111 tester.finalize()
112 tester.configureMetrics()
113 # Failing to find any of the required keys
114 with self.assertRaises(KeyError):
115 tester({})
116 tester = MatchedRefCoaddDiffToolMinimal(**kwargs)
117 tester.validate()
118 with self.assertRaises(KeyError):
119 tester.configureMetrics()
120 tester.finalize()
121 inputs = list(tester.getInputSchema())
122 n_input = len(inputs)
123 self.assertGreater(n_input, 0)
124 self.assertGreater(len(list(tester.configureMetrics())), 0)
126 self.assertEqual(len(inputs), n_input)
127 data = {key.format(band="analysisTools"): np.array([0.0]) for key, *_ in inputs}
128 # There's no metric or plot so it just returns an empty dict
129 self.assertEqual(len(tester(data)), 0)
131 def testMatchedRefCoaddCompurity(self):
132 self._testMatchedRefCoaddMetricDerived(
133 MatchedRefCoaddCompurityTool,
134 )
136 def testMatchedRefCoaddDiffColor(self):
137 self._testMatchedRefCoaddMetricDerived(
138 MatchedRefCoaddDiffColorTool,
139 suffixes_configure=["_0", "_1"],
140 fluxes={"cmodel": MagnitudeTool.fluxes_default.cmodel_err},
141 mag_y1="cmodel_err",
142 mag_y2="cmodel_err",
143 bands={
144 "g": "i",
145 "u": "z",
146 },
147 name_prefix="",
148 unit="",
149 )
151 def testMatchedRefCoaddDiffDistance(self):
152 self._testMatchedRefCoaddMetricDerived(
153 MatchedRefCoaddDiffDistanceTool,
154 )
156 def testMatchedRefCoaddDiffMag(self):
157 self._testMatchedRefCoaddMetricDerived(
158 MatchedRefCoaddDiffMagTool,
159 fluxes={"cmodel": MagnitudeTool.fluxes_default.cmodel_err},
160 mag_y="cmodel",
161 name_prefix="",
162 unit="",
163 )
165 def testMatchedRefCoaddDiffPosition(self):
166 for variable in ("x", "y"):
167 self._testMatchedRefCoaddMetricDerived(
168 MatchedRefCoaddDiffPositionTool,
169 coord_meas=variable,
170 coord_ref=variable,
171 )
174class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
175 pass
178def setup_module(module):
179 lsst.utils.tests.init()
182if __name__ == "__main__": 182 ↛ 183line 182 didn't jump to line 183 because the condition on line 182 was never true
183 lsst.utils.tests.init()
184 main()