Coverage for python/lsst/validate/drp/calcsrd/tex.py: 22%

52 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-02-05 19:03 -0800

1# LSST Data Management System 

2# Copyright 2015-2017 AURA/LSST. 

3# 

4# This product includes software developed by the 

5# LSST Project (http://www.lsst.org/). 

6# 

7# This program is free software: you can redistribute it and/or modify 

8# it under the terms of the GNU General Public License as published by 

9# the Free Software Foundation, either version 3 of the License, or 

10# (at your option) any later version. 

11# 

12# This program is distributed in the hope that it will be useful, 

13# but WITHOUT ANY WARRANTY; without even the implied warranty of 

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

15# GNU General Public License for more details. 

16# 

17# You should have received a copy of the LSST License Statement and 

18# the GNU General Public License along with this program. If not, 

19# see <https://www.lsstcorp.org/LegalNotices/>. 

20 

21import operator 

22 

23import astropy.units as u 

24from matplotlib import pyplot as plt 

25import numpy as np 

26import treecorr 

27 

28from lsst.verify import Measurement, Datum, ThresholdSpecification 

29 

30from ..util import (averageRaFromCat, averageDecFromCat, 

31 medianEllipticity1ResidualsFromCat, 

32 medianEllipticity2ResidualsFromCat) 

33 

34 

35def measureTEx(metric, matchedDataset, D, bin_range_operator, verbose=False): 

36 r"""Measurement of TEx (x=1,2): Correlation of PSF residual ellipticity 

37 on scales of D=(1, 5) arcmin. 

38 

39 Parameters 

40 ---------- 

41 metric : `lsst.verify.Metric` 

42 An TE1 or TE2 `~lsst.verify.Metric` instance. 

43 matchedDataset : lsst.verify.Blob 

44 The matched catalogs to analyze. 

45 D : `astropy.units.Quantity` 

46 Radial size of annulus in arcmin 

47 bin_range_operator : str 

48 String representation to use in comparisons 

49 verbose : `bool`, optional 

50 Output additional information on the analysis steps. 

51 

52 Returns 

53 ------- 

54 measurement : `lsst.verify.Measurement` 

55 Measurement of TEx (x=1,2) and associated metadata. 

56 

57 Notes 

58 ----- 

59 The TEx table below is provided in ``validate_drp``\ 's :file:`metrics.yaml`. 

60 

61 LPM-17 dated 2011-07-06 

62 

63 Specification: 

64 Using the full survey data, the E1, E2, and EX residual PSF ellipticity 

65 correlations averaged over an arbitrary FOV must have the median 

66 less than TE1 for theta <= 1 arcmin, and less than TE2 for theta >= 5 arcmin. 

67 

68 The residual ellipticity correlations vary smoothly so it is sufficient to 

69 specify limits in these two angular ranges. On 1 arcmin to 5 arcmin scales, 

70 these residual ellipticity correlations put LSST systematics a factor of a 

71 few below the weak lensing shot noise, i.e., statistical errors will 

72 dominate over systematics. On larger scales, the noise level imposed by 

73 nature due to shot noise plus cosmic variance is almost scale-independent, 

74 whereas the atmospheric contribution to systematics becomes negligible. 

75 Therefore the specifications on 5 arcmin scales apply to all larger scales 

76 as well (as per section 2.1.1). On scales larger than the field of view, 

77 sources of systematic error have less to do with the instrumentation than 

78 with the operations (due to the seeing distribution), software, and algorithms. 

79 

80 ========================= ====== ======= ======= 

81 PSF Ellipticity Residuals Specification 

82 ------------------------- ---------------------- 

83 Metric Design Minimum Stretch 

84 ========================= ====== ======= ======= 

85 TE1 () 2e-5 3e-5 1e-5 

86 TE2 (%) 1e-7 3e-7 5e-8 

87 TEF (%) 15 15 10 

88 TE3 () 4e-5 6e-5 2e-5 

89 TE4 () 2e-7 5e-7 1e-7 

90 ========================= ====== ======= ======= 

91 

92 

93 Table 27: These residual PSF ellipticity correlations apply to the r and i bands. 

94 """ 

95 

96 matches = matchedDataset.matchesBright 

97 

98 datums = {} 

99 datums['D'] = Datum(quantity=D, description="Separation distance") 

100 

101 radius, xip, xip_err = correlation_function_ellipticity_from_matches(matches, verbose=verbose) 

102 datums['radius'] = Datum(quantity=radius, description="Correlation radius") 

103 datums['xip'] = Datum(quantity=xip, description="Correlation strength") 

104 datums['xip_err'] = Datum(quantity=xip_err, description="Correlation strength uncertainty") 

105 datums['bin_range_operator'] = Datum(quantity=bin_range_operator, description="Bin range operator string") 

106 

107 operator = ThresholdSpecification.convert_operator_str(bin_range_operator) 

108 corr, corr_err = select_bin_from_corr(radius, xip, xip_err, radius=D, operator=operator) 

109 quantity = np.abs(corr) * u.Unit('') 

110 return Measurement(metric, quantity, extras=datums) 

111 

112 

113def correlation_function_ellipticity_from_matches(matches, **kwargs): 

114 """Compute shear-shear correlation function for ellipticity residual from a 'MatchedMultiVisitDataset' object. 

115 

116 Convenience function for calling correlation_function_ellipticity. 

117 

118 Parameters 

119 ---------- 

120 matches : `lsst.verify.Blob` 

121 - The matched catalogs to analyze. 

122 

123 Returns 

124 ------- 

125 r, xip, xip_err : each a np.array(dtype=float) 

126 - The bin centers, two-point correlation, and uncertainty. 

127 """ 

