24 "NumberSciSourcesMetricTask",
"NumberSciSourcesMetricConfig",
25 "FractionDiaSourcesToSciSourcesMetricTask",
"FractionDiaSourcesToSciSourcesMetricConfig",
30import astropy.units
as u
33from lsst.verify
import Measurement
34from lsst.verify.tasks
import MetricTask, MetricConfig, MetricConnections, \
35 MetricComputationError
40 defaultTemplates={
"package":
"ip_diffim",
41 "metric":
"numSciSources"},
42 dimensions={
"instrument",
"visit",
"detector"},
44 sources = connectionTypes.Input(
45 doc=
"The catalog of science sources.",
47 storageClass=
"SourceCatalog",
48 dimensions={
"instrument",
"visit",
"detector"},
52class NumberSciSourcesMetricConfig(
54 pipelineConnections=NumberSciSourcesMetricConnections):
58class NumberSciSourcesMetricTask(MetricTask):
59 """Task that computes the number of cataloged non-primary science sources.
63 The task excludes any non-primary sources in the catalog, but it does
64 not require that the catalog include a ``detect_isPrimary``
or
65 ``sky_sources`` column.
67 _DefaultName = "numSciSources"
68 ConfigClass = NumberSciSourcesMetricConfig
70 def run(self, sources):
71 """Count the number of primary science sources.
76 A science source catalog, which may be empty.
80 result : `lsst.pipe.base.Struct`
81 A `~lsst.pipe.base.Struct` containing the following component:
84 the total number of non-primary science sources
85 (`lsst.verify.Measurement` or `
None`)
87 nSciSources = _countRealSources(sources)
88 meas = Measurement(self.config.metricName, nSciSources * u.count)
89 return Struct(measurement=meas)
92class FractionDiaSourcesToSciSourcesMetricConnections(
93 MetricTask.ConfigClass.ConnectionsClass,
94 dimensions={
"instrument",
"visit",
"detector"},
95 defaultTemplates={
"coaddName":
"deep",
97 "package":
"ip_diffim",
98 "metric":
"fracDiaSourcesToSciSources"}):
99 sciSources = connectionTypes.Input(
100 doc=
"The catalog of science sources.",
102 storageClass=
"SourceCatalog",
103 dimensions={
"instrument",
"visit",
"detector"},
105 diaSources = connectionTypes.Input(
106 doc=
"The catalog of DIASources.",
107 name=
"{fakesType}{coaddName}Diff_diaSrc",
108 storageClass=
"SourceCatalog",
109 dimensions={
"instrument",
"visit",
"detector"},
113class FractionDiaSourcesToSciSourcesMetricConfig(
114 MetricTask.ConfigClass,
115 pipelineConnections=FractionDiaSourcesToSciSourcesMetricConnections):
119class FractionDiaSourcesToSciSourcesMetricTask(MetricTask):
120 """Task that computes the ratio of difference image sources to science
121 sources in an image, visit, etc.
125 The task excludes any non-primary sources
in the catalog, but it does
126 not require that the catalog include a ``detect_isPrimary``
or
127 ``sky_sources`` column.
129 _DefaultName = "fracDiaSourcesToSciSources"
130 ConfigClass = FractionDiaSourcesToSciSourcesMetricConfig
132 def run(self, sciSources, diaSources):
133 """Compute the ratio of DIASources to non-primary science sources.
138 A science source catalog, which may be empty.
140 A DIASource catalog for the same unit of processing
145 result : `lsst.pipe.base.Struct`
146 A `~lsst.pipe.base.Struct` containing the following component:
149 the ratio (`lsst.verify.Measurement`
or `
None`)
151 nSciSources = _countRealSources(sciSources)
152 nDiaSources = _countRealSources(diaSources)
153 metricName = self.config.metricName
155 raise MetricComputationError(
156 "No science sources found; ratio of DIASources to science sources ill-defined.")
158 meas = Measurement(metricName, nDiaSources / nSciSources * u.dimensionless_unscaled)
159 return Struct(measurement=meas)
162def _countRealSources(catalog):
163 """Return the number of valid sources in a catalog.
165 At present, this definition includes only primary sources. If a catalog
166 does not have a ``detect_isPrimary`` flag, this function counts non-sky
167 sources. If it does
not have a ``sky_source`` flag, either, all sources
173 The catalog of sources to count.
178 The number of sources that satisfy the criteria.
182 if "detect_isPrimary" in catalog.schema:
183 return np.count_nonzero(catalog[
"detect_isPrimary"] ==
True)
184 elif "sky_source" in catalog.schema:
185 return np.count_nonzero(catalog[
"sky_source"] ==
False)
run(self, coaddExposures, bbox, wcs, dataIds, physical_filter=None, **kwargs)