Coverage for python/lsst/cp/verify/verifyCalib.py: 73%
30 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-29 03:03 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-29 03:03 -0800
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
25from lsst.cp.pipe._lookupStaticCalibration import lookupStaticCalibration
27__all__ = ['CpVerifyCalibConfig', 'CpVerifyCalibTask']
30class CpVerifyCalibConnections(pipeBase.PipelineTaskConnections,
31 dimensions={"instrument", "detector"},
32 defaultTemplates={}):
34 exposure = cT.Input(
35 name="raw",
36 doc="Exposure to retreve calibration",
37 storageClass='Exposure',
38 dimensions=("instrument", "detector", "exposure"),
39 multiple=True,
40 deferLoad=True,
41 )
43 inputCalib = cT.Input(
44 name="calib",
45 doc="Input calib to calculate statistics for.",
46 storageClass="IsrCalib",
47 dimensions=["instrument", "detector"],
48 isCalibration=True
49 )
51 camera = cT.PrerequisiteInput(
52 name="camera",
53 doc="Input camera to use for gain lookup.",
54 storageClass="Camera",
55 dimensions=("instrument",),
56 lookupFunction=lookupStaticCalibration,
57 isCalibration=True,
58 )
60 outputStats = cT.Output(
61 name="calibStats",
62 doc="Output statistics from cp_verify.",
63 storageClass="StructuredDataDict",
64 dimensions=["instrument", "detector"],
65 )
68class CpVerifyCalibConfig(pipeBase.PipelineTaskConfig,
69 pipelineConnections=CpVerifyCalibConnections):
70 """Configuration parameters for CpVerifyCalibTask.
71 """
72 # Statistics options.
73 useReadNoise = pexConfig.Field(
74 dtype=bool,
75 doc="Compare sigma against read noise?",
76 default=True,
77 )
78 numSigmaClip = pexConfig.Field(
79 dtype=float,
80 doc="Rejection threshold (sigma) for statistics clipping.",
81 default=5.0,
82 )
83 clipMaxIter = pexConfig.Field(
84 dtype=int,
85 doc="Max number of clipping iterations to apply.",
86 default=3,
87 )
89 # Keywords and statistics to measure from different sources.
90 calibStatKeywords = pexConfig.DictField(
91 keytype=str,
92 itemtype=str,
93 doc="Calib statistics to run.",
94 default={},
95 )
98class CpVerifyCalibTask(pipeBase.PipelineTask):
99 """Main statistic measurement and validation class.
101 This operates on a generic calibration, and is designed to be
102 subclassed so specific calibrations can apply their own validation
103 methods.
104 """
106 ConfigClass = CpVerifyCalibConfig
107 _DefaultName = 'cpVerifyCalib'
109 def run(self, inputCalib, camera=None, exposure=None):
110 """Calculate quality statistics and verify they meet the requirements
111 for a calibration.
113 Parameters
114 ----------
115 inputCalib : `lsst.ip.isr.IsrCalib`
116 The calibration to be measured.
117 camera : `lsst.afw.cameraGeom.Camera`, optional
118 Input camera.
119 exposure : `lsst.afw.image.Exposure`, optional
120 Dummy exposure to identify a particular calibration
121 dataset.
123 Returns
124 -------
125 result : `lsst.pipe.base.Struct`
126 Result struct with components:
127 - ``outputStats`` : `dict`
128 The output measured statistics.
130 Notes
131 -----
132 The outputStats should have a yaml representation of the form
133 (with STAT and TEST being the appropriate statistic and test
134 names)
136 DET:
137 STAT: value
138 STAT2: value
139 AMP:
140 STAT: value
141 STAT2: value
142 VERIFY:
143 TEST: boolean
144 SUCCESS: boolean
146 """
147 outputStats = {}
148 outputStats['AMP'] = self.amplifierStatistics(inputCalib, camera=camera)
149 outputStats['DET'] = self.detectorStatistics(inputCalib, camera=camera)
150 outputStats['VERIFY'], outputStats['SUCCESS'] = self.verify(inputCalib, outputStats, camera=camera)
152 return pipeBase.Struct(
153 outputStats=outputStats,
154 )
156 # Methods that need to be implemented by the calibration-level subclasses.
157 def detectorStatistics(self, inputCalib, camera=None, exposure=None):
158 """Calculate detector level statistics from the calibration.
160 Parameters
161 ----------
162 inputCalib : `lsst.ip.isr.IsrCalib`
163 The calibration to verify.
165 Returns
166 -------
167 outputStatistics : `dict` [`str`, scalar]
168 A dictionary of the statistics measured and their values.
169 camera : `lsst.afw.cameraGeom.Camera`, optional
170 Input camera.
171 exposure : `lsst.afw.image.Exposure`, optional
172 Dummy exposure to identify a particular calibration
173 dataset.
175 Raises
176 ------
177 NotImplementedError :
178 This method must be implemented by the calibration-type
179 subclass.
180 """
181 raise NotImplementedError("Subclasses must implement detector statistics method.")
183 def amplifierStatistics(self, inputCalib, camera=None, exposure=None):
184 """Calculate amplifier level statistics from the calibration.
186 Parameters
187 ----------
188 inputCalib : `lsst.ip.isr.IsrCalib`
189 The calibration to verify.
190 camera : `lsst.afw.cameraGeom.Camera`, optional
191 Input camera.
192 exposure : `lsst.afw.image.Exposure`, optional
193 Dummy exposure to identify a particular calibration
194 dataset.
196 Returns
197 -------
198 outputStatistics : `dict` [`str`, scalar]
199 A dictionary of the statistics measured and their values.
201 Raises
202 ------
203 NotImplementedError :
204 This method must be implemented by the calibration-type
205 subclass.
206 """
207 raise NotImplementedError("Subclasses must implement amplifier statistics method.")
209 def verify(self, inputCalib, statisticsDict, camera=None, exposure=None):
210 """Verify that the measured calibration meet the verification criteria.
212 Parameters
213 ----------
214 inputCalib : `lsst.ip.isr.IsrCalib`
215 The calibration to verify.
216 statisticsDictionary : `dict` [`str`, `dict` [`str`, scalar]],
217 Dictionary of measured statistics. The inner dictionary
218 should have keys that are statistic names (`str`) with
219 values that are some sort of scalar (`int` or `float` are
220 the mostly likely types).
221 camera : `lsst.afw.cameraGeom.Camera`, optional
222 Input camera.
223 exposure : `lsst.afw.image.Exposure`, optional
224 Dummy exposure to identify a particular calibration
225 dataset.
227 Returns
228 -------
229 outputStatistics : `dict` [`str`, `dict` [`str`, `bool`]]
230 A dictionary indexed by the amplifier name, containing
231 dictionaries of the verification criteria.
232 success : `bool`
233 A boolean indicating whether all tests have passed.
235 Raises
236 ------
237 NotImplementedError :
238 This method must be implemented by the calibration-type
239 subclass.
240 """
241 raise NotImplementedError("Subclasses must implement verification criteria.")