128 ra = matches.aggregate(averageRaFromCat) * u.radian 

129 dec = matches.aggregate(averageDecFromCat) * u.radian 

130 

131 e1_res = matches.aggregate(medianEllipticity1ResidualsFromCat) 

132 e2_res = matches.aggregate(medianEllipticity2ResidualsFromCat) 

133 

134 return correlation_function_ellipticity(ra, dec, e1_res, e2_res, **kwargs) 

135 

136 

137def correlation_function_ellipticity(ra, dec, e1_res, e2_res, 

138 nbins=20, min_sep=0.25, max_sep=20, 

139 sep_units='arcmin', verbose=False): 

140 """Compute shear-shear correlation function from ra, dec, g1, g2. 

141 

142 Default parameters for nbins, min_sep, max_sep chosen to cover 

143 an appropriate range to calculate TE1 (<=1 arcmin) and TE2 (>=5 arcmin). 

144 Parameters 

145 ---------- 

146 ra : numpy.array 

147 Right ascension of points [radians] 

148 dec : numpy.array 

149 Declination of points [radians] 

150 e1_res : numpy.array 

151 Residual ellipticity 1st component 

152 e2_res : numpy.array 

153 Residual ellipticity 2nd component 

154 nbins : float, optional 

155 Number of bins over which to analyze the two-point correlation 

156 min_sep : float, optional 

157 Minimum separation over which to analyze the two-point correlation 

158 max_sep : float, optional 

159 Maximum separation over which to analyze the two-point correlation 

160 sep_units : str, optional 

161 Specify the units of min_sep and max_sep 

162 verbose : bool 

163 Request verbose output from `treecorr`. 

164 verbose=True will use verbose=2 for `treecorr.GGCorrelation`. 

165 

166 Returns 

167 ------- 

168 r, xip, xip_err : each a np.array(dtype=float) 

169 - The bin centers, two-point correlation, and uncertainty. 

170 """ 

171 # Translate to 'verbose_level' here to refer to the integer levels in TreeCorr 

172 # While 'verbose' is more generically what is being passed around 

173 # for verbosity within 'validate_drp' 

174 if verbose: 

175 verbose_level = 2 

176 else: 

177 verbose_level = 0 

178 

179 catTree = treecorr.Catalog(ra=ra, dec=dec, g1=e1_res, g2=e2_res, 

180 dec_units='radian', ra_units='radian') 

181 gg = treecorr.GGCorrelation(nbins=nbins, min_sep=min_sep, max_sep=max_sep, 

182 sep_units=sep_units, 

183 verbose=verbose_level) 

184 gg.process(catTree) 

185 r = np.exp(gg.meanlogr) * u.arcmin 

186 xip = gg.xip * u.Unit('') 

187 # FIXME: Remove treecorr < 4 support 

188 try: 

189 # treecorr > 4 

190 xip_err = np.sqrt(gg.varxip) * u.Unit('') 

191 except AttributeError: 

192 # treecorr < 4 

193 xip_err = np.sqrt(gg.varxi) * u.Unit('') 

194 

195 return (r, xip, xip_err) 

196 

197 

198def select_bin_from_corr(r, xip, xip_err, radius=1*u.arcmin, operator=operator.le): 

199 """Aggregate measurements for r less than (or greater than) radius. 

200 

201 Returns aggregate measurement for all entries where operator(r, radius). 

202 E.g., 

203 * Passing radius=5, operator=operator.le will return averages for r<=5 

204 * Passing radius=2, operator=operator.gt will return averages for r >2 

205 

206 Written with the use of correlation functions in mind, thus the naming 

207 but generically just returns averages of the arrays xip and xip_err 

208 where the condition is satsified 

209 

210 Parameters 

211 ---------- 

212 r : numpy.array 

213 radius 

214 xip : numpy.array 

215 correlation 

216 xip_err : numpy.array 

217 correlation uncertainty 

218 operator : Operation in the 'operator' module: le, ge, lt, gt 

219 

220 Returns 

221 ------- 

222 avg_xip, avg_xip_err : (float, float) 

223 """ 

224 w, = np.where(operator(r, radius)) 

225 

226 avg_xip = np.average(xip[w]) 

227 avg_xip_err = np.average(xip_err[w]) 

228 

229 return avg_xip, avg_xip_err 

230 

231 

232def plot_correlation_function_ellipticity(r, xip, xip_err, 

233 plotfile='ellipticity_corr.png'): 

234 """ 

235 Parameters 

236 ---------- 

237 r : numpy.array 

238 Correlation average radius in each bin 

239 xip : numpy.array 

240 Two-point correlation 

241 xip_err : numpy.array 

242 Uncertainty on two-point correlation 

243 plotfile : Str 

244 Name of file to save the figure in. 

245 

246 Effects 

247 ------- 

248 Creates a plot file in the local filesystem: 'ellipticty_corr.png' 

249 """ 

250 fig = plt.figure() 

251 ax = fig.add_subplot(111) 

252 ax.errorbar(r.value, xip, yerr=xip_err) 

253 ax.set_xlabel('Separation (arcmin)', size=19) 

254 ax.set_ylabel('Median Residual Ellipticity Correlation', size=19) 

255 fig.savefig(plotfile)