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
« 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/>.
28import pickle
29import unittest
31import hpgeom as hpg
32import numpy as np
34try:
35 import yaml
36except ImportError:
37 yaml = None
39from lsst.sphgeom import Angle, Box, Circle, ConvexPolygon, Ellipse, HealpixPixelization, LonLat, UnitVector3d
42class HealpixPixelizationTestCase(unittest.TestCase):
43 """Test HEALPix pixelization."""
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)
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)
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)
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)
79 corners_ra, corners_dec = hpg.boundaries(h.nside, pix, step=1)
81 # Take the southernmost corner...
82 smost = np.argmin(corners_dec)
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])
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])
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])
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])
117 def _check_envelope(self, pixelization, region, check_pixels):
118 """Check the envelope from a region.
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)
128 pixels = []
129 for r in pixel_range.ranges():
130 pixels.extend(range(r[0], r[1]))
132 self.assertEqual(pixels, check_pixels)
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)
139 corners_ra, corners_dec = hpg.boundaries(h.nside, pix, step=1)
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])
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])
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])
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])
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])
184 def _check_interior(self, pixelization, region, check_pixels):
185 """Check the interior from a region.
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)
195 pixels = []
196 for r in pixel_range.ranges():
197 pixels.extend(range(r[0], r[1]))
199 self.assertEqual(pixels, check_pixels)
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))
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}))
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)
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)
228if __name__ == "__main__":
229 unittest.main()