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