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

66 statements  

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""" 

25 

26import unittest 

27import numpy as np 

28 

29import lsst.utils 

30import lsst.utils.tests 

31 

32import lsst.ip.isr as ipIsr 

33import lsst.cp.pipe as cpPipe 

34import lsst.afw.cameraGeom as cameraGeom 

35 

36 

37class BfkSolveTaskTestCase(lsst.utils.tests.TestCase): 

38 """A test case for the brighter fatter kernel solver. 

39 """ 

40 

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() 

49 

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) 

64 

65 self.ptc.gain['amp 1'] = 1.0 

66 self.ptc.noise['amp 1'] = 5.0 

67 

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]]) 

72 

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]]) 

88 

89 def test_averaged(self): 

90 """Test "averaged" brighter-fatter kernel. 

91 """ 

92 task = cpPipe.BrighterFatterKernelSolveTask() 

93 

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) 

96 

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) 

103 

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) 

106 

107 def test_quadratic(self): 

108 """Test quadratic correlation solver. 

109 

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) 

119 

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) 

133 

134 ptc.gain['amp 1'] = 1.0 

135 ptc.noise['amp 1'] = 5.0 

136 

137 results = task.run(ptc, ['this is a dummy exposure'], self.camera, {'detector': 1}) 

138 

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) 

154 

155 

156class TestMemory(lsst.utils.tests.MemoryTestCase): 

157 pass 

158 

159 

160def setup_module(module): 

161 lsst.utils.tests.init() 

162 

163 

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()