Coverage for python/lsst/ap/pipe/metrics.py : 47%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of ap_pipe.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://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 <http://www.gnu.org/licenses/>.
21#
23"""Metrics for ap_pipe tasks.
24"""
26__all__ = [
27 "ApFakesCompletenessMetricTask", "ApFakesCompletenessMetricConfig",
28]
30import astropy.units as u
31import numpy as np
32import traceback
34import lsst.pex.config as pexConfig
35from lsst.pipe.base import Struct
36import lsst.pipe.base.connectionTypes as connTypes
37from lsst.pipe.tasks.insertFakes import InsertFakesConfig
38from lsst.verify import Measurement
39from lsst.verify.tasks import MetricTask, MetricComputationError
42class ApFakesCompletenessMetricConnections(
43 MetricTask.ConfigClass.ConnectionsClass,
44 dimensions={"instrument", "visit", "detector", "band"},
45 defaultTemplates={"coaddName": "deep",
46 "fakesType": "fakes_",
47 "package": "ap_pipe",
48 "metric": "apFakesCompleteness"}):
49 """ApFakesCompleteness connections.
50 """
51 matchedFakes = connTypes.Input(
52 doc="Fakes matched to their detections in the difference image.",
53 name="{fakesType}{coaddName}Diff_matchDiaSrc",
54 storageClass="DataFrame",
55 dimensions=("instrument", "visit", "detector"),
56 )
59# Inherits from InsertFakesConfig to preserve column names in the fakes
60# catalog.
61class ApFakesCompletenessMetricConfig(
62 MetricTask.ConfigClass,
63 InsertFakesConfig,
64 pipelineConnections=ApFakesCompletenessMetricConnections):
65 """ApFakesCompleteness config.
66 """
67 magMin = pexConfig.RangeField(
68 doc="Minimum of cut on magnitude range used to compute completeness "
69 "in.",
70 dtype=float,
71 default=20,
72 min=1,
73 max=40,
74 )
75 magMax = pexConfig.RangeField(
76 doc="Maximum of cut on magnitude range used to compute completeness "
77 "in.",
78 dtype=int,
79 default=30,
80 min=1,
81 max=40,
82 )
85class ApFakesCompletenessMetricTask(MetricTask):
86 """Metric task for summarizing the completeness of fakes inserted into the
87 AP pipeline.
88 """
89 _DefaultName = "apFakesCompleteness"
90 ConfigClass = ApFakesCompletenessMetricConfig
92 def runQuantum(self, butlerQC, inputRefs, outputRefs):
93 try:
94 inputs = butlerQC.get(inputRefs)
95 inputs["band"] = butlerQC.quantum.dataId["band"]
96 outputs = self.run(**inputs)
97 if outputs.measurement is not None:
98 butlerQC.put(outputs, outputRefs)
99 else:
100 self.log.debugf("Skipping measurement of {!r} on {} "
101 "as not applicable.", self, inputRefs)
102 except MetricComputationError:
103 # Apparently lsst.log doesn't have built-in exception support?
104 self.log.errorf(
105 "Measurement of {!r} failed on {}->{}\n{}",
106 self, inputRefs, outputRefs, traceback.format_exc())
108 def run(self, matchedFakes, band):
109 """Compute the completeness of recovered fakes within a magnitude
110 range.
112 Parameters
113 ----------
114 matchedFakes : `lsst.afw.table.SourceCatalog` or `None`
115 Catalog of fakes that were inserted into the ccdExposure matched
116 to their detected counterparts.
118 Returns
119 -------
120 result : `lsst.pipe.base.Struct`
121 A `~lsst.pipe.base.Struct` containing the following component:
122 ``measurement``
123 the ratio (`lsst.verify.Measurement` or `None`)
124 """
125 if matchedFakes is not None:
126 magnitudes = matchedFakes[f"{self.config.magVar}" % band]
127 magCutFakes = matchedFakes[np.logical_and(magnitudes > self.config.magMin,
128 magnitudes < self.config.magMax)]
129 if len(magCutFakes) <= 0.0:
130 raise MetricComputationError(
131 "No matched fakes catalog sources found; Completeness is "
132 "ill defined.")
133 else:
134 meas = Measurement(
135 self.config.metricName,
136 ((magCutFakes["diaSourceId"] > 0).sum() / len(magCutFakes))
137 * u.dimensionless_unscaled)
138 else:
139 self.log.info("Nothing to do: no matched catalog found.")
140 meas = None
141 return Struct(measurement=meas)