Coverage for tests/test_spline.py: 24%

83 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-08-01 01:19 -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 

22""" 

23Tests for Splines 

24 

25Run with: 

26 python test_spline.py 

27or 

28 pytest test_spline.py 

29""" 

30import math 

31import unittest 

32 

33import lsst.utils.tests 

34import lsst.afw.math as afwMath 

35 

36 

37class SplineTestCase(unittest.TestCase): 

38 """A test case for Image""" 

39 

40 def smooth(self, x, differentiate=False): 

41 if differentiate: 

42 return math.cos(x) 

43 else: 

44 return math.sin(x) 

45 

46 def noDerivative(self, x): 

47 if False: 

48 return math.sin(x) 

49 else: 

50 if x < 1: 

51 return 1 - x 

52 else: 

53 return 0 

54 

55 def setUp(self): 

56 x, x2, ySin, yND = [], [], [], [] 

57 for i in range(0, 40): 

58 x.append(0.1*i) 

59 for j in range(4): 

60 x2.append(0.1*(i + 0.25*j)) 

61 

62 ySin.append(self.smooth(x[i])) 

63 yND.append(self.noDerivative(x[i])) 

64 

65 self.x = x 

66 self.x2 = x2 

67 self.yND = yND 

68 self.ySin = ySin 

69 

70 def tearDown(self): 

71 del self.x 

72 del self.x2 

73 del self.ySin 

74 del self.yND 

75 

76 def testNaturalSpline1(self): 

77 """Test fitting a natural spline to a smooth function""" 

78 gamma = 0 

79 sp = afwMath.TautSpline(self.x, self.ySin, gamma) 

80 

81 y2 = [] 

82 sp.interpolate(self.x2, y2) 

83 

84 for x, y in zip(self.x2, y2): 

85 self.assertAlmostEqual(y, self.smooth(x), 1) # fails at 2 places! 

86 

87 def testNaturalSplineDerivative1(self): 

88 """Test fitting a natural spline to a smooth function and finding its derivative""" 

89 sp = afwMath.TautSpline(self.x, self.ySin) 

90 

91 y2 = [] 

92 sp.derivative(self.x2, y2) 

93 

94 for x, y in zip(self.x2, y2): 

95 self.assertAlmostEqual(y, self.smooth(x, True), delta=1.5e-3) 

96 

97 def testNaturalSpline2(self): 

98 """Test fitting a natural spline to a non-differentiable function (we basically fail)""" 

99 gamma = 0 

100 sp = afwMath.TautSpline(self.x, self.yND, gamma) 

101 

102 y2 = [] 

103 sp.interpolate(self.x2, y2) 

104 

105 for x, y in zip(self.x2, y2): 

106 # fails at 2 places! 

107 self.assertAlmostEqual(y, self.noDerivative(x), 1) 

108 

109 def testTautSpline1(self): 

110 """Test fitting a taut spline to a smooth function""" 

111 gamma = 2.5 

112 sp = afwMath.TautSpline(self.x, self.ySin, gamma) 

113 

114 y2 = [] 

115 sp.interpolate(self.x2, y2) 

116 

117 for x, y in zip(self.x2, y2): 

118 self.assertAlmostEqual(y, self.smooth(x), 4) 

119 

120 def testTautSpline2(self): 

121 """Test fitting a taut spline to a non-differentiable function""" 

122 gamma = 2.5 

123 sp = afwMath.TautSpline(self.x, self.yND, gamma) 

124 

125 y2 = [] 

126 sp.interpolate(self.x2, y2) 

127 

128 for x, y in zip(self.x2, y2): 

129 self.assertAlmostEqual(y, self.noDerivative(x)) 

130 

131 def testRootFinding(self): 

132 """Test finding roots of Spline = value""" 

133 

134 gamma = 2.5 

135 sp = afwMath.TautSpline(self.x, self.yND, gamma) 

136 

137 for value in (0.1, 0.5): 

138 self.assertEqual( 

139 sp.roots(value, self.x[0], self.x[-1])[0], 1 - value) 

140 

141 if False: 

142 y = [] 

143 sp.interpolate(self.x, y) 

144 for x, y in zip(self.x, y): 

145 print(x, y) 

146 # 

147 # Solve sin(x) = 0.5 

148 # 

149 sp = afwMath.TautSpline(self.x, self.ySin) 

150 roots = [math.degrees(x) for x in sp.roots(0.5, self.x[0], self.x[-1])] 

151 self.assertAlmostEqual(roots[0], 30, 5) 

152 self.assertAlmostEqual(roots[1], 150, 5) 

153 

154 

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

156 pass 

157 

158 

159def setup_module(module): 

160 lsst.utils.tests.init() 

161 

162 

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

164 lsst.utils.tests.init() 

165 unittest.main()