Coverage for tests/test_linearizeSquared.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

104 statements  

1# 

2# LSST Data Management System 

3# Copyright 2017 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

21# 

22import unittest 

23import pickle 

24import logging 

25 

26import numpy as np 

27 

28import lsst.utils.tests 

29import lsst.geom 

30import lsst.afw.image as afwImage 

31import lsst.afw.cameraGeom as cameraGeom 

32from lsst.afw.geom.testUtils import BoxGrid 

33from lsst.afw.image.testUtils import makeRampImage 

34from lsst.ip.isr import Linearizer 

35 

36 

37def refLinearizeSquared(image, detector): 

38 """!Basic implementation of squared non-linearization correction 

39 

40 corr = uncorr + coeff[0]*uncorr^2 

41 

42 @param[in,out] image image to correct in place (an lsst.afw.image.Image of some type) 

43 @param[in] detector detector info (an lsst.afw.cameraGeom.Detector) 

44 """ 

45 ampInfoCat = detector.getAmplifiers() 

46 for ampInfo in ampInfoCat: 

47 bbox = ampInfo.getBBox() 

48 sqCoeff = ampInfo.getLinearityCoeffs()[0] 

49 viewArr = image.Factory(image, bbox).getArray() 

50 viewArr[:] = viewArr + sqCoeff*viewArr**2 

51 

52 

53class LinearizeSquaredTestCase(lsst.utils.tests.TestCase): 

54 """!Unit tests for LinearizeSquared""" 

55 

56 def setUp(self): 

57 # the following values are all arbitrary, but sane and varied 

58 self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(-31, 22), lsst.geom.Extent2I(100, 85)) 

59 self.numAmps = (2, 3) 

60 self.sqCoeffs = np.array([[0, 5e-6, 2.5e-5], [1e-5, 1.1e-6, 2.1e-5]], dtype=float) 

61 self.detector = self.makeDetector() 

62 

63 def tearDown(self): 

64 # destroy LSST objects so memory test passes 

65 self.bbox = None 

66 self.detector = None 

67 

68 def testBasics(self): 

69 """!Test basic functionality of LinearizeSquared 

70 """ 

71 for imageClass in (afwImage.ImageF, afwImage.ImageD): 

72 inImage = makeRampImage(bbox=self.bbox, start=-5, stop=2500, imageClass=imageClass) 

73 

74 measImage = inImage.Factory(inImage, True) 

75 linCorr = Linearizer(detector=self.detector) 

76 linRes = linCorr.applyLinearity(image=measImage, detector=self.detector) 

77 desNumLinearized = np.sum(self.sqCoeffs.flatten() > 0) 

78 self.assertEqual(linRes.numLinearized, desNumLinearized) 

79 self.assertEqual(linRes.numAmps, len(self.detector.getAmplifiers())) 

80 

81 refImage = inImage.Factory(inImage, True) 

82 refLinearizeSquared(image=refImage, detector=self.detector) 

83 

84 self.assertImagesAlmostEqual(refImage, measImage) 

85 

86 # make sure logging is accepted 

87 log = logging.getLogger("lsst.ip.isr.LinearizeSquared") 

88 linRes = linCorr.applyLinearity(image=measImage, detector=self.detector, log=log) 

89 

90 def testKnown(self): 

91 """!Test a few known values 

92 """ 

93 numAmps = (2, 2) 

94 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(4, 4)) 

95 # make a 4x4 image with 4 identical 2x2 subregions that flatten to -1, 0, 1, 2 

96 im = afwImage.ImageF(bbox) 

97 imArr = im.getArray() 

98 imArr[:, :] = np.array(((-1, 0, -1, 0), 

99 (1, 2, 1, 2), 

100 (-1, 0, -1, 0), 

101 (1, 2, 1, 2)), dtype=imArr.dtype) 

102 

103 sqCoeffs = np.array(((0, 0.11), (-0.15, -12))) 

104 detector = self.makeDetector(bbox=bbox, numAmps=numAmps, sqCoeffs=sqCoeffs) 

105 ampInfoCat = detector.getAmplifiers() 

106 

107 linSq = Linearizer(detector=detector) 

108 linSq.applyLinearity(im, detector=detector) 

109 

110 # amp 0 has 0 squared coefficient and so makes no correction 

111 imArr0 = im.Factory(im, ampInfoCat[0].getBBox()).getArray() 

112 linCoeff0 = ampInfoCat[0].getLinearityCoeffs()[0] 

113 self.assertEqual(0, linCoeff0) 

114 self.assertFloatsAlmostEqual(imArr0.flatten(), (-1, 0, 1, 2)) 

115 

116 # test all amps 

117 for ampInfo in ampInfoCat: 

118 imArr = im.Factory(im, ampInfo.getBBox()).getArray() 

119 linCoeff = ampInfo.getLinearityCoeffs()[0] 

120 expect = np.array((-1 + linCoeff, 0, 1 + linCoeff, 2 + 4*linCoeff), dtype=imArr.dtype) 

121 self.assertFloatsAlmostEqual(imArr.flatten(), expect) 

122 

123 def testPickle(self): 

124 """!Test that a LinearizeSquared can be pickled and unpickled 

125 """ 

126 inImage = makeRampImage(bbox=self.bbox, start=-5, stop=2500) 

127 linSq = Linearizer(detector=self.detector) 

128 

129 refImage = inImage.Factory(inImage, True) 

130 refNumOutOfRange = linSq.applyLinearity(refImage, detector=self.detector) 

131 

132 pickledStr = pickle.dumps(linSq) 

133 restoredLlt = pickle.loads(pickledStr) 

134 

135 measImage = inImage.Factory(inImage, True) 

136 measNumOutOfRange = restoredLlt.applyLinearity(measImage, detector=self.detector) 

137 

138 self.assertEqual(refNumOutOfRange, measNumOutOfRange) 

139 self.assertImagesAlmostEqual(refImage, measImage) 

140 

141 def makeDetector(self, bbox=None, numAmps=None, sqCoeffs=None, linearityType="Squared"): 

142 """!Make a detector 

143 

144 @param[in] bbox bounding box for image 

145 @param[n] numAmps x,y number of amplifiers (pair of int) 

146 @param[in] sqCoeffs square coefficient for each amplifier (2D array of float) 

147 @param[in] detName detector name (a str) 

148 @param[in] detID detector ID (an int) 

149 @param[in] detSerial detector serial numbe (a str) 

150 @param[in] linearityType name of linearity type (a str) 

151 

152 @return a detector (an lsst.afw.cameraGeom.Detector) 

153 """ 

154 bbox = bbox if bbox is not None else self.bbox 

155 numAmps = numAmps if numAmps is not None else self.numAmps 

156 sqCoeffs = sqCoeffs if sqCoeffs is not None else self.sqCoeffs 

157 

158 detName = "det_a" 

159 detId = 1 

160 detSerial = "123" 

161 orientation = cameraGeom.Orientation() 

162 pixelSize = lsst.geom.Extent2D(1, 1) 

163 

164 camBuilder = cameraGeom.Camera.Builder("fakeCam") 

165 detBuilder = camBuilder.add(detName, detId) 

166 detBuilder.setSerial(detSerial) 

167 detBuilder.setBBox(bbox) 

168 detBuilder.setOrientation(orientation) 

169 detBuilder.setPixelSize(pixelSize) 

170 

171 boxArr = BoxGrid(box=bbox, numColRow=numAmps) 

172 for i in range(numAmps[0]): 

173 for j in range(numAmps[1]): 

174 ampInfo = cameraGeom.Amplifier.Builder() 

175 ampInfo.setName("amp %d_%d" % (i + 1, j + 1)) 

176 ampInfo.setBBox(boxArr[i, j]) 

177 ampInfo.setLinearityType(linearityType) 

178 ampInfo.setLinearityCoeffs([sqCoeffs[i, j]]) 

179 detBuilder.append(ampInfo) 

180 

181 return detBuilder 

182 

183 

184class MemoryTester(lsst.utils.tests.MemoryTestCase): 

185 pass 

186 

187 

188def setup_module(module): 

189 lsst.utils.tests.init() 

190 

191 

192if __name__ == "__main__": 192 ↛ 193line 192 didn't jump to line 193, because the condition on line 192 was never true

193 lsst.utils.tests.init() 

194 unittest.main()