Coverage for python / lsst / images / _intersection_bounds.py: 61%
29 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-07 08:34 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-07 08:34 +0000
1# This file is part of lsst-images.
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# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12from __future__ import annotations
14__all__ = ("IntersectionBounds",)
16from typing import TYPE_CHECKING, Any, Self, cast, overload
18import numpy as np
20from ._geom import Bounds, Box
22if TYPE_CHECKING:
23 from ._concrete_bounds import SerializableBounds
26class IntersectionBounds:
27 """An implementation of the `Bounds` protocol that acts as a lazy
28 intersection of two other `Bounds` objects.
29 """
31 def __init__(self, a: Bounds, b: Bounds):
32 self._a = a
33 self._b = b
35 @property
36 def bbox(self) -> Box:
37 """The intersection of the bounding boxes of the operands (`.Box`)."""
38 from ._concrete_bounds import _intersect_box_box
40 return _intersect_box_box(self._a.bbox, self._b.bbox)
42 @overload
43 def contains(self, *, x: int, y: int) -> bool: ... 43 ↛ exitline 43 didn't return from function 'contains' because
45 @overload
46 def contains(self, *, x: np.ndarray, y: np.ndarray) -> np.ndarray: ... 46 ↛ exitline 46 didn't return from function 'contains' because
48 def contains(self, *, x: Any, y: Any) -> Any:
49 """Test whether these bounds contain one or more points.
51 Parameters
52 ----------
53 x
54 One or more integer X coordinates to test for containment.
55 If an array, an array of results will be returned.
56 y
57 One or more integer Y coordinates to test for containment.
58 If an array, an array of results will be returned.
60 Returns
61 -------
62 `bool` | `numpy.ndarray`
63 If ``x`` and ``y`` are both scalars, a single `bool` value. If
64 ``x`` and ``y`` are arrays, a boolean array with their broadcasted
65 shape.
66 """
67 return np.logical_and(self._a.contains(x=x, y=y), self._b.contains(x=x, y=y))
69 def intersection(self, other: Bounds) -> Bounds:
70 """Compute the intersection of this bounds object with another.
72 Notes
73 -----
74 Bounds intersection is guaranteed to raise `NoOverlapError` when the
75 operand bounding boxes do not overlap, but it may return a bounds
76 implementation that contains no points in more complex cases.
77 """
78 from ._concrete_bounds import _intersect_ib
80 return _intersect_ib(self, other)
82 def serialize(self) -> SerializableBounds:
83 """Convert a bounds instance into a serializable object."""
84 # Cyclic dependencies prevent IntersectionBoundsSerializationModel
85 # from being defined here.
86 from ._concrete_bounds import IntersectionBoundsSerializationModel
88 return IntersectionBoundsSerializationModel(a=self._a.serialize(), b=self._b.serialize())
90 @classmethod
91 def deserialize(cls, serialized: SerializableBounds) -> Self:
92 """Convert a serialized bounds object into its in-memory form."""
93 from ._concrete_bounds import deserialize_bounds
95 return cast(Self, deserialize_bounds(serialized))