Coverage for python / lsst / analysis / tools / atools / diaSourceMetrics.py: 47%
36 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 17:42 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 17:42 +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 "NumGoodDiaSourcesMetrics",
25 "NumDipolesMetric",
26 "NumDiaSourcesSelectionMetric",
27 "DiaSourcesGoodVsBadRatioMetric",
28)
30from lsst.pex.config import Field
32from ..actions.scalar import CountAction, DivideScalar
33from ..actions.vector import DownselectVector, FlagSelector, GoodDiaSourceSelector
34from ..interfaces import AnalysisTool
37class NumGoodDiaSourcesMetrics(AnalysisTool):
38 """Calculate the number of DIA Sources that do not have known
39 bad/quality flags set to true, and also calculate the ratio of
40 counts of non-flagged sources to all sources.
41 """
43 parameterizedBand: bool = False
45 def setDefaults(self):
46 super().setDefaults()
48 # filter for and count the number of dia sources that don't have flags
49 self.process.filterActions.goodDiaSources = DownselectVector(
50 vectorKey="parentDiaSourceId", selector=GoodDiaSourceSelector()
51 )
52 self.process.calculateActions.numGoodDiaSources = CountAction(vectorKey="goodDiaSources")
54 # Count the total number of dia sources:
55 self.process.calculateActions.numAllDiaSources = CountAction(vectorKey="parentDiaSourceId")
57 # And calculate the ratio of good-to-all counts
58 self.process.calculateActions.ratioGoodToAllDiaSources = DivideScalar(
59 actionA=self.process.calculateActions.numGoodDiaSources,
60 actionB=self.process.calculateActions.numAllDiaSources,
61 )
63 # the units for the quantity (count, an astropy quantity)
64 self.produce.metric.units = {
65 "numAllDiaSources": "ct",
66 "numGoodDiaSources": "ct",
67 "ratioGoodToAllDiaSources": "",
68 }
71class NumDipolesMetric(AnalysisTool):
72 """Calculate the number of dipoles with NaN values excluded."""
74 def setDefaults(self):
75 super().setDefaults()
77 # select all diaSources flagged as dipole
78 self.prep.selectors.flags = FlagSelector(selectWhenTrue=["isDipole"])
80 # count the number of dipoles
81 self.process.buildActions.numDipoles = CountAction(vectorKey="isDipole")
83 # the units for the quantity (count, an astropy quantity)
84 self.produce.metric.units = {"numDipoles": "ct"}
87class NumDiaSourcesSelectionMetric(AnalysisTool):
88 """Count the number of DIA Sources for a given threshold."""
90 metricName = Field[str](doc="Name to use for output metric")
92 def setDefaults(self):
93 super().setDefaults()
95 # Count dia sources with reliability lower than the threshold
96 self.process.calculateActions.countingAction = CountAction
98 # The units for the quantity (count, an astropy quantity)
99 self.produce.metric.units = {"countingAction": "ct"}
101 def finalize(self):
102 self.produce.metric.newNames = {"countingAction": self.metricName}
105class DiaSourcesGoodVsBadRatioMetric(AnalysisTool):
106 """Calculate the ratio of 'good' vs 'bad' DIA Sources."""
108 def setDefaults(self):
109 super().setDefaults()
111 # Count dia sources with reliability higher than the threshold
112 self.process.buildActions.numDiaSourcesHighReliability = CountAction(
113 op="gt", threshold=0.9, vectorKey="reliability"
114 )
116 # Count dia sources with reliability lower than the threshold
117 self.process.buildActions.numDiaSourcesLowReliability = CountAction(
118 op="lt", threshold=0.1, vectorKey="reliability"
119 )
121 # Calculate ratio of good vs bad DIA Sources
122 self.process.calculateActions.DiaSourcesGoodVsBadRatio = DivideScalar(
123 actionA=self.process.buildActions.numDiaSourcesHighReliability,
124 actionB=self.process.buildActions.numDiaSourcesLowReliability,
125 )
127 # The units for the quantity (dimensionless, an astropy quantity)
128 self.produce.metric.units = {"DiaSourcesGoodVsBadRatio": ""}