Coverage for tests/test_Box.py: 19%

119 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-05-24 02:22 -0700

1# 

2# LSST Data Management System 

3# See COPYRIGHT file at the top of the source tree. 

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 <https://www.lsstcorp.org/LegalNotices/>. 

21# 

22 

23import pickle 

24try: 

25 import yaml 

26except ImportError: 

27 yaml = None 

28 

29import math 

30import unittest 

31 

32import numpy as np 

33 

34from lsst.sphgeom import (Angle, AngleInterval, Box, CONTAINS, DISJOINT, 

35 LonLat, NormalizedAngle, NormalizedAngleInterval, 

36 Region, UnitVector3d) 

37 

38 

39class BoxTestCase(unittest.TestCase): 

40 

41 def setUp(self): 

42 np.random.seed(1) 

43 

44 def test_construction(self): 

45 b = Box(Box.allLongitudes(), Box.allLatitudes()) 

46 self.assertTrue(b.isFull()) 

47 b = Box.fromDegrees(-90, -45, 90, 45) 

48 self.assertEqual(b, Box(b.getLon(), b.getLat())) 

49 a = Box.fromRadians(-0.5 * math.pi, -0.25 * math.pi, 

50 0.5 * math.pi, 0.25 * math.pi) 

51 b = Box(LonLat.fromRadians(-0.5 * math.pi, -0.25 * math.pi), 

52 LonLat.fromRadians(0.5 * math.pi, 0.25 * math.pi)) 

53 c = Box(LonLat.fromRadians(0, 0), 

54 Angle(0.5 * math.pi), Angle(0.25 * math.pi)) 

55 d = c.clone() 

56 self.assertEqual(a, b) 

57 self.assertEqual(b, c) 

58 self.assertEqual(c, d) 

59 self.assertNotEqual(id(c), id(d)) 

60 b = Box() 

61 self.assertTrue(b.isEmpty()) 

62 self.assertTrue(Box.empty().isEmpty()) 

63 self.assertTrue(Box.full().isFull()) 

64 

65 def test_comparison_operators(self): 

66 self.assertEqual(Box(LonLat.fromDegrees(45, 45)), 

67 LonLat.fromDegrees(45, 45)) 

68 self.assertEqual(Box.fromDegrees(90, -45, 180, 45), 

69 Box(NormalizedAngleInterval.fromDegrees(90, 180), 

70 AngleInterval.fromDegrees(-45, 45))) 

71 self.assertNotEqual(Box(LonLat.fromDegrees(45, 45)), 

72 LonLat.fromDegrees(45, 90)) 

73 self.assertNotEqual(Box.fromDegrees(90, -45, 180, 45), 

74 Box.fromDegrees(90, -45, 180, 90)) 

75 

76 def test_center_and_dimensions(self): 

77 b = Box.fromDegrees(-90, -45, 90, 45) 

78 self.assertEqual(b.getCenter(), LonLat.fromDegrees(0, 0)) 

79 self.assertEqual(b.getWidth(), Angle.fromDegrees(180)) 

80 self.assertEqual(b.getHeight(), Angle.fromDegrees(90)) 

81 self.assertEqual(b.getLon().getA(), NormalizedAngle.fromDegrees(-90)) 

82 self.assertEqual(b.getLat().getB(), Angle.fromDegrees(45)) 

83 

84 def test_relationships(self): 

85 b1 = Box.fromDegrees(90, 0, 180, 45) 

86 p = LonLat.fromDegrees(135, 10) 

87 self.assertTrue(p in b1) 

88 self.assertTrue(b1.contains(p)) 

89 b2 = Box.fromDegrees(135, 15, 135, 30) 

90 self.assertTrue(b1.contains(b2)) 

91 self.assertTrue(b2.isWithin(b1)) 

92 b3 = Box.fromDegrees(0, -45, 90, 0) 

93 u = UnitVector3d(1, 1, -1) 

94 self.assertTrue(b1.intersects(b3)) 

95 self.assertTrue(u in b3) 

96 self.assertTrue(b3.contains(u)) 

97 b4 = Box.fromDegrees(200, 10, 300, 20) 

98 self.assertTrue(b1.isDisjointFrom(b4)) 

99 r = b1.relate(LonLat.fromDegrees(135, 10)) 

100 self.assertEqual(r, CONTAINS) 

