Coverage for python/lsst/afw/geom/skyWcs.py: 37%

37 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-03-30 02:46 -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 

22import numpy as np 

23import scipy 

24 

25from lsst.utils import continueClass 

26import lsst.geom 

27from ._python import reduceTransform 

28from ._geom import (SkyWcs, makeCdMatrix, makeFlippedWcs, makeModifiedWcs, 

29 makeSkyWcs, makeTanSipWcs, makeWcsPairTransform, 

30 getIntermediateWorldCoordsToSky, getPixelToIntermediateWorldCoords) 

31from ._hpxUtils import makeHpxWcs 

32 

33__all__ = ["SkyWcs", "makeCdMatrix", "makeFlippedWcs", "makeSkyWcs", 

34 "makeModifiedWcs", "makeTanSipWcs", "makeWcsPairTransform", 

35 "getIntermediateWorldCoordsToSky", "getPixelToIntermediateWorldCoords", 

36 "makeHpxWcs"] 

37 

38 

39@continueClass 

40class SkyWcs: # noqa: F811 

41 def pixelToSkyArray(self, x, y, degrees=False): 

42 """ 

43 Convert numpy array pixels (x, y) to numpy array sky (ra, dec) 

44 positions. 

45 

46 Parameters 

47 ---------- 

48 x : `np.ndarray` 

49 Array of x values. 

50 y : `np.ndarray` 

51 Array of y values. 

52 degrees : `bool`, optional 

53 Return ra, dec arrays in degrees if True. 

54 

55 Returns 

56 ------- 

57 ra : `np.ndarray` 

58 Array of Right Ascension. Units are radians unless 

59 degrees=True. 

60 dec : `np.ndarray` 

61 Array of Declination. Units are radians unless 

62 degrees=True. 

63 """ 

64 xy = np.vstack((x, y)) 

65 ra, dec = np.vsplit(self.getTransform().getMapping().applyForward(xy), 2) 

66 ra %= (2.*np.pi) 

67 

68 if degrees: 

69 return np.rad2deg(ra.ravel()), np.rad2deg(dec.ravel()) 

70 else: 

71 return ra.ravel(), dec.ravel() 

72 

73 def skyToPixelArray(self, ra, dec, degrees=False): 

74 """ 

75 Convert numpy array sky (ra, dec) positions to numpy array 

76 pixels (x, y). 

77 

78 Parameters 

79 ---------- 

80 ra : `np.ndarray` 

81 Array of Right Ascension. Units are radians unless 

82 degrees=True. 

83 dec : `np.ndarray` 

84 Array of Declination. Units are radians unless 

85 degrees=True. 

86 degrees : `bool`, optional 

87 Input ra, dec arrays are degrees if True. 

88 

89 Returns 

90 ------- 

91 x : `np.ndarray` 

92 Array of x values. 

93 y : `np.ndarray` 

94 Array of y values. 

95 """ 

96 radec = np.vstack((ra, dec)) 

97 if degrees: 

98 radec = np.deg2rad(radec) 

99 

100 x, y = np.vsplit(self.getTransform().getMapping().applyInverse(radec), 2) 

101 

102 return x.ravel(), y.ravel() 

103 

104 def getRelativeRotationToWcs(self, otherWcs): 

105 """Get the difference in sky rotation angle to the specified wcs. 

106 

107 Ignoring location on the sky, if another wcs were atop this one, 

108 what would the difference in rotation be? i.e. for 

109 

110 otherWcs = createInitialSkyWcsFromBoresight(radec, rotation, detector) 

111 

112 what is the value that needs to be added to ``self.rotation`` (or 

113 subtracted from `other.rotation``) to align them? 

114 

115 Parameters 

116 ---------- 

117 otherWcs : `lsst.afw.geom.SkyWcs` 

118 The wcs to calculate the angle to. 

119 

120 Returns 

121 ------- 

122 angle : `lsst.geom.Angle` 

123 The angle between this and the supplied wcs, 

124 over the half-open range [0, 2pi). 

125 """ 

126 # Note: tests for this function live in 

127 # obs_lsst/tests/test_afwWcsUtil.py due to the need for an easy 

128 # constructor and instantiated detector, and the fact that afw 

129 # cannot depend on obs_base or obs_lsst. 

130 

131 m1 = self.getCdMatrix() 

132 m2 = otherWcs.getCdMatrix() 

133 

134 svd1 = scipy.linalg.svd(m1) 

135 svd2 = scipy.linalg.svd(m2) 

136 

137 m1rot = np.matmul(svd1[0], svd1[2]) 

138 m2rot = np.matmul(svd2[0], svd2[2]) 

139 

140 v_rot = [1, 0] 

141 

142 v_rot = np.matmul(v_rot, m1rot) # rotate by wcs1 

143 v_rot = np.matmul(v_rot, m2rot.T) # rotate _back_ by wcs2 

144 

145 rotation = np.arctan2(v_rot[1], v_rot[0]) 

146 rotation = rotation % (2*np.pi) 

147 return lsst.geom.Angle(rotation, lsst.geom.radians) 

148 

149 

150SkyWcs.__reduce__ = reduceTransform