Coverage for metadetect / shearpos.py: 13%

59 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-07 01:53 -0800

1import numpy as np 

2import galsim 

3 

4from ngmix.metacal import DEFAULT_STEP 

5 

6SKIP_SHEARS = ['noshear', '1p_psf', '1m_psf', '2p_psf', '2m_psf'] 

7 

8 

9def shear_positions_obs(rows, cols, shear_str, obs, step=DEFAULT_STEP): 

10 """ 

11 unshear the input row and column positions 

12 

13 Parameters 

14 ---------- 

15 rows: array 

16 array of row values in sheared coordinates. Should be pixels 

17 in the image, not in a larger system 

18 cols: array 

19 array of col values in sheared coordinates. Should be pixels 

20 in the image, not in a larger system 

21 shear_str: string 

22 'noshear', '1p', '1m', '2p', '2m' 

23 obs: ngmix.Observation 

24 The observation data 

25 step: float 

26 shear step for metacal, default 0.01 

27 

28 Returns 

29 ------- 

30 rows_sheared, cols_sheared: 

31 rows and cols in the sheared coordinates 

32 """ 

33 jac = obs.jacobian 

34 dims = obs.image.shape 

35 

36 return shear_positions( 

37 rows=rows, cols=cols, shear_str=shear_str, jac=jac, dims=dims, 

38 step=step, 

39 ) 

40 

41 

42def shear_positions(rows, cols, shear_str, jac, dims, step=DEFAULT_STEP): 

43 """ 

44 unshear the input row and column positions 

45 

46 Parameters 

47 ---------- 

48 rows: array 

49 array of row values in sheared coordinates. Should be pixels 

50 in the image, not in a larger system 

51 cols: array 

52 array of col values in sheared coordinates. Should be pixels 

53 in the image, not in a larger system 

54 shear_str: string 

55 'noshear', '1p', '1m', '2p', '2m' 

56 jac: ngmix.Jacobian 

57 Describes the wcs 

58 dims: (nrows, ncols) 

59 The shape of the image data 

60 step: float 

61 shear step for metacal, default 0.01 

62 

63 Returns 

64 ------- 

65 rows_sheared, cols_sheared: 

66 rows and cols in the sheared coordinates 

67 """ 

68 

69 if shear_str in SKIP_SHEARS: 

70 return rows, cols 

71 

72 shear = get_galsim_shear(shear_str, step) 

73 

74 # this is the matrix that does shearing in u, v 

75 a = shear.getMatrix() 

76 

77 # we need the canonical image center in (u, v) for undoing the 

78 # shearing 

79 

80 row_cen = (dims[0] - 1) / 2 

81 col_cen = (dims[1] - 1) / 2 

82 

83 v_cen, u_cen = jac.get_vu(row=row_cen, col=col_cen) 

84 

85 # apply WCS to get to world coords 

86 v, u = jac.get_vu(row=rows, col=cols) 

87 

88 # unshear (subtract and then add the canonical center in u, v) 

89 u = np.atleast_1d(u) - u_cen 

90 v = np.atleast_1d(v) - v_cen 

91 

92 pos = np.vstack((u, v)) 

93 

94 out = np.dot(a, pos) 

95 assert out.shape[1] == u.shape[0] 

96 u_sheared = out[0, :] + u_cen 

97 v_sheared = out[1, :] + v_cen 

98 

99 # undo the WCS to get to image coords 

100 rows_sheared, cols_sheared = jac.get_rowcol(v=v_sheared, u=u_sheared) 

101 

102 return rows_sheared, cols_sheared 

103 

104 

105def unshear_positions_obs(rows, cols, shear_str, obs, step=DEFAULT_STEP): 

106 """ 

107 unshear the input row and column positions 

108 

109 Parameters 

110 ---------- 

111 rows: array 

112 array of row values in sheared coordinates 

113 cols: array 

114 array of col values in sheared coordinates 

115 shear_str: string 

116 'noshear', '1p', '1m', '2p', '2m' 

117 obs: ngmix.Observation 

118 The observation data 

119 step: float, optional 

120 shear step for metacal, default 0.01 

121 

122 Returns 

123 ------- 

124 rows_unsheared, cols_unsheared: 

125 rows and cols in the unsheared coordinates 

126 """ 

127 

128 jac = obs.jacobian 

129 dims = obs.image.shape 

130 

131 return unshear_positions( 

132 rows=rows, cols=cols, shear_str=shear_str, jac=jac, dims=dims, 

133 step=step, 

134 ) 

135 

136 

137def unshear_positions(rows, cols, shear_str, jac, dims, step=DEFAULT_STEP): 

138 """ 

139 unshear the input row and column positions 

140 

141 Parameters 

142 ---------- 

143 rows: array 

144 array of row values in sheared coordinates 

145 cols: array 

146 array of col values in sheared coordinates 

147 shear_str: string 

148 'noshear', '1p', '1m', '2p', '2m' 

149 jac: ngmix.Jacobian 

150 Describes the wcs 

151 dims: (nrows, ncols) 

152 The shape of the image data 

153 step: float 

154 shear step for metacal, default 0.01 

155 

156 Returns 

157 ------- 

158 rows_unsheared, cols_unsheared: 

159 rows and cols in the unsheared coordinates 

160 """ 

161 

162 if shear_str in SKIP_SHEARS: 

163 return rows, cols 

164 

165 shear = get_galsim_shear(shear_str, step) 

166 

167 # this is the matrix that undoes shearing in u, v 

168 ainv = np.linalg.inv(shear.getMatrix()) 

169 

170 # we need the canonical image center in (u, v) for undoing the 

171 # shearing 

172 

173 row_cen = (dims[0] - 1) / 2 

174 col_cen = (dims[1] - 1) / 2 

175 

176 v_cen, u_cen = jac.get_vu(row=row_cen, col=col_cen) 

177 

178 # apply WCS to get to world coords 

179 v, u = jac.get_vu(row=rows, col=cols) 

180 

181 # unshear (subtract and then add the canonical center in u, v) 

182 u = np.atleast_1d(u) - u_cen 

183 v = np.atleast_1d(v) - v_cen 

184 

185 pos = np.vstack((u, v)) 

186 

187 out = np.dot(ainv, pos) 

188 assert out.shape[1] == u.shape[0] 

189 u_unsheared = out[0] + u_cen 

190 v_unsheared = out[1] + v_cen 

191 

192 # undo the WCS to get to image coords 

193 rows_unsheared, cols_unsheared = \ 

194 jac.get_rowcol(v=v_unsheared, u=u_unsheared) 

195 

196 return rows_unsheared, cols_unsheared 

197 

198 

199def get_galsim_shear(shear_str, step): 

200 """ 

201 convert shear string to galsim Shear object 

202 """ 

203 

204 if shear_str == '1p': 

205 shear = galsim.Shear(g1=+step, g2=0.00) 

206 elif shear_str == '1m': 

207 shear = galsim.Shear(g1=-step, g2=0.00) 

208 elif shear_str == '2p': 

209 shear = galsim.Shear(g1=0.00, g2=+step) 

210 elif shear_str == '2m': 

211 shear = galsim.Shear(g1=0.00, g2=-step) 

212 else: 

213 raise ValueError('can only convert 1p,1m,2p,2m to galsim Shear') 

214 

215 return shear