101 r = b4.relate(b1) 

102 self.assertEqual(r, DISJOINT) 

103 

104 def test_vectorized_contains(self): 

105 b = Box.fromDegrees(200, 10, 300, 20) 

106 x = np.random.rand(5, 3) 

107 y = np.random.rand(5, 3) 

108 z = np.random.rand(5, 3) 

109 c = b.contains(x, y, z) 

110 lon = np.arctan2(y, x) 

111 lat = np.arctan2(z, np.hypot(x, y)) 

112 c2 = b.contains(lon, lat) 

113 for i in range(x.shape[0]): 

114 for j in range(x.shape[1]): 

115 u = UnitVector3d(x[i, j], y[i, j], z[i, j]) 

116 self.assertEqual(c[i, j], b.contains(u)) 

117 self.assertEqual(c2[i, j], b.contains(u)) 

118 # test with non-contiguous memory 

119 c3 = b.contains(x[::2], y[::2], z[::2]) 

120 c4 = b.contains(lon[::2], lat[::2]) 

121 for i in range(x.shape[0], 2): 

122 for j in range(x.shape[1]): 

123 u = UnitVector3d(x[i, j], y[i, j], z[i, j]) 

124 self.assertEqual(c3[i//2, j], b.contains(u)) 

125 self.assertEqual(c4[i//2, j], b.contains(u)) 

126 

127 def test_expanding_and_clipping(self): 

128 a = Box.fromDegrees(0, 0, 10, 10) 

129 b = (a.expandedTo(LonLat.fromDegrees(20, 20)) 

130 .expandedTo(Box.fromDegrees(0, 0, 30, 10)) 

131 .clippedTo(Box.fromDegrees(10, 10, 15, 15)) 

132 .clippedTo(LonLat.fromDegrees(11, 11))) 

133 a.expandTo(LonLat.fromDegrees(20, 20)) 

134 a.expandTo(Box.fromDegrees(0, 0, 30, 10)) 

135 a.clipTo(Box.fromDegrees(10, 10, 15, 15)) 

136 a.clipTo(LonLat.fromDegrees(11, 11)) 

137 self.assertEqual(a, b) 

138 self.assertEqual(a, LonLat.fromDegrees(11, 11)) 

139 a.clipTo(LonLat.fromDegrees(0, 0)) 

140 self.assertTrue(a.isEmpty()) 

141 

142 def test_dilation_and_erosion(self): 

143 a = Box.fromRadians(0.5, -0.5, 1.5, 0.5) 

144 b = a.dilatedBy(Angle(0.5), Angle(0.5)).erodedBy(Angle(1), Angle(1)) 

145 a.dilateBy(Angle(0.5), Angle(0.5)).erodeBy(Angle(1), Angle(1)) 

146 self.assertEqual(a, b) 

147 self.assertEqual(a, LonLat.fromRadians(1, 0)) 

148 

149 def test_codec(self): 

150 b = Box.fromRadians(0, 0, 1, 1) 

151 s = b.encode() 

152 self.assertEqual(Box.decode(s), b) 

153 self.assertEqual(Region.decode(s), b) 

154 

155 def test_string(self): 

156 b = Box.fromRadians(0, 0, 1, 1) 

157 self.assertEqual(str(b), 'Box([0.0, 1.0], [0.0, 1.0])') 

158 self.assertEqual( 

159 repr(b), 

160 'Box(NormalizedAngleInterval.fromRadians(0.0, 1.0), ' 

161 'AngleInterval.fromRadians(0.0, 1.0))' 

162 ) 

163 self.assertEqual(b, eval(repr(b), dict( 

164 AngleInterval=AngleInterval, Box=Box, 

165 NormalizedAngleInterval=NormalizedAngleInterval 

166 ))) 

167 

168 def test_pickle(self): 

169 a = Box.fromDegrees(0, 0, 10, 10) 

170 b = pickle.loads(pickle.dumps(a, pickle.HIGHEST_PROTOCOL)) 

171 self.assertEqual(a, b) 

172 

173 @unittest.skipIf(not yaml, "YAML module can not be imported") 

174 def test_yaml(self): 

175 a = Box.fromDegrees(0, 0, 10, 10) 

176 b = yaml.safe_load(yaml.dump(a)) 

177 self.assertEqual(a, b) 

178 

179 

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

181 unittest.main()