23 "NumberDeblendedSourcesMetricTask",
"NumberDeblendedSourcesMetricConfig",
24 "NumberDeblendChildSourcesMetricTask",
"NumberDeblendChildSourcesMetricConfig",
29import astropy.units
as u
32from lsst.verify
import Measurement
33from lsst.verify.tasks
import MetricTask, MetricConfig, MetricConnections, MetricComputationError
38 defaultTemplates={
"package":
"pipe_tasks",
39 "metric":
"numDeblendedSciSources"},
40 dimensions={
"instrument",
"visit",
"detector"},
42 sources = connectionTypes.Input(
43 doc=
"The catalog of science sources.",
45 storageClass=
"SourceCatalog",
46 dimensions={
"instrument",
"visit",
"detector"},
50class NumberDeblendedSourcesMetricConfig(
52 pipelineConnections=NumberDeblendedSourcesMetricConnections):
56class NumberDeblendedSourcesMetricTask(MetricTask):
57 """Task that computes the number of science sources that have
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
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.
71 _DefaultName = "numDeblendedSciSources"
72 ConfigClass = NumberDeblendedSourcesMetricConfig
74 def run(self, sources):
75 """Count the number of deblended science sources.
80 A science source catalog, which may be empty
or `
None`.
84 result : `lsst.pipe.base.Struct`
85 A `~lsst.pipe.base.Struct` containing the following component:
88 the total number of deblended science sources
89 (`lsst.verify.Measurement`). If no deblending information
is
90 available
in ``sources``, this
is `
None`.
94 MetricComputationError
95 Raised
if ``sources``
is missing mandatory keys
for
99 self.log.info(
"Nothing to do: no catalogs found.")
101 elif "deblend_nChild" not in sources.schema:
102 self.log.info(
"Nothing to do: no deblending performed.")
106 deblended = ((sources[
"parent"] == 0)
107 & (sources[
"deblend_nChild"] > 0)
109 deblended = _filterSkySources(sources, deblended)
110 except LookupError
as e:
112 raise MetricComputationError(
"Invalid input catalog")
from e
114 nDeblended = np.count_nonzero(deblended)
115 meas = Measurement(self.config.metricName, nDeblended * u.dimensionless_unscaled)
117 return Struct(measurement=meas)
120class NumberDeblendChildSourcesMetricConnections(
122 defaultTemplates={
"package":
"pipe_tasks",
123 "metric":
"numDeblendChildSciSources"},
124 dimensions={
"instrument",
"visit",
"detector"},
126 sources = connectionTypes.Input(
127 doc=
"The catalog of science sources.",
129 storageClass=
"SourceCatalog",
130 dimensions={
"instrument",
"visit",
"detector"},
134class NumberDeblendChildSourcesMetricConfig(
136 pipelineConnections=NumberDeblendChildSourcesMetricConnections):
140class NumberDeblendChildSourcesMetricTask(MetricTask):
141 """Task that computes the number of science sources created
144 This task only counts final deblending products; i.e., if deblending was
145 run more than once
or with multiple iterations, only the final set of
146 deblended sources are counted,
and not any intermediate ones.
147 If sky source information
is present, sky sources are excluded.
151 The task excludes any non-sky sources
in the catalog, but it does
152 not require that the catalog include a ``sky_sources`` column.
154 _DefaultName = "numDeblendChildSciSources"
155 ConfigClass = NumberDeblendChildSourcesMetricConfig
157 def run(self, sources):
158 """Count the number of science sources created by deblending.
163 A science source catalog, which may be empty
or `
None`.
167 result : `lsst.pipe.base.Struct`
168 A `~lsst.pipe.base.Struct` containing the following component:
171 the total number of science sources
from deblending
172 (`lsst.verify.Measurement`). If no deblending information
is
173 available
in ``sources``, this
is `
None`.
177 MetricComputationError
178 Raised
if ``sources``
is missing mandatory keys
for
182 self.log.info(
"Nothing to do: no catalogs found.")
186 elif "deblend_parentNChild" not in sources.schema
or "deblend_nChild" not in sources.schema:
187 self.log.info(
"Nothing to do: no deblending performed.")
191 children = ((sources[
"deblend_parentNChild"] > 1)
192 & (sources[
"deblend_nChild"] == 0)
194 children = _filterSkySources(sources, children)
195 except LookupError
as e:
197 raise MetricComputationError(
"Invalid input catalog")
from e
199 nChildren = np.count_nonzero(children)
200 meas = Measurement(self.config.metricName, nChildren * u.dimensionless_unscaled)
202 return Struct(measurement=meas)
205def _filterSkySources(catalog, selection):
206 """Filter out any sky sources from a vector of selected sources.
208 If no sky source information is available, all sources are assumed to
214 The catalog to filter.
215 selection : `numpy.ndarray` [`bool`], (N,)
216 A vector of existing source selections, of the same length
as
217 ``catalog``, where selected sources are marked `
True`.
221 filtered : `numpy.ndarray` [`bool`], (N,)
222 A version of ``selection``
with any sky sources filtered out
223 (set to `
False`). May be the same vector
as ``selection``
if
224 no changes were made.
226 if "sky_source" in catalog.schema:
229 return selection & (catalog[
"sky_source"] ==
False)