Coverage for python/lsst/afw/cameraGeom/_rotateBBoxBy90.py: 5%

51 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-07 04:03 -0700

1# This file is part of afw. 

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/>. 

21 

22__all__ = ["rotateBBoxBy90"] 

23 

24import numpy 

25 

26import lsst.geom 

27 

28 

29def rotateBBoxBy90(bbox, n90, dimensions): 

30 """Rotate a bounding box by an integer multiple of 90 degrees. 

31 

32 Parameters 

33 ---------- 

34 bbox : `lsst.geom.Box2I` 

35 Bounding box to rotate. 

36 n90 : `int` 

37 Number of quarter rotations to perform 

38 dimensions : `tuple` of `int` 

39 Dimensions of the parent grid. 

40 

41 Returns 

42 ------- 

43 newBbox : `lsst.geom.Box` 

44 Rotated bounding box. 

45 

46 Notes 

47 ----- 

48 **TODO:** 

49 document dimensions better; what does it specify? 

50 """ 

51 while n90 < 0: 

52 n90 += 4 

53 n90 %= 4 

54 

55 # sin/cos of the rotation angle 

56 s = 0 

57 c = 0 

58 if n90 == 0: 

59 s = 0 

60 c = 1 

61 elif n90 == 1: 

62 s = 1 

63 c = 0 

64 elif n90 == 2: 

65 s = 0 

66 c = -1 

67 elif n90 == 3: 

68 s = -1 

69 c = 0 

70 else: 

71 raise ValueError("n90 must be an integer") 

72 

73 centerPixel = lsst.geom.Point2I(int(dimensions[0]/2), int(dimensions[1]/2)) 

74 

75 xCorner = numpy.array([(corner.getX() - centerPixel[0]) 

76 for corner in bbox.getCorners()]) 

77 yCorner = numpy.array([(corner.getY() - centerPixel[1]) 

78 for corner in bbox.getCorners()]) 

79 x0 = int((c*xCorner - s*yCorner).min()) 

80 y0 = int((s*xCorner + c*yCorner).min()) 

81 x1 = int((c*xCorner - s*yCorner).max()) 

82 y1 = int((s*xCorner + c*yCorner).max()) 

83 

84 # Fiddle things a little if the detector has an even number of pixels so that square BBoxes 

85 # will map into themselves 

86 

87 if n90 == 1: 

88 if dimensions[0]%2 == 0: 

89 x0 -= 1 

90 x1 -= 1 

91 elif n90 == 2: 

92 if dimensions[0]%2 == 0: 

93 x0 -= 1 

94 x1 -= 1 

95 if dimensions[1]%2 == 0: 

96 y0 -= 1 

97 y1 -= 1 

98 elif n90 == 3: 

99 if dimensions[1]%2 == 0: 

100 y0 -= 1 

101 y1 -= 1 

102 

103 LLC = lsst.geom.Point2I(centerPixel[0] + x0, centerPixel[1] + y0) 

104 URC = lsst.geom.Point2I(centerPixel[0] + x1, centerPixel[1] + y1) 

105 

106 newBbox = lsst.geom.Box2I(LLC, URC) 

107 

108 dxy0 = centerPixel[0] - centerPixel[1] 

109 if n90%2 == 1 and not dxy0 == 0: 

110 newBbox.shift(lsst.geom.Extent2I(-dxy0, dxy0)) 

111 

112 return newBbox