Coverage for tests/test_HealpixPixelization.py: 23%

88 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-05-02 03:12 -0700

1# This file is part of sphgeom. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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 software is dual licensed under the GNU General Public License and also 

10# under a 3-clause BSD license. Recipients may choose which of these licenses 

11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, 

12# respectively. If you choose the GPL option then the following text applies 

13# (but note that there is still no warranty even if you opt for BSD instead): 

14# 

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

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

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

18# (at your option) any later version. 

19# 

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

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

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

23# GNU General Public License for more details. 

24# 

25# You should have received a copy of the GNU General Public License 

26# along with this program. If not, see <http://www.gnu.org/licenses/>. 

27 

28import pickle 

29import unittest 

30 

31import hpgeom as hpg 

32import numpy as np 

33 

34try: 

35 import yaml 

36except ImportError: 

37 yaml = None 

38 

39from lsst.sphgeom import Angle, Box, Circle, ConvexPolygon, Ellipse, HealpixPixelization, LonLat, UnitVector3d 

40 

41 

42class HealpixPixelizationTestCase(unittest.TestCase): 

43 """Test HEALPix pixelization.""" 

44 

45 def test_construction(self): 

46 """Test construction of a HealpixPixelization.""" 

47 with self.assertRaises(ValueError): 

48 HealpixPixelization(-1) 

49 h1 = HealpixPixelization(5) 

50 self.assertEqual(h1.level, 5) 

51 self.assertEqual(h1.getLevel(), 5) 

52 self.assertEqual(h1.nside, 32) 

53 h2 = HealpixPixelization(6) 

54 h3 = HealpixPixelization(h2.level) 

55 self.assertNotEqual(h1, h2) 

56 self.assertEqual(h2, h3) 

57 

58 def test_indexing(self): 

59 """Test indexing of HealpixPixelization.""" 

60 h = HealpixPixelization(5) 

61 vec = UnitVector3d(1, 1, 1) 

62 lonlat = LonLat(vec) 

63 pix = hpg.angle_to_pixel(h.nside, lonlat.getLon().asDegrees(), lonlat.getLat().asDegrees()) 

64 self.assertEqual(h.index(UnitVector3d(1, 1, 1)), pix) 

65 

66 def test_pixel(self): 

67 """Test pixel polygon of HealpixPixelization.""" 

68 h = HealpixPixelization(5) 

69 pix_poly = h.pixel(10) 

70 self.assertIsInstance(pix_poly, ConvexPolygon) 

71 

72 def test_envelope(self): 

73 """Test envelope method of HealpixPixelization.""" 

74 # Make the hardest intersection: a region that _just_ 

75 # touches a healpix pixel. 

76 h = HealpixPixelization(5) 

77 pix = hpg.angle_to_pixel(h.nside, 50.0, 20.0) 

78 

79 corners_ra, corners_dec = hpg.boundaries(h.nside, pix, step=1) 

80 

81 # Take the southernmost corner... 

82 smost = np.argmin(corners_dec) 

83 

84 # Choose challenging comparison box corners: 

85 ra_range = np.array([corners_ra[smost] - 0.5, corners_ra[smost] + 0.5]) 

86 dec_range = np.array([corners_dec[smost] - 0.5, corners_dec[smost] + 1e-8]) 

87 

88 # Test the box region 

89 box = Box( 

90 point1=LonLat.fromDegrees(ra_range[0], dec_range[0]), 

91 point2=LonLat.fromDegrees(ra_range[1], dec_range[1]), 

92 ) 

93 # These pixels have been checked to completely overlap the region 

94 self._check_envelope(h, box, [98, 99, 104, 105]) 

95 

96 # Try a polygon region: 

97 poly = ConvexPolygon( 

98 [ 

99 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[0])), 

100 UnitVector3d(LonLat.fromDegrees(ra_range[1], dec_range[0])), 

101 UnitVector3d(LonLat.fromDegrees(ra_range[1], dec_range[1])), 

102 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[1])), 

103 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[0])), 

104 ] 

105 ) 

106 self._check_envelope(h, poly, [98, 99, 104, 105]) 

107 

108 # Try a circle region 

109 circle = Circle( 

110 center=UnitVector3d( 

111 LonLat.fromDegrees((ra_range[0] + ra_range[1]) / 2.0, (dec_range[0] + dec_range[1]) / 2.0) 

112 ), 

113 angle=Angle.fromDegrees((dec_range[1] - dec_range[0]) / 2.0), 

114 ) 

115 self._check_envelope(h, circle, [98, 99, 104, 105]) 

116 

117 def _check_envelope(self, pixelization, region, check_pixels): 

118 """Check the envelope from a region. 

119 

120 Parameters 

121 ---------- 

122 pixelization : `lsst.sphgeom.HealpixPixelization` 

123 region : `lsst.sphgeom.Region` 

124 check_pixels : `list` [`int`] 

125 """ 

126 pixel_range = pixelization.envelope(region) 

127 

128 pixels = [] 

129 for r in pixel_range.ranges(): 

130 pixels.extend(range(r[0], r[1])) 

131 

132 self.assertEqual(pixels, check_pixels) 

133 

134 def test_interior(self): 

135 """Test interior method of HealpixPixelization.""" 

136 h = HealpixPixelization(5) 

137 pix = hpg.angle_to_pixel(h.nside, 50.0, 20.0) 

138 

139 corners_ra, corners_dec = hpg.boundaries(h.nside, pix, step=1) 

140 

141 ra_range = np.array([corners_ra.min() - 1.0, corners_ra.max() + 1.0]) 

142 dec_range = np.array([corners_dec.min() - 1.0, corners_dec.max() + 1.0]) 

143 

144 # Test the box region 

145 box = Box( 

146 point1=LonLat.fromDegrees(ra_range[0], dec_range[0]), 

147 point2=LonLat.fromDegrees(ra_range[1], dec_range[1]), 

148 ) 

149 # These pixels have been checked to completely overlap the region 

150 self._check_interior(h, box, [pix]) 

151 

152 # Try a polygon region: 

153 poly = ConvexPolygon( 

154 [ 

155 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[0])), 

156 UnitVector3d(LonLat.fromDegrees(ra_range[1], dec_range[0])), 

157 UnitVector3d(LonLat.fromDegrees(ra_range[1], dec_range[1])), 

158 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[1])), 

159 UnitVector3d(LonLat.fromDegrees(ra_range[0], dec_range[0])), 

160 ] 

161 ) 

162 self._check_interior(h, poly, [pix]) 

163 

164 # Try a circle region 

165 circle = Circle( 

166 center=UnitVector3d( 

167 LonLat.fromDegrees((ra_range[0] + ra_range[1]) / 2.0, (dec_range[0] + dec_range[1]) / 2.0) 

168 ), 

169 angle=Angle.fromDegrees(2.5), 

170 ) 

171 self._check_interior(h, circle, [pix]) 

172 

173 # Try an ellipse region 

174 ellipse = Ellipse( 

175 center=UnitVector3d( 

176 LonLat.fromDegrees((ra_range[0] + ra_range[1]) / 2.0, (dec_range[0] + dec_range[1]) / 2.0) 

177 ), 

178 alpha=Angle.fromDegrees(1.5), 

179 beta=Angle.fromDegrees(2.5), 

180 orientation=Angle.fromDegrees(45.0), 

181 ) 

182 self._check_interior(h, ellipse, [pix]) 

183 

184 def _check_interior(self, pixelization, region, check_pixels): 

185 """Check the interior from a region. 

186 

187 Parameters 

188 ---------- 

189 pixelization : `lsst.sphgeom.HealpixPixelization` 

190 region : `lsst.sphgeom.Region` 

191 check_pixels : `list` [`int`] 

192 """ 

193 pixel_range = pixelization.interior(region) 

194 

195 pixels = [] 

196 for r in pixel_range.ranges(): 

197 pixels.extend(range(r[0], r[1])) 

198 

199 self.assertEqual(pixels, check_pixels) 

200 

201 def test_index_to_string(self): 

202 """Test converting index to string of HealpixPixelization.""" 

203 h = HealpixPixelization(5) 

204 self.assertEqual(h.toString(0), str(0)) 

205 self.assertEqual(h.toString(100), str(100)) 

206 

207 def test_string(self): 

208 """Test string representation of HealpixPixelization.""" 

209 h = HealpixPixelization(5) 

210 self.assertEqual(str(h), "HealpixPixelization(5)") 

211 self.assertEqual(str(h), repr(h)) 

212 self.assertEqual(h, eval(repr(h), {"HealpixPixelization": HealpixPixelization})) 

213 

214 def test_pickle(self): 

215 """Test pickling of HealpixPixelization.""" 

216 a = HealpixPixelization(5) 

217 b = pickle.loads(pickle.dumps(a)) 

218 self.assertEqual(a, b) 

219 

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

221 def test_yaml(self): 

222 """Test yaml representation of HealpixPixelization.""" 

223 a = HealpixPixelization(5) 

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

225 self.assertEqual(a, b) 

226 

227 

228if __name__ == "__main__": 

229 unittest.main()