LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+bd2ed33bd6,g1470d8bcf6+de7501a2e0,g14a832a312+ff425fae3c,g2079a07aa2+86d27d4dc4,g2305ad1205+91a32aca49,g295015adf3+762506a1ad,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+c34e8be1fa,g487adcacf7+5fae3daba8,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+ea1711114f,g5a732f18d5+53520f316c,g64a986408d+bd2ed33bd6,g858d7b2824+bd2ed33bd6,g8a8a8dda67+585e252eca,g99cad8db69+016a06b37a,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+ef4e3a5875,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+09e12c87ab,gc120e1dc64+bc2e06c061,gc28159a63d+0e5473021a,gcf0d15dbbd+c34e8be1fa,gdaeeff99f8+f9a426f77a,ge6526c86ff+508d0e0a30,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf18bd8381d+8d59551888,gf1cff7945b+bd2ed33bd6,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
metrics.py
Go to the documentation of this file.
1# This file is part of pipe_tasks.
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/>.
21
22__all__ = [
23 "NumberDeblendedSourcesMetricTask", "NumberDeblendedSourcesMetricConfig",
24 "NumberDeblendChildSourcesMetricTask", "NumberDeblendChildSourcesMetricConfig",
25]
26
27
28import numpy as np
29import astropy.units as u
30
31from lsst.pipe.base import NoWorkFound, Struct, connectionTypes
32from lsst.verify import Measurement
33from lsst.verify.tasks import MetricTask, MetricConfig, MetricConnections, MetricComputationError
34
35
37 MetricConnections,
38 defaultTemplates={"package": "pipe_tasks",
39 "metric": "numDeblendedSciSources"},
40 dimensions={"instrument", "visit", "detector"},
41):
42 sources = connectionTypes.Input(
43 doc="The catalog of science sources.",
44 name="src",
45 storageClass="SourceCatalog",
46 dimensions={"instrument", "visit", "detector"},
47 )
48
49
50class NumberDeblendedSourcesMetricConfig(
51 MetricConfig,
52 pipelineConnections=NumberDeblendedSourcesMetricConnections):
53 pass
54
55
56class NumberDeblendedSourcesMetricTask(MetricTask):
57 """Task that computes the number of science sources that have
58 been deblended.
59
60 This task only counts sources that existed prior to any deblending;
61 i.e., if deblending was run more than once or with multiple iterations,
62 only the "top-level" deblended sources are counted, and not any
63 intermediate ones. If sky source information is present, sky sources
64 are excluded.
65
66 Notes
67 -----
68 The task excludes any non-sky sources in the catalog, but it does
69 not require that the catalog include a ``sky_sources`` column.
70 """
71 _DefaultName = "numDeblendedSciSources"
72 ConfigClass = NumberDeblendedSourcesMetricConfig
73
74 def run(self, sources):
75 """Count the number of deblended science sources.
76
77 Parameters
78 ----------
79 sources : `lsst.afw.table.SourceCatalog`
80 A science source catalog, which may be empty.
81
82 Returns
83 -------
84 result : `lsst.pipe.base.Struct`
85 A `~lsst.pipe.base.Struct` containing the following component:
86
87 ``measurement``
88 the total number of deblended science sources
89 (`lsst.verify.Measurement`). If no deblending information is
90 available in ``sources``, this is `None`.
91
92 Raises
93 ------
94 MetricComputationError
95 Raised if ``sources`` is missing mandatory keys for
96 source catalogs.
97 """
98 if "deblend_nChild" not in sources.schema:
99 raise NoWorkFound("Nothing to do: no deblending performed.")
100 else:
101 try:
102 deblended = ((sources["parent"] == 0) # top-level source
103 & (sources["deblend_nChild"] > 0) # deblended
104 )
105 deblended = _filterSkySources(sources, deblended)
106 except LookupError as e:
107 # Probably "parent"; all other columns already checked
108 raise MetricComputationError("Invalid input catalog") from e
109 else:
110 nDeblended = np.count_nonzero(deblended)
111 return Struct(measurement=Measurement(self.config.metricName,
112 nDeblended * u.dimensionless_unscaled))
113
114
115class NumberDeblendChildSourcesMetricConnections(
116 MetricConnections,
117 defaultTemplates={"package": "pipe_tasks",
118 "metric": "numDeblendChildSciSources"},
119 dimensions={"instrument", "visit", "detector"},
120):
121 sources = connectionTypes.Input(
122 doc="The catalog of science sources.",
123 name="src",
124 storageClass="SourceCatalog",
125 dimensions={"instrument", "visit", "detector"},
126 )
127
128
129class NumberDeblendChildSourcesMetricConfig(
130 MetricConfig,
131 pipelineConnections=NumberDeblendChildSourcesMetricConnections):
132 pass
133
134
135class NumberDeblendChildSourcesMetricTask(MetricTask):
136 """Task that computes the number of science sources created
137 through deblending.
138
139 This task only counts final deblending products; i.e., if deblending was
140 run more than once or with multiple iterations, only the final set of
141 deblended sources are counted, and not any intermediate ones.
142 If sky source information is present, sky sources are excluded.
143
144 Notes
145 -----
146 The task excludes any non-sky sources in the catalog, but it does
147 not require that the catalog include a ``sky_sources`` column.
148 """
149 _DefaultName = "numDeblendChildSciSources"
150 ConfigClass = NumberDeblendChildSourcesMetricConfig
151
152 def run(self, sources):
153 """Count the number of science sources created by deblending.
154
155 Parameters
156 ----------
157 sources : `lsst.afw.table.SourceCatalog`
158 A science source catalog, which may be empty.
159
160 Returns
161 -------
162 result : `lsst.pipe.base.Struct`
163 A `~lsst.pipe.base.Struct` containing the following component:
164
165 ``measurement``
166 the total number of science sources from deblending
167 (`lsst.verify.Measurement`). If no deblending information is
168 available in ``sources``, this is `None`.
169
170 Raises
171 ------
172 MetricComputationError
173 Raised if ``sources`` is missing mandatory keys for
174 source catalogs.
175 """
176 # Use deblend_parentNChild rather than detect_fromBlend because the
177 # latter need not be defined in post-deblending catalogs.
178 if "deblend_parentNChild" not in sources.schema or "deblend_nChild" not in sources.schema:
179 raise NoWorkFound("Nothing to do: no deblending performed.")
180 else:
181 try:
182 children = ((sources["deblend_parentNChild"] > 1) # deblend child
183 & (sources["deblend_nChild"] == 0) # not deblended
184 )
185 children = _filterSkySources(sources, children)
186 except LookupError as e:
187 # Probably "parent"; all other columns already checked
188 raise MetricComputationError("Invalid input catalog") from e
189 else:
190 nChildren = np.count_nonzero(children)
191 return Struct(measurement=Measurement(self.config.metricName,
192 nChildren * u.dimensionless_unscaled))
193
194
195def _filterSkySources(catalog, selection):
196 """Filter out any sky sources from a vector of selected sources.
197
198 If no sky source information is available, all sources are assumed to
199 be non-sky.
200
201 Parameters
202 ----------
203 catalog : `lsst.afw.table.SourceCatalog`
204 The catalog to filter.
205 selection : `numpy.ndarray` [`bool`], (N,)
206 A vector of existing source selections, of the same length as
207 ``catalog``, where selected sources are marked `True`.
208
209 Returns
210 -------
211 filtered : `numpy.ndarray` [`bool`], (N,)
212 A version of ``selection`` with any sky sources filtered out
213 (set to `False`). May be the same vector as ``selection`` if
214 no changes were made.
215 """
216 if "sky_source" in catalog.schema:
217 # E712 is not applicable, because afw.table.SourceRecord.ColumnView
218 # is not a bool.
219 return selection & (catalog["sky_source"] == False) # noqa: E712
220 else:
221 return selection