Coverage for python/lsst/images/_intersection_bounds.py: 62%

25 statements  

« prev     ^ index     » next       coverage.py v7.14.3, created at 2026-07-01 09:14 +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. 

11 

12from __future__ import annotations 

13 

14__all__ = ("IntersectionBounds",) 

15 

16from typing import TYPE_CHECKING, Any, overload 

17 

18import numpy as np 

19 

20from ._geom import Bounds, Box 

21 

22if TYPE_CHECKING: 

23 from ._concrete_bounds import IntersectionBoundsSerializationModel 

24 

25 

26class IntersectionBounds: 

27 """An implementation of the `Bounds` protocol that acts as a lazy 

28 intersection of two other `Bounds` objects. 

29 

30 Parameters 

31 ---------- 

32 a 

33 First operand of the intersection. 

34 b 

35 Second operand of the intersection. 

36 """ 

37 

38 def __init__(self, a: Bounds, b: Bounds) -> None: 

39 self._a = a 

40 self._b = b 

41 

42 @property 

43 def bbox(self) -> Box: 

44 """The intersection of the bounding boxes of the operands (`.Box`).""" 

45 from ._concrete_bounds import _intersect_box_box 

46 

47 return _intersect_box_box(self._a.bbox, self._b.bbox) 

48 

49 @overload 

50 def contains(self, *, x: int, y: int) -> bool: ... 50 ↛ exitline 50 didn't return from function 'contains' because

51 

52 @overload 

53 def contains(self, *, x: np.ndarray, y: np.ndarray) -> np.ndarray: ... 53 ↛ exitline 53 didn't return from function 'contains' because

54 

55 def contains(self, *, x: Any, y: Any) -> Any: 

56 """Test whether these bounds contain one or more points. 

57 

58 Parameters 

59 ---------- 

60 x 

61 One or more integer X coordinates to test for containment. 

62 If an array, an array of results will be returned. 

63 y 

64 One or more integer Y coordinates to test for containment. 

65 If an array, an array of results will be returned. 

66 

67 Returns 

68 ------- 

69 `bool` | `numpy.ndarray` 

70 If ``x`` and ``y`` are both scalars, a single `bool` value. If 

71 ``x`` and ``y`` are arrays, a boolean array with their broadcasted 

72 shape. 

73 """ 

74 return np.logical_and(self._a.contains(x=x, y=y), self._b.contains(x=x, y=y)) 

75 

76 def intersection(self, other: Bounds) -> Bounds: 

77 """Compute the intersection of this bounds object with another. 

78 

79 Parameters 

80 ---------- 

81 other 

82 Bounds to intersect with this one. 

83 

84 Notes 

85 ----- 

86 Bounds intersection is guaranteed to raise `NoOverlapError` when the 

87 operand bounding boxes do not overlap, but it may return a bounds 

88 implementation that contains no points in more complex cases. 

89 """ 

90 from ._concrete_bounds import _intersect_ib 

91 

92 return _intersect_ib(self, other) 

93 

94 def serialize(self) -> IntersectionBoundsSerializationModel: 

95 """Convert a bounds instance into a serializable object.""" 

96 # Cyclic dependencies prevent IntersectionBoundsSerializationModel 

97 # from being defined here. 

98 from ._concrete_bounds import IntersectionBoundsSerializationModel 

99 

100 return IntersectionBoundsSerializationModel(a=self._a.serialize(), b=self._b.serialize())