Coverage for tests / test_uniform_grid.py: 18%
105 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 08:40 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 08:40 +0000
1# This file is part of cell_coadds.
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/>.
22from __future__ import annotations
24import pickle
25import unittest
27import lsst.utils.tests
28from lsst.cell_coadds import UniformGrid
29from lsst.geom import Box2I, Extent2I, Point2I
30from lsst.skymap import Index2D
33class UniformGridTestCase(unittest.TestCase):
34 """Tests for UniformGrid and GridIndex/Index2D's C++/Python
35 translation.
36 """
38 def setUp(self) -> None: # noqa: D102
39 self.x0 = 1
40 self.y0 = 2
41 self.bw = 15
42 self.bh = 12
43 self.nx = 5
44 self.ny = 6
45 self.cw = 3
46 self.ch = 2
48 self.bbox = Box2I(Point2I(x=self.x0, y=self.y0), Extent2I(x=self.bw, y=self.bh))
49 self.cell_size = Extent2I(x=self.cw, y=self.ch)
50 self.shape = Index2D(x=self.nx, y=self.ny)
51 self.padding = 0
53 def test_ctor_bbox_cell_size(self) -> None:
54 """Test UniformGrid after construction with (bbox, cell_size)."""
55 grid = UniformGrid.from_bbox_cell_size(self.bbox, self.cell_size)
56 self._check(grid)
58 def test_ctor_bbox_shape(self) -> None:
59 """Test UniformGrid after construction with (bbox, shape)."""
60 grid = UniformGrid.from_bbox_shape(self.bbox, self.shape)
61 self._check(grid)
63 def test_ctor_cell_size_shape_min(self) -> None:
64 """Test UniformGrid after construction with (cell_size, shape, min)."""
65 grid = UniformGrid(self.cell_size, self.shape, min=self.bbox.getMin())
66 self._check(grid)
68 def _check(self, grid: UniformGrid) -> None:
69 self.assertEqual(grid.bbox, self.bbox)
70 self.assertEqual(grid.cell_size, self.cell_size)
71 self.assertEqual(grid.shape, self.shape)
72 self.assertEqual(grid.padding, self.padding)
73 self.assertIsInstance(grid.shape, Index2D)
74 self.assertEqual(grid.bbox_of(Index2D(x=3, y=4)), Box2I(Point2I(x=10, y=10), self.cell_size))
75 index = grid.index(Point2I(x=11, y=9))
76 self.assertEqual(index, Index2D(x=3, y=3))
77 self.assertIsInstance(index, Index2D)
79 def test_index(self):
80 """Test various inputs to UniformGrid.index."""
81 grid = UniformGrid.from_bbox_cell_size(self.bbox, self.cell_size)
82 self.assertEqual(grid.index(self.bbox.getMin()), Index2D(x=0, y=0))
83 self.assertEqual(grid.index(self.bbox.getMax()), Index2D(x=4, y=5))
84 self.assertEqual(grid.index(Point2I(x=9, y=5)), Index2D(x=2, y=1))
85 self.assertEqual(grid.index(Point2I(x=9, y=6)), Index2D(x=2, y=2))
86 self.assertEqual(grid.index(Point2I(x=10, y=5)), Index2D(x=3, y=1))
87 self.assertEqual(grid.index(Point2I(x=10, y=6)), Index2D(x=3, y=2))
88 with self.assertRaises(ValueError):
89 grid.index(self.bbox.getMin() - Extent2I(x=0, y=1))
90 with self.assertRaises(ValueError):
91 grid.index(self.bbox.getMin() - Extent2I(x=1, y=0))
92 with self.assertRaises(ValueError):
93 grid.index(self.bbox.getMin() - Extent2I(x=1, y=1))
94 with self.assertRaises(ValueError):
95 grid.index(self.bbox.getMax() + Extent2I(x=0, y=1))
96 with self.assertRaises(ValueError):
97 grid.index(self.bbox.getMax() + Extent2I(x=1, y=0))
98 with self.assertRaises(ValueError):
99 grid.index(self.bbox.getMax() + Extent2I(x=1, y=1))
101 def test_repr(self):
102 """Test that UniformGrid.__repr__ round-trips through eval."""
103 for grid in (
104 UniformGrid.from_bbox_cell_size(self.bbox, self.cell_size),
105 UniformGrid.from_bbox_shape(self.bbox, self.shape, padding=1),
106 UniformGrid(self.cell_size, self.shape, min=self.bbox.getMin(), padding=3),
107 ):
108 self.assertEqual(eval(repr(grid)), grid, msg=repr(grid))
110 @lsst.utils.tests.methodParameters(padding=[0, 3])
111 def test_pickle(self, padding: int):
112 """Test that UniformGrid objects are pickleable."""
113 grid1 = UniformGrid.from_bbox_cell_size(self.bbox, self.cell_size, padding=padding)
114 grid2 = pickle.loads(pickle.dumps(grid1, pickle.HIGHEST_PROTOCOL))
115 self.assertIsInstance(grid2, UniformGrid)
116 self.assertEqual(grid1, grid2)
118 @lsst.utils.tests.methodParameters(padding=(1, 2, 3, 4, 7, 10))
119 def test_padding(self, padding: int):
120 """Test that bbox_of and index methods work with padding > 0."""
121 grid = UniformGrid.from_bbox_cell_size(self.bbox, self.cell_size, padding=padding)
123 # Test all interior cells
124 for x in range(1, self.nx - 1):
125 for y in range(1, self.ny - 1):
126 bbox = grid.bbox_of(Index2D(x=x, y=y))
127 self.assertEqual(bbox.getDimensions(), self.cell_size)
128 self.assertEqual(bbox.getMin(), Point2I(x=x * self.cw + self.x0, y=y * self.ch + self.y0))
130 # Test the four corners
131 for x in (0, self.nx - 1):
132 for y in (0, self.ny - 1):
133 bbox = grid.bbox_of(Index2D(x=x, y=y))
134 self.assertEqual(
135 bbox.getDimensions(),
136 self.cell_size + Extent2I(padding, padding),
137 )
138 self.assertEqual(
139 bbox.getMin(),
140 Point2I(
141 x=x * self.cw + self.x0 - padding * (x == 0),
142 y=y * self.ch + self.y0 - padding * (y == 0),
143 ),
144 )
146 # Test along the two horizontal edges
147 for x in (0, self.nx - 1):
148 for y in range(1, self.ny - 1):
149 bbox = grid.bbox_of(Index2D(x=x, y=y))
150 self.assertEqual(bbox.getDimensions(), self.cell_size + Extent2I(padding, 0))
151 self.assertEqual(
152 bbox.getMin(),
153 Point2I(x=x * self.cw + self.x0 - padding * (x == 0), y=y * self.ch + self.y0),
154 )
156 # Test along the two vertical edges
157 for x in range(1, self.nx - 1):
158 for y in (0, self.ny - 1):
159 bbox = grid.bbox_of(Index2D(x=x, y=y))
160 self.assertEqual(bbox.getDimensions(), self.cell_size + Extent2I(0, padding))
161 self.assertEqual(
162 bbox.getMin(),
163 Point2I(x=x * self.cw + self.x0, y=y * self.ch + self.y0 - padding * (y == 0)),
164 )
166 # Check the mapping between positions and indices
167 positions_index = (
168 # Check the four interior corners
169 (Point2I(x=self.x0, y=self.y0), Index2D(x=0, y=0)), # Lower-left corner, in the x and y buffer
170 (
171 Point2I(x=self.x0 + self.bw - 1, y=self.y0),
172 Index2D(x=self.nx - 1, y=0),
173 ), # Lower-right corner, in the x buffer
174 (
175 Point2I(x=self.x0, y=self.y0 + self.bh - 1),
176 Index2D(x=0, y=self.ny - 1),
177 ), # Upper-left corner, in the y buffer
178 (
179 Point2I(x=self.x0 + self.bw - 1, y=self.y0 + self.bh - 1),
180 Index2D(x=self.nx - 1, y=self.ny - 1),
181 ), # Upper-right corner, in the x and y buffer
182 # Check for one cell from the origin in either directions
183 (Point2I(x=self.x0, y=self.y0 + self.ch), Index2D(x=0, y=1)), # Left edge, in the x buffer
184 (Point2I(x=self.x0 + self.cw, y=self.y0), Index2D(x=1, y=0)),
185 # Check the four corners of the lower left buffer region
186 (Point2I(x=self.x0 - padding, y=self.y0), Index2D(0, 0)),
187 (Point2I(x=self.x0, y=self.y0 - padding), Index2D(0, 0)),
188 (Point2I(x=self.x0 - padding, y=self.y0), Index2D(0, 0)),
189 (Point2I(x=self.x0 - padding, y=self.y0 - padding), Index2D(0, 0)),
190 # Check the four corners of the lower right buffer region
191 (Point2I(x=self.x0 + self.bw, y=self.y0), Index2D(self.nx - 1, 0)),
192 (Point2I(x=self.x0 + self.bw + padding - 1, y=self.y0), Index2D(self.nx - 1, 0)),
193 (Point2I(x=self.x0 + self.bw + padding - 1, y=self.y0 - padding), Index2D(self.nx - 1, 0)),
194 (Point2I(x=self.x0 + self.bw, y=self.y0 - padding), Index2D(self.nx - 1, 0)),
195 # Check the four corners of the upper left buffer region
196 (Point2I(x=self.x0, y=self.y0 + self.bh), Index2D(0, self.ny - 1)),
197 (Point2I(x=self.x0, y=self.y0 + self.bh + padding - 1), Index2D(0, self.ny - 1)),
198 (Point2I(x=self.x0 - padding, y=self.y0 + self.bh + padding - 1), Index2D(0, self.ny - 1)),
199 (Point2I(x=self.x0 - padding, y=self.y0 + self.bh), Index2D(0, self.ny - 1)),
200 # Check the four corners of the upper right buffer region
201 (Point2I(x=self.x0 + self.bw, y=self.y0 + self.bh), Index2D(self.nx - 1, self.ny - 1)),
202 (
203 Point2I(x=self.x0 + self.bw, y=self.y0 + self.bh + padding - 1),
204 Index2D(self.nx - 1, self.ny - 1),
205 ),
206 (
207 Point2I(x=self.x0 + self.bw + padding - 1, y=self.y0 + self.bh),
208 Index2D(self.nx - 1, self.ny - 1),
209 ),
210 (
211 Point2I(x=self.x0 + self.bw + padding - 1, y=self.y0 + self.bh + padding - 1),
212 Index2D(self.nx - 1, self.ny - 1),
213 ),
214 )
216 for position, index in positions_index:
217 self.assertEqual(grid.index(position), index, msg=f"{position} does not map to {index}")
219 # Check that positions outside the grid raise an exception
220 self.assertRaises(ValueError, grid.index, Point2I(x=self.x0 - padding - 1, y=self.y0))
221 self.assertRaises(ValueError, grid.index, Point2I(x=self.x0 + self.bw + padding, y=self.y0))
222 self.assertRaises(ValueError, grid.index, Point2I(x=self.x0, y=self.y0 - padding - 1))
223 self.assertRaises(ValueError, grid.index, Point2I(x=self.x0, y=self.y0 + self.bh + padding))
226class TestMemory(lsst.utils.tests.MemoryTestCase):
227 """Test for memory/resource leaks."""
230def setup_module(module): # noqa: D103
231 lsst.utils.tests.init()
234if __name__ == "__main__": 234 ↛ 235line 234 didn't jump to line 235 because the condition on line 234 was never true
235 lsst.utils.tests.init()
236 unittest.main()