Hide keyboard shortcuts

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# 

22 

23"""Metrics for ap_pipe tasks. 

24""" 

25 

26__all__ = [ 

27 "ApFakesCompletenessMetricTask", "ApFakesCompletenessMetricConfig", 

28 "ApFakesCountMetricTask", "ApFakesCountMetricConfig" 

29] 

30 

31import astropy.units as u 

32import numpy as np 

33import traceback 

34 

35import lsst.pex.config as pexConfig 

36from lsst.pipe.base import Struct 

37import lsst.pipe.base.connectionTypes as connTypes 

38from lsst.pipe.tasks.insertFakes import InsertFakesConfig 

39from lsst.verify import Measurement 

40from lsst.verify.tasks import MetricTask, MetricComputationError 

41 

42 

43class ApFakesCompletenessMetricConnections( 

44 MetricTask.ConfigClass.ConnectionsClass, 

45 dimensions={"instrument", "visit", "detector", "band"}, 

46 defaultTemplates={"coaddName": "deep", 

47 "fakesType": "fakes_", 

48 "package": "ap_pipe", 

49 "metric": "apFakesCompleteness"}): 

50 """ApFakesCompleteness connections. 

51 """ 

52 matchedFakes = connTypes.Input( 

53 doc="Fakes matched to their detections in the difference image.", 

54 name="{fakesType}{coaddName}Diff_matchDiaSrc", 

55 storageClass="DataFrame", 

56 dimensions=("instrument", "visit", "detector"), 

57 ) 

58 

59 

60# Inherits from InsertFakesConfig to preserve column names in the fakes 

61# catalog. 

62class ApFakesCompletenessMetricConfig( 

63 MetricTask.ConfigClass, 

64 InsertFakesConfig, 

65 pipelineConnections=ApFakesCompletenessMetricConnections): 

66 """ApFakesCompleteness config. 

67 """ 

68 magMin = pexConfig.RangeField( 

69 doc="Minimum of cut on magnitude range used to compute completeness " 

70 "in.", 

71 dtype=float, 

72 default=20, 

73 min=1, 

74 max=40, 

75 ) 

76 magMax = pexConfig.RangeField( 

77 doc="Maximum of cut on magnitude range used to compute completeness " 

78 "in.", 

79 dtype=int, 

80 default=30, 

81 min=1, 

82 max=40, 

83 ) 

84 

85 

86class ApFakesCompletenessMetricTask(MetricTask): 

87 """Metric task for summarizing the completeness of fakes inserted into the 

88 AP pipeline. 

89 """ 

90 _DefaultName = "apFakesCompleteness" 

91 ConfigClass = ApFakesCompletenessMetricConfig 

92 

93 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

94 try: 

95 inputs = butlerQC.get(inputRefs) 

96 inputs["band"] = butlerQC.quantum.dataId["band"] 

97 outputs = self.run(**inputs) 

98 if outputs.measurement is not None: 

99 butlerQC.put(outputs, outputRefs) 

100 else: 

101 self.log.debugf("Skipping measurement of {!r} on {} " 

102 "as not applicable.", self, inputRefs) 

103 except MetricComputationError: 

104 # Apparently lsst.log doesn't have built-in exception support? 

105 self.log.errorf( 

106 "Measurement of {!r} failed on {}->{}\n{}", 

107 self, inputRefs, outputRefs, traceback.format_exc()) 

108 

109 def run(self, matchedFakes, band): 

110 """Compute the completeness of recovered fakes within a magnitude 

111 range. 

112 

113 Parameters 

114 ---------- 

115 matchedFakes : `lsst.afw.table.SourceCatalog` or `None` 

116 Catalog of fakes that were inserted into the ccdExposure matched 

117 to their detected counterparts. 

118 band : `str` 

119 Single character name of the observed band for this quanta. 

120 

121 Returns 

122 ------- 

123 result : `lsst.pipe.base.Struct` 

124 A `~lsst.pipe.base.Struct` containing the following component: 

125 ``measurement`` 

126 the ratio (`lsst.verify.Measurement` or `None`) 

127 """ 

128 if matchedFakes is not None: 

129 magnitudes = np.fabs(matchedFakes[f"{self.config.mag_col}" % band]) 

130 magCutFakes = matchedFakes[np.logical_and(magnitudes > self.config.magMin, 

131 magnitudes < self.config.magMax)] 

132 if len(magCutFakes) <= 0.0: 

133 raise MetricComputationError( 

134 "No matched fakes catalog sources found; Completeness is " 

135 "ill defined.") 

136 else: 

137 meas = Measurement( 

138 self.config.metricName, 

139 ((magCutFakes["diaSourceId"] > 0).sum() / len(magCutFakes)) 

140 * u.dimensionless_unscaled) 

141 else: 

142 self.log.info("Nothing to do: no matched catalog found.") 

143 meas = None 

144 return Struct(measurement=meas) 

145 

146 

147class ApFakesCountMetricConnections( 

148 ApFakesCompletenessMetricConnections, 

149 dimensions={"instrument", "visit", "detector", "band"}, 

150 defaultTemplates={"coaddName": "deep", 

151 "fakesType": "fakes_", 

152 "package": "ap_pipe", 

153 "metric": "apFakesCompleteness"}): 

154 pass 

155 

156 

157class ApFakesCountMetricConfig( 

158 ApFakesCompletenessMetricConfig, 

159 pipelineConnections=ApFakesCountMetricConnections): 

160 """ApFakesCompleteness config. 

161 """ 

162 pass 

163 

164 

165class ApFakesCountMetricTask(ApFakesCompletenessMetricTask): 

166 """Metric task for summarizing the completeness of fakes inserted into the 

167 AP pipeline. 

168 """ 

169 _DefaultName = "apFakesCount" 

170 ConfigClass = ApFakesCountMetricConfig 

171 

172 def run(self, matchedFakes, band): 

173 """Compute the number of fakes inserted within a magnitude 

174 range. 

175 

176 Parameters 

177 ---------- 

178 matchedFakes : `lsst.afw.table.SourceCatalog` or `None` 

179 Catalog of fakes that were inserted into the ccdExposure matched 

180 to their detected counterparts. 

181 band : `str` 

182 Single character name of the observed band for this quanta. 

183 

184 Returns 

185 ------- 

186 result : `lsst.pipe.base.Struct` 

187 A `~lsst.pipe.base.Struct` containing the following component: 

188 ``measurement`` 

189 the ratio (`lsst.verify.Measurement` or `None`) 

190 """ 

191 if matchedFakes is not None: 

192 magnitudes = np.fabs(matchedFakes[f"{self.config.mag_col}" % band]) 

193 magCutFakes = matchedFakes[np.logical_and(magnitudes > self.config.magMin, 

194 magnitudes < self.config.magMax)] 

195 meas = Measurement(self.config.metricName, 

196 len(magCutFakes) * u.count) 

197 else: 

198 self.log.info("Nothing to do: no matched catalog supplied.") 

199 meas = None 

200 return Struct(measurement=meas)