Coverage for python/lsst/cp/verify/verifyDefects.py: 23%
Shortcuts 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
Shortcuts 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 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 numpy as np
22import scipy
24from .verifyStats import CpVerifyStatsConfig, CpVerifyStatsTask, CpVerifyStatsConnections
27__all__ = ['CpVerifyDefectsConfig', 'CpVerifyDefectsTask']
30class CpVerifyDefectsConfig(CpVerifyStatsConfig,
31 pipelineConnections=CpVerifyStatsConnections):
32 """Inherits from base CpVerifyStatsConfig.
33 """
35 def setDefaults(self):
36 super().setDefaults()
37 self.maskNameList = ['BAD'] # noqa F821
39 self.imageStatKeywords = {'DEFECT_PIXELS': 'NMASKED', # noqa F821
40 'OUTLIERS': 'NCLIPPED',
41 'MEDIAN': 'MEDIAN',
42 'STDEV': 'STDEVCLIP',
43 'MIN': 'MIN',
44 'MAX': 'MAX', }
45 self.unmaskedImageStatKeywords = {'UNMASKED_MIN': 'MIN', # noqa F821
46 'UNMASKED_MAX': 'MAX',
47 'UNMASKED_OUTLIERS': 'NCLIPPED', }
50class CpVerifyDefectsTask(CpVerifyStatsTask):
51 """Defects verification sub-class, implementing the verify method.
53 This also applies additional image processing statistics.
54 """
55 ConfigClass = CpVerifyDefectsConfig
56 _DefaultName = 'cpVerifyDefects'
58 def imageStatistics(self, exposure, statControl):
59 """Measure additional defect statistics.
61 This calls the parent class method first, then adds additional
62 measurements.
64 Parameters
65 ----------
66 exposure : `lsst.afw.image.Exposure`
67 Exposure containing the ISR processed data to measure.
68 statControl : `lsst.afw.math.StatControl`
69 Statistics control object with parameters defined by
70 the config.
72 Returns
73 -------
74 outputStatistics : `dict` [`str`, `dict` [`str`, scalar]]
75 A dictionary indexed by the amplifier name, containing
76 dictionaries of the statistics measured and their values.
77 """
78 outputStatistics = super().imageStatistics(exposure, statControl)
80 # Is this a useful test? It saves having to do chi^2 fits,
81 # which are going to be biased by the bulk of points.
82 for amp in exposure.getDetector():
83 ampName = amp.getName()
84 ampExp = exposure.Factory(exposure, amp.getBBox())
86 normImage = ampExp.getImage()
87 normArray = normImage.getArray()
89 normArray -= outputStatistics[ampName]['MEDIAN']
90 normArray /= outputStatistics[ampName]['STDEV']
92 probability = scipy.stats.norm.pdf(normArray)
93 outliers = np.where(probability < 1.0 / probability.size, 1.0, 0.0)
94 outputStatistics[ampName]['STAT_OUTLIERS'] = np.sum(outliers)
96 return outputStatistics
98 def verify(self, exposure, statisticsDict):
99 """Verify that the measured statistics meet the verification criteria.
101 Parameters
102 ----------
103 exposure : `lsst.afw.image.Exposure`
104 The exposure the statistics are from.
105 statisticsDictionary : `dict` [`str`, `dict` [`str`, scalar]],
106 Dictionary of measured statistics. The inner dictionary
107 should have keys that are statistic names (`str`) with
108 values that are some sort of scalar (`int` or `float` are
109 the mostly likely types).
111 Returns
112 -------
113 outputStatistics : `dict` [`str`, `dict` [`str`, `bool`]]
114 A dictionary indexed by the amplifier name, containing
115 dictionaries of the verification criteria.
116 success : `bool`
117 A boolean indicating if all tests have passed.
118 """
119 ampStats = statisticsDict['AMP']
120 verifyStats = {}
121 success = True
122 for ampName, stats in ampStats.items():
123 verify = {}
125 # These are not defined in DMTN-101 yet.
126 verify['OUTLIERS'] = bool(stats['UNMASKED_OUTLIERS'] > stats['OUTLIERS'])
127 verify['MIN'] = bool(stats['MIN'] >= stats['UNMASKED_MIN'])
128 verify['MAX'] = bool(stats['MAX'] <= stats['UNMASKED_MAX'])
130 verify['PROB_TEST'] = bool(stats['STAT_OUTLIERS'] == stats['DEFECT_PIXELS'])
132 verify['SUCCESS'] = bool(np.all(list(verify.values())))
133 if verify['SUCCESS'] is False:
134 success = False
136 verifyStats[ampName] = verify
138 return {'AMP': verifyStats}, bool(success)