Coverage for python / lsst / analysis / tools / atools / diaFakeMetrics.py: 57%
69 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-25 08:54 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-25 08:54 +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 <https://www.gnu.org/licenses/>.
21from __future__ import annotations
23__all__ = (
24 "FractionFoundFakesDiaSnrMetric",
25 "FractionFoundFakesDiaMagMetric",
26 "FractionFoundFakesAssocDiaSnrMetric",
27 "FractionFoundFakesAssocDiaMagMetric",
28)
30import numpy as np
32from lsst.pex.config import Field, ListField
34from ..actions.scalar import CountAction, FracThreshold
35from ..actions.vector import FlagSelector, MultiCriteriaDownselectVector, RangeSelector
36from ..interfaces import AnalysisTool
39class FractionFoundFakesDiaSnrMetric(AnalysisTool):
40 """Calculate the fraction of fake DIA Sources found within the
41 given SNR range"""
43 parameterizedBand: bool = False
45 snrMin = Field[float](doc="Minimum SNR for fake sources metric calculation.", default=0)
47 snrMax = Field[float](doc="Maximum SNR for fake sources metric calculation.", default=np.inf)
49 fluxType = Field[str](
50 "Flux type for fake sources metric calculation.", default="forced_base_PsfFlux_instFlux"
51 )
53 fakeFlagsWhenTrue = ListField[str](
54 "Flags for fake source cleaning before metrics calculation. Select sources when flags are true.",
55 default=[],
56 )
58 fakeFlagsWhenFalse = ListField[str](
59 "Flags for fake source cleaning before metrics calculation. Select sources when flags are false.",
60 default=[
61 "forced_base_PixelFlags_flag_bad",
62 "forced_base_LocalBackground_flag",
63 "forced_base_PixelFlags_flag_interpolated",
64 "forced_base_PixelFlags_flag_edgeCenter",
65 ],
66 )
68 def setDefaults(self):
69 super().setDefaults()
71 def finalize(self):
72 # There is no need to calculate the SNR as it is already estimated
73 # Select the fake sources using their SNR values for the given range
74 # and flux type estimation
75 self.process.filterActions.fakeSourcesDiaSrcId = MultiCriteriaDownselectVector(
76 vectorKey="diaSourceId"
77 )
79 self.process.filterActions.fakeSourcesDiaSrcId.selectors.snrange = RangeSelector(
80 vectorKey=f"{self.fluxType}_SNR", maximum=self.snrMax, minimum=self.snrMin
81 )
83 self.process.filterActions.fakeSourcesDiaSrcId.selectors.fakeFlags = FlagSelector(
84 selectWhenFalse=self.fakeFlagsWhenFalse, selectWhenTrue=self.fakeFlagsWhenTrue
85 )
87 self.process.calculateActions.numTotalFakeSources = CountAction(vectorKey="fakeSourcesDiaSrcId")
89 self.process.calculateActions.numFoundFakeSources = CountAction(
90 vectorKey="fakeSourcesDiaSrcId", op="gt", threshold=0
91 )
93 self.process.calculateActions.fractionFoundFakesDiaAll = FracThreshold(
94 vectorKey="fakeSourcesDiaSrcId", op="gt", threshold=0
95 )
97 # the units for the quantity (count, an astropy quantity)
98 self.produce.metric.units = {
99 "numTotalFakeSources": "ct",
100 "numFoundFakeSources": "ct",
101 "fractionFoundFakesDiaAll": "",
102 }
105class FractionFoundFakesDiaMagMetric(AnalysisTool):
106 """Calculate the fraction of fake DIA Sources found within the given
107 magnitude range"""
109 parameterizedBand: bool = False
111 magMin = Field[float](doc="Minimum magnitude for fake sources metric calculation.", default=18)
113 magMax = Field[float](doc="Maximum magnitude for fake sources metric calculation.", default=22)
115 fakeFlagsWhenTrue = ListField[str](
116 "Flags for fake source cleaning before metrics calculation.. Select sources when flags are true.",
117 default=[],
118 )
120 fakeFlagsWhenFalse = ListField[str](
121 "Flags for fake source cleaning before metrics calculation. Select sources when flags are false.",
122 default=[
123 "forced_base_PixelFlags_flag_interpolated",
124 "forced_base_LocalBackground_flag",
125 "forced_base_PixelFlags_flag_bad",
126 "forced_base_PixelFlags_flag_edgeCenter",
127 ],
128 )
130 def finalize(self):
131 # Selecting the fake sources using the truth magnitude values.
132 self.process.filterActions.fakeSourcesDiaSrcId = MultiCriteriaDownselectVector(
133 vectorKey="diaSourceId"
134 )
136 self.process.filterActions.fakeSourcesDiaSrcId.selectors.magrange = RangeSelector(
137 vectorKey="mag", maximum=self.magMax, minimum=self.magMin
138 )
140 self.process.filterActions.fakeSourcesDiaSrcId.selectors.fakeFlags = FlagSelector(
141 selectWhenFalse=self.fakeFlagsWhenFalse, selectWhenTrue=self.fakeFlagsWhenTrue
142 )
144 self.process.calculateActions.numTotalFakeSources = CountAction(vectorKey="fakeSourcesDiaSrcId")
146 self.process.calculateActions.numFoundFakeSources = CountAction(
147 vectorKey="fakeSourcesDiaSrcId", op="gt", threshold=0
148 )
150 self.process.calculateActions.fractionFoundFakesDiaAll = FracThreshold(
151 vectorKey="fakeSourcesDiaSrcId", op="gt", threshold=0
152 )
154 # the units for the quantity (count, an astropy quantity)
155 self.produce.metric.units = {
156 "numTotalFakeSources": "ct",
157 "numFoundFakeSources": "ct",
158 "fractionFoundFakesDiaAll": "",
159 }
162class FractionFoundFakesAssocDiaSnrMetric(AnalysisTool):
163 """Calculate the fraction of fake DIA Sources found within the
164 given SNR range"""
166 parameterizedBand: bool = False
168 snrMin = Field[float](doc="Minimum SNR for fake sources metric calculation.", default=0)
170 snrMax = Field[float](doc="Maximum SNR for fake sources metric calculation.", default=np.inf)
172 fluxType = Field[str](
173 "Flux type for fake sources metric calculation.", default="forced_base_PsfFlux_instFlux"
174 )
176 fakeFlagsWhenTrue = ListField[str](
177 "Flags for fake source cleaning before metrics calculation. Select sources when flags are true.",
178 default=[],
179 )
181 fakeFlagsWhenFalse = ListField[str](
182 "Flags for fake source cleaning before metrics calculation. Select sources when flags are false.",
183 default=[
184 "forced_base_PixelFlags_flag_bad",
185 "forced_base_LocalBackground_flag",
186 "forced_base_PixelFlags_flag_interpolated",
187 "forced_base_PixelFlags_flag_edgeCenter",
188 ],
189 )
191 def setDefaults(self):
192 super().setDefaults()
194 def finalize(self):
195 # There is no need to calculate the SNR as it is already estimated
196 # Select the fake sources using their SNR values for the given range
197 # and flux type estimation
199 self.process.filterActions.fakeSourcesAssocDiaSrcId = MultiCriteriaDownselectVector(
200 vectorKey="isAssocDiaSource"
201 )
203 self.process.filterActions.fakeSourcesAssocDiaSrcId.selectors.snrange = RangeSelector(
204 vectorKey=f"{self.fluxType}_SNR", maximum=self.snrMax, minimum=self.snrMin
205 )
207 self.process.filterActions.fakeSourcesAssocDiaSrcId.selectors.fakeFlags = FlagSelector(
208 selectWhenFalse=self.fakeFlagsWhenFalse, selectWhenTrue=self.fakeFlagsWhenTrue
209 )
211 self.process.calculateActions.numTotalFakeAssocSources = CountAction(
212 vectorKey="fakeSourcesAssocDiaSrcId"
213 )
215 self.process.calculateActions.numFoundFakeAssocSources = CountAction(
216 vectorKey="fakeSourcesAssocDiaSrcId", op="gt", threshold=0
217 )
219 self.process.calculateActions.fractionFoundFakesAssocDiaAll = FracThreshold(
220 vectorKey="fakeSourcesAssocDiaSrcId", op="gt", threshold=0
221 )
223 # the units for the quantity (count, an astropy quantity)
224 self.produce.metric.units = {
225 "numTotalFakeAssocSources": "ct",
226 "numFoundFakeAssocSources": "ct",
227 "fractionFoundFakesAssocDiaAll": "",
228 }
231class FractionFoundFakesAssocDiaMagMetric(AnalysisTool):
232 """Calculate the fraction of fake sources found in AssocDiasrcs within
233 the given magnitude range"""
235 parameterizedBand: bool = False
237 magMin = Field[float](doc="Minimum magnitude for fake sources metric calculation.", default=18)
239 magMax = Field[float](doc="Maximum magnitude for fake sources metric calculation.", default=22)
241 fakeFlagsWhenTrue = ListField[str](
242 "Flags for fake source cleaning before metrics calculation. Select sources when flags are true.",
243 default=[],
244 )
246 fakeFlagsWhenFalse = ListField[str](
247 "Flags for fake source cleaning before metrics calculation. Select sources when flags are false.",
248 default=[
249 "forced_base_PixelFlags_flag_interpolated",
250 "forced_base_LocalBackground_flag",
251 "forced_base_PixelFlags_flag_bad",
252 "forced_base_PixelFlags_flag_edgeCenter",
253 ],
254 )
256 def finalize(self):
257 # Selecting the fake sources using the truth magnitude values.
258 self.process.filterActions.fakeSourcesAssocDiaSrcId = MultiCriteriaDownselectVector(
259 vectorKey="isAssocDiaSource"
260 )
262 self.process.filterActions.fakeSourcesAssocDiaSrcId.selectors.magrange = RangeSelector(
263 vectorKey="mag", maximum=self.magMax, minimum=self.magMin
264 )
266 self.process.filterActions.fakeSourcesAssocDiaSrcId.selectors.fakeFlags = FlagSelector(
267 selectWhenFalse=self.fakeFlagsWhenFalse, selectWhenTrue=self.fakeFlagsWhenTrue
268 )
270 self.process.calculateActions.numTotalFakeAssocSources = CountAction(
271 vectorKey="fakeSourcesAssocDiaSrcId"
272 )
274 self.process.calculateActions.numFoundFakeAssocSources = CountAction(
275 vectorKey="fakeSourcesAssocDiaSrcId", op="gt", threshold=0
276 )
278 self.process.calculateActions.fractionFoundFakesAssocDiaAll = FracThreshold(
279 vectorKey="fakeSourcesAssocDiaSrcId", op="gt", threshold=0
280 )
282 # the units for the quantity (count, an astropy quantity)
283 self.produce.metric.units = {
284 "numTotalFakeAssocSources": "ct",
285 "numFoundFakeAssocSources": "ct",
286 "fractionFoundFakesAssocDiaAll": "",
287 }