Coverage for python/lsst/cp/verify/verifyCalib.py: 77%

29 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-18 20:44 +0000

1# This file is part of cp_verify. 

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/>. 

21import lsst.pex.config as pexConfig 

22import lsst.pipe.base as pipeBase 

23import lsst.pipe.base.connectionTypes as cT 

24 

25from lsst.cp.pipe._lookupStaticCalibration import lookupStaticCalibration 

26 

27__all__ = ['CpVerifyCalibConfig', 'CpVerifyCalibTask'] 

28 

29 

30class CpVerifyCalibConnections(pipeBase.PipelineTaskConnections, 

31 dimensions={"instrument", "detector"}, 

32 defaultTemplates={}): 

33 inputCalib = cT.Input( 

34 name="calib", 

35 doc="Input calib to calculate statistics for.", 

36 storageClass="IsrCalib", 

37 dimensions=["instrument", "detector"], 

38 isCalibration=True 

39 ) 

40 

41 camera = cT.PrerequisiteInput( 

42 name="camera", 

43 doc="Input camera to use for gain lookup.", 

44 storageClass="Camera", 

45 dimensions=("instrument",), 

46 lookupFunction=lookupStaticCalibration, 

47 isCalibration=True, 

48 ) 

49 

50 outputStats = cT.Output( 

51 name="calibStats", 

52 doc="Output statistics from cp_verify.", 

53 storageClass="StructuredDataDict", 

54 dimensions=["instrument", "detector"], 

55 ) 

56 

57 

58class CpVerifyCalibConfig(pipeBase.PipelineTaskConfig, 

59 pipelineConnections=CpVerifyCalibConnections): 

60 """Configuration parameters for CpVerifyCalibTask. 

61 """ 

62 # Statistics options. 

63 useReadNoise = pexConfig.Field( 

64 dtype=bool, 

65 doc="Compare sigma against read noise?", 

66 default=True, 

67 ) 

68 numSigmaClip = pexConfig.Field( 

69 dtype=float, 

70 doc="Rejection threshold (sigma) for statistics clipping.", 

71 default=5.0, 

72 ) 

73 clipMaxIter = pexConfig.Field( 

74 dtype=int, 

75 doc="Max number of clipping iterations to apply.", 

76 default=3, 

77 ) 

78 

79 # Keywords and statistics to measure from different sources. 

80 calibStatKeywords = pexConfig.DictField( 

81 keytype=str, 

82 itemtype=str, 

83 doc="Calib statistics to run.", 

84 default={}, 

85 ) 

86 

87 

88class CpVerifyCalibTask(pipeBase.PipelineTask): 

89 """Main statistic measurement and validation class. 

90 

91 This operates on a generic calibration, and is designed to be 

92 subclassed so specific calibrations can apply their own validation 

93 methods. 

94 """ 

95 

96 ConfigClass = CpVerifyCalibConfig 

97 _DefaultName = 'cpVerifyCalib' 

98 

99 def run(self, inputCalib, camera=None): 

100 """Calculate quality statistics and verify they meet the requirements 

101 for a calibration. 

102 

103 Parameters 

104 ---------- 

105 inputCalib : `lsst.ip.isr.IsrCalib` 

106 The calibration to be measured. 

107 camera : `lsst.afw.cameraGeom.Camera`, optional 

108 Input camera. 

109 

110 Returns 

111 ------- 

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

113 Result struct with components: 

114 - ``outputStats`` : `dict` 

115 The output measured statistics. 

116 

117 Notes 

118 ----- 

119 The outputStats should have a yaml representation of the form 

120 (with STAT and TEST being the appropriate statistic and test 

121 names) 

122 

123 DET: 

124 STAT: value 

125 STAT2: value 

126 AMP: 

127 STAT: value 

128 STAT2: value 

129 VERIFY: 

130 TEST: boolean 

131 SUCCESS: boolean 

132 

133 """ 

134 outputStats = {} 

135 outputStats['AMP'] = self.amplifierStatistics(inputCalib, camera=camera) 

136 outputStats['DET'] = self.detectorStatistics(inputCalib, camera=camera) 

137 outputStats['VERIFY'], outputStats['SUCCESS'] = self.verify(inputCalib, outputStats, camera=camera) 

138 

139 return pipeBase.Struct( 

140 outputStats=outputStats, 

141 ) 

142 

143 # Methods that need to be implemented by the calibration-level subclasses. 

144 def detectorStatistics(self, inputCalib, camera=None): 

145 """Calculate detector level statistics from the calibration. 

146 

147 Parameters 

148 ---------- 

149 inputCalib : `lsst.ip.isr.IsrCalib` 

150 The calibration to verify. 

151 

152 Returns 

153 ------- 

154 outputStatistics : `dict` [`str`, scalar] 

155 A dictionary of the statistics measured and their values. 

156 camera : `lsst.afw.cameraGeom.Camera`, optional 

157 Input camera. 

158 

159 Raises 

160 ------ 

161 NotImplementedError : 

162 This method must be implemented by the calibration-type 

163 subclass. 

164 """ 

165 raise NotImplementedError("Subclasses must implement detector statistics method.") 

166 

167 def amplifierStatistics(self, inputCalib, camera=None): 

168 """Calculate amplifier level statistics from the calibration. 

169 

170 Parameters 

171 ---------- 

172 inputCalib : `lsst.ip.isr.IsrCalib` 

173 The calibration to verify. 

174 camera : `lsst.afw.cameraGeom.Camera`, optional 

175 Input camera. 

176 

177 Returns 

178 ------- 

179 outputStatistics : `dict` [`str`, scalar] 

180 A dictionary of the statistics measured and their values. 

181 

182 Raises 

183 ------ 

184 NotImplementedError : 

185 This method must be implemented by the calibration-type 

186 subclass. 

187 """ 

188 raise NotImplementedError("Subclasses must implement amplifier statistics method.") 

189 

190 def verify(self, inputCalib, statisticsDict, camera=None): 

191 """Verify that the measured calibration meet the verification criteria. 

192 

193 Parameters 

194 ---------- 

195 inputCalib : `lsst.ip.isr.IsrCalib` 

196 The calibration to verify. 

197 statisticsDictionary : `dict` [`str`, `dict` [`str`, scalar]], 

198 Dictionary of measured statistics. The inner dictionary 

199 should have keys that are statistic names (`str`) with 

200 values that are some sort of scalar (`int` or `float` are 

201 the mostly likely types). 

202 camera : `lsst.afw.cameraGeom.Camera`, optional 

203 Input camera. 

204 

205 Returns 

206 ------- 

207 outputStatistics : `dict` [`str`, `dict` [`str`, `bool`]] 

208 A dictionary indexed by the amplifier name, containing 

209 dictionaries of the verification criteria. 

210 success : `bool` 

211 A boolean indicating whether all tests have passed. 

212 

213 Raises 

214 ------ 

215 NotImplementedError : 

216 This method must be implemented by the calibration-type 

217 subclass. 

218 """ 

219 raise NotImplementedError("Subclasses must implement verification criteria.")