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