Coverage for tests/test_brighterFatterKernel.py: 29%
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#
2# LSST Data Management System
3#
4# Copyright 2008-2017 AURA/LSST.
5#
6# This product includes software developed by the
7# LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <https://www.lsstcorp.org/LegalNotices/>.
22#
23"""Test cases for lsst.cp.pipe.BrighterFatterKernelSolveTask.
24"""
26import unittest
27import numpy as np
29import lsst.utils
30import lsst.utils.tests
32import lsst.ip.isr as ipIsr
33import lsst.cp.pipe as cpPipe
34import lsst.afw.cameraGeom as cameraGeom
37class BfkSolveTaskTestCase(lsst.utils.tests.TestCase):
38 """A test case for the brighter fatter kernel solver.
39 """
41 def setUp(self):
42 """Set up a plausible PTC dataset, with 1% of the expected variance
43 shifted into covariance terms.
44 """
45 cameraBuilder = cameraGeom.Camera.Builder('fake camera')
46 detectorWrapper = cameraGeom.testUtils.DetectorWrapper(numAmps=1, cameraBuilder=cameraBuilder)
47 self.detector = detectorWrapper.detector
48 self.camera = cameraBuilder.finish()
50 self.defaultConfig = cpPipe.BrighterFatterKernelSolveConfig()
51 self.ptc = ipIsr.PhotonTransferCurveDataset(ampNames=['amp 1'], ptcFitType='FULLCOVARIANCE',
52 covMatrixSide=3)
53 self.ptc.expIdMask['amp 1'] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
54 self.ptc.finalMeans['amp 1'] = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
55 self.ptc.rawMeans['amp 1'] = self.ptc.finalMeans['amp 1']
56 self.ptc.finalVars['amp 1'] = 0.99 * np.array(self.ptc.finalMeans['amp 1'], dtype=float)
57 self.ptc.covariances['amp 1'] = []
58 for mean, variance in zip(self.ptc.finalMeans['amp 1'], self.ptc.finalVars['amp 1']):
59 residual = mean - variance
60 covariance = [[variance, 0.5 * residual, 0.1 * residual],
61 [0.2 * residual, 0.1 * residual, 0.05 * residual],
62 [0.025 * residual, 0.015 * residual, 0.01 * residual]]
63 self.ptc.covariances['amp 1'].append(covariance)
65 self.ptc.gain['amp 1'] = 1.0
66 self.ptc.noise['amp 1'] = 5.0
68 # This is empirically determined from the above parameters.
69 self.ptc.aMatrix['amp 1'] = np.array([[2.14329806e-06, -4.28659612e-07, -5.35824515e-08],
70 [-1.07164903e-06, -2.14329806e-07, -3.21494709e-08],
71 [-2.14329806e-07, -1.07164903e-07, -2.14329806e-08]])
73 # This is empirically determined from the above parameters.
74 self.expectation = np.array([[4.88348887e-08, 1.01136877e-07, 1.51784114e-07,
75 1.77570668e-07, 1.51784114e-07, 1.01136877e-07, 4.88348887e-08],
76 [9.42026776e-08, 2.03928507e-07, 3.28428909e-07,
77 4.06714446e-07, 3.28428909e-07, 2.03928507e-07, 9.42026776e-08],
78 [1.24047315e-07, 2.70512582e-07, 4.44123665e-07,
79 5.78099493e-07, 4.44123665e-07, 2.70512582e-07, 1.24047315e-07],
80 [1.31474000e-07, 2.77801372e-07, 3.85123870e-07,
81 -5.42128333e-08, 3.85123870e-07, 2.77801372e-07, 1.31474000e-07],
82 [1.24047315e-07, 2.70512582e-07, 4.44123665e-07,
83 5.78099493e-07, 4.44123665e-07, 2.70512582e-07, 1.24047315e-07],
84 [9.42026776e-08, 2.03928507e-07, 3.28428909e-07,
85 4.06714446e-07, 3.28428909e-07, 2.03928507e-07, 9.42026776e-08],
86 [4.88348887e-08, 1.01136877e-07, 1.51784114e-07,
87 1.77570668e-07, 1.51784114e-07, 1.01136877e-07, 4.88348887e-08]])
89 def test_averaged(self):
90 """Test "averaged" brighter-fatter kernel.
91 """
92 task = cpPipe.BrighterFatterKernelSolveTask()
94 results = task.run(self.ptc, ['this is a dummy exposure'], self.camera, {'detector': 1})
95 self.assertFloatsAlmostEqual(results.outputBFK.ampKernels['amp 1'], self.expectation, atol=1e-5)
97 def test_aMatrix(self):
98 """Test solution from Astier et al. 2019 "A" matrix
99 """
100 config = cpPipe.BrighterFatterKernelSolveConfig()
101 config.useAmatrix = True
102 task = cpPipe.BrighterFatterKernelSolveTask(config=config)
104 results = task.run(self.ptc, ['this is a dummy exposure'], self.camera, {'detector': 1})
105 self.assertFloatsAlmostEqual(results.outputBFK.ampKernels['amp 1'], self.expectation, atol=1e-5)
107 def test_quadratic(self):
108 """Test quadratic correlation solver.
110 This requires a different model for the variance, so cannot
111 use the one generated by setUp. This model is not entirely
112 physical, but will ensure that accidental code changes are
113 detected.
114 """
115 config = cpPipe.BrighterFatterKernelSolveConfig()
116 config.correlationQuadraticFit = True
117 config.forceZeroSum = True
118 task = cpPipe.BrighterFatterKernelSolveTask(config=config)
120 ptc = ipIsr.PhotonTransferCurveDataset(ampNames=['amp 1'], ptcFitType='FULLCOVARIANCE',
121 covMatrixSide=3)
122 ptc.expIdMask['amp 1'] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
123 ptc.finalMeans['amp 1'] = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
124 ptc.rawMeans['amp 1'] = ptc.finalMeans['amp 1']
125 ptc.finalVars['amp 1'] = 9e-5 * np.square(np.array(ptc.finalMeans['amp 1'], dtype=float))
126 ptc.covariances['amp 1'] = []
127 for mean, variance in zip(ptc.finalMeans['amp 1'], ptc.finalVars['amp 1']):
128 residual = variance
129 covariance = [[variance, 0.5 * residual, 0.1 * residual],
130 [0.2 * residual, 0.1 * residual, 0.05 * residual],
131 [0.025 * residual, 0.015 * residual, 0.01 * residual]]
132 ptc.covariances['amp 1'].append(covariance)
134 ptc.gain['amp 1'] = 1.0
135 ptc.noise['amp 1'] = 5.0
137 results = task.run(ptc, ['this is a dummy exposure'], self.camera, {'detector': 1})
139 expectation = np.array([[4.05330882e-08, 2.26654412e-07, 5.66636029e-07, 7.56066176e-07,
140 5.66636029e-07, 2.26654412e-07, 4.05330882e-08],
141 [-6.45220588e-08, 2.99448529e-07, 1.28382353e-06, 1.89099265e-06,
142 1.28382353e-06, 2.99448529e-07, -6.45220588e-08],
143 [-5.98069853e-07, -1.14816176e-06, -2.12178309e-06, -4.75974265e-06,
144 -2.12178309e-06, -1.14816176e-06, -5.98069853e-07],
145 [-1.17959559e-06, -3.52224265e-06, -1.28630515e-05, -6.16863971e-05,
146 -1.28630515e-05, -3.52224265e-06, -1.17959559e-06],
147 [-5.98069853e-07, -1.14816176e-06, -2.12178309e-06, -4.75974265e-06,
148 -2.12178309e-06, -1.14816176e-06, -5.98069853e-07],
149 [-6.45220588e-08, 2.99448529e-07, 1.28382353e-06, 1.89099265e-06,
150 1.28382353e-06, 2.99448529e-07, -6.45220588e-08],
151 [4.05330882e-08, 2.26654412e-07, 5.66636029e-07, 7.56066176e-07,
152 5.66636029e-07, 2.26654412e-07, 4.05330882e-08]])
153 self.assertFloatsAlmostEqual(results.outputBFK.ampKernels['amp 1'], expectation, atol=1e-5)
156class TestMemory(lsst.utils.tests.MemoryTestCase):
157 pass
160def setup_module(module):
161 lsst.utils.tests.init()
164if __name__ == "__main__": 164 ↛ 165line 164 didn't jump to line 165, because the condition on line 164 was never true
165 lsst.utils.tests.init()
166 unittest.main()