Coverage for tests/test_approximate.py: 20%

79 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-19 04:54 -0700

1# This file is part of afw. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://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 <https://www.gnu.org/licenses/>. 

21 

22import unittest 

23 

24import numpy as np 

25 

26import lsst.utils.tests 

27import lsst.afw.display as afwDisplay 

28import lsst.geom 

29import lsst.afw.image as afwImage 

30import lsst.afw.math as afwMath 

31import lsst.pex.exceptions as pexExcept 

32 

33afwDisplay.setDefaultMaskTransparency(75) 

34# Set to True to display things 

35display = False 

36 

37 

38class ApproximateTestCase(lsst.utils.tests.TestCase): 

39 def makeRamp(self, binsize=1): 

40 """Make a linear ramp""" 

41 ramp = afwImage.MaskedImageF(20, 40) 

42 

43 x = [] 

44 for i in range(ramp.getWidth()): 

45 x.append((i + 0.5)*binsize - 0.5) 

46 

47 y = [] 

48 for j in range(ramp.getHeight()): 

49 y.append((j + 0.5)*binsize - 0.5) 

50 

51 var = 1 

52 rampCoeffs = (1000, 1, 1) 

53 for i in range(ramp.getHeight()): 

54 for j in range(ramp.getWidth()): 

55 ramp[j, i, afwImage.LOCAL] = (rampCoeffs[0] + rampCoeffs[1]*x[j] + rampCoeffs[2]*y[i], 

56 0x0, var) 

57 

58 return ramp, rampCoeffs, x, y 

59 

60 def testLinearRamp(self): 

61 """Fit a ramp""" 

62 

63 binsize = 1 

64 ramp, rampCoeffs, xVec, yVec = self.makeRamp(binsize) 

65 # Add a (labelled) bad value 

66 ramp[ramp.getWidth()//2, ramp.getHeight()//2, afwImage.LOCAL] = (0, 0x1, np.nan) 

67 

68 if display: 

69 afwDisplay.Display(frame=0).mtv(ramp, title=self._testMethodName + ": Input") 

70 # Here's the range that the approximation should be valid (and also the 

71 # bbox of the image returned by getImage) 

72 bbox = lsst.geom.BoxI(lsst.geom.PointI(0, 0), 

73 lsst.geom.PointI(binsize*ramp.getWidth() - 1, 

74 binsize*ramp.getHeight() - 1)) 

75 

76 order = 3 # 1 would be enough to fit the ramp 

77 actrl = afwMath.ApproximateControl( 

78 afwMath.ApproximateControl.CHEBYSHEV, order) 

79 approx = afwMath.makeApproximate(xVec, yVec, ramp, bbox, actrl) 

80 

81 for i, aim in enumerate([approx.getImage(), 

82 approx.getMaskedImage().getImage(), 

83 ]): 

84 if i == 0 and display: 

85 disp = afwDisplay.Display(frame=1) 

86 disp.mtv(aim, title=self._testMethodName + ": Interpolated") 

87 with disp.Buffering(): 

88 for x in xVec: 

89 for y in yVec: 

90 disp.dot('+', x, y, size=0.4) 

91 

92 for x, y in aim.getBBox().getCorners(): 

93 self.assertEqual( 

94 aim[x, y, afwImage.LOCAL], rampCoeffs[0] + rampCoeffs[1]*x + rampCoeffs[1]*y) 

95 

96 def testChebyshevEqualOrder(self): 

97 """Check that we enforce the condition orderX == orderY""" 

98 

99 self.assertRaises(pexExcept.InvalidParameterError, 

100 lambda: 

101 afwMath.ApproximateControl(afwMath.ApproximateControl.CHEBYSHEV, 1, 2)) 

102 

103 def testNoFinitePoints(self): 

104 """Check that makeApproximate throws a RuntimeError if grid has no finite points and weights to fit 

105 """ 

106 binsize = 1 

107 for badValue in [(3, 0x1, 0), (np.nan, 0x1, 1)]: 

108 ramp, rampCoeffs, xVec, yVec = self.makeRamp(binsize) 

109 ramp.set(badValue) 

110 bbox = lsst.geom.BoxI(lsst.geom.PointI(0, 0), lsst.geom.PointI(binsize*ramp.getWidth() - 1, 

111 binsize*ramp.getHeight() - 1)) 

112 order = 2 

113 actrl = afwMath.ApproximateControl( 

114 afwMath.ApproximateControl.CHEBYSHEV, order) 

115 self.assertRaises(pexExcept.RuntimeError, 

116 lambda: afwMath.makeApproximate(xVec, yVec, ramp, bbox, actrl)) 

117 

118 def testLinearRampAsBackground(self): 

119 """Fit a ramp""" 

120 

121 ramp, rampCoeffs = self.makeRamp()[0:2] 

122 

123 if display: 

124 afwDisplay.Display(frame=0).mtv(ramp, title=self._testMethodName + ": Input") 

125 # Here's the range that the approximation should be valid (and also the 

126 # bbox of the image returned by getImage) 

127 bkgd = afwMath.makeBackground(ramp, afwMath.BackgroundControl(10, 10)) 

128 

129 orderMax = 3 # 1 would be enough to fit the ramp 

130 for order in range(orderMax + 1): 

131 actrl = afwMath.ApproximateControl( 

132 afwMath.ApproximateControl.CHEBYSHEV, order) 

133 

134 approx = bkgd.getApproximate(actrl) 

135 # Get the Image, the MaskedImage, and the Image with a truncated 

136 # expansion 

137 for i, aim in enumerate([approx.getImage(), 

138 approx.getMaskedImage().getImage(), 

139 approx.getImage( 

140 order - 1 if order > 1 else -1), 

141 ]): 

142 if display and (i == 0 and order == 1): 

143 afwDisplay.Display(frame=1).mtv(aim, title=self._testMethodName + ": Interpolated") 

144 

145 for x, y in aim.getBBox().getCorners(): 

146 val = np.mean(aim.getArray()) if order == 0 else \ 

147 rampCoeffs[0] + rampCoeffs[1]*x + rampCoeffs[1]*y 

148 

149 self.assertEqual(aim[x, y, afwImage.LOCAL], val) 

150 # Check that we can't "truncate" the expansion to a higher order than 

151 # we requested 

152 self.assertRaises(pexExcept.InvalidParameterError, 

153 lambda: approx.getImage(orderMax + 1, orderMax + 1)) 

154 

155 

156class MemoryTester(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()