Skip to content

Commit 4255a51

Browse files
author
martinkilbinger
committed
implemented weighted shear response
1 parent 2a50e33 commit 4255a51

File tree

5 files changed

+208
-36
lines changed

5 files changed

+208
-36
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Config file for masking and calibration.
2+
# Standard cuts without halo masks, type v1.X.6.
3+
4+
# General parameters (can also given on command line)
5+
params:
6+
input_path: unions_shapepipe_comprehensive_struc_2024_v1.X.c.hdf5
7+
cmatrices: True
8+
sky_regions: False
9+
verbose: True
10+
11+
# Masks
12+
## Using columns in 'dat' group (ShapePipe flags)
13+
dat:
14+
# SExtractor flags
15+
- col_name: FLAGS
16+
label: SE FLAGS
17+
kind: equal
18+
value: 0
19+
20+
# Duplicate objects
21+
- col_name: overlap
22+
label: tile overlap
23+
kind: equal
24+
value: True
25+
26+
# ShapePipe flags
27+
- col_name: IMAFLAGS_ISO
28+
label: SP mask
29+
kind: equal
30+
value: 0
31+
32+
# Number of epochs
33+
- col_name: N_EPOCH
34+
label: r"$n_{\rm epoch}$"
35+
kind: greater_equal
36+
value: 2
37+
38+
# Magnitude range
39+
- col_name: mag
40+
label: mag range
41+
kind: range
42+
value: [15, 30]
43+
44+
# ngmix flags
45+
- col_name: NGMIX_MOM_FAIL
46+
label: "ngmix moments failure"
47+
kind: equal
48+
value: 0
49+
50+
# invalid PSF ellipticities
51+
- col_name: NGMIX_ELL_PSFo_NOSHEAR_0
52+
label: "bad PSF ellipticity comp 1"
53+
kind: not_equal
54+
value: -10
55+
- col_name: NGMIX_ELL_PSFo_NOSHEAR_1
56+
label: "bad PSF ellipticity comp 2"
57+
kind: not_equal
58+
value: -10
59+
60+
## Using columns in 'dat_ext' group (post-processing flags)
61+
dat_ext:
62+
63+
# Stars
64+
- col_name: 4_Stars
65+
label: "Stars"
66+
kind: equal
67+
value: False
68+
69+
# Manual mask
70+
- col_name: 8_Manual
71+
label: "manual mask"
72+
kind: equal
73+
value: False
74+
75+
# r-band footprint
76+
- col_name: 64_r
77+
label: "r-band imaging"
78+
kind: equal
79+
value: False
80+
81+
# Maximask
82+
- col_name: 1024_Maximask
83+
label: "maximask"
84+
kind: equal
85+
value: False
86+
87+
# Rough pointing coverage
88+
- col_name: npoint3
89+
label: r"$n_{\rm pointing}$"
90+
kind: greater_equal
91+
value: 3
92+
93+
# Metacal parameters
94+
metacal:
95+
# Ellipticity dispersion
96+
sigma_eps_prior: 0.34
97+
98+
# Signal-to-noise range
99+
gal_snr_min: 10
100+
gal_snr_max: 1000
101+
102+
# Relative-size (hlr / hlr_psf) range
103+
gal_rel_size_min: 0.707
104+
gal_rel_size_max: 3
105+
106+
# Correct relative size for ellipticity?
107+
gal_size_corr_ell: False
108+
109+
# Weight for global response matrix, None for unweighted mean
110+
global_R_weight: w

notebooks/calibrate_comprehensive_cat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
dat, dat_ext = obj.read_cat(load_into_memory=False)
3939

4040
# %%
41-
#n_test = -1
42-
n_test = 100000
41+
n_test = -1
42+
#n_test = 100000
4343
if n_test > 0:
4444
print(f"MKDEBUG testing only first {n_test} objects")
4545
dat = dat[:n_test]
@@ -234,7 +234,7 @@
234234
g1_uncal=g_uncorr[0],
235235
g2_uncal=g_uncorr[1],
236236
R=gal_metacal.R,
237-
R_shear=R_shear,
237+
R_shear=gal_metacal.R_shear_global,
238238
R_select=gal_metacal.R_selection,
239239
c=c,
240240
c_err=c_err,

sp_validation/basic.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class metacal:
4444
masking type, one in 'gal', 'gal_mom', 'star'
4545
step : float, optional, default=0.01
4646
step h in finite differences
47-
stat_operator : optional, default=np.mean
48-
summary statistic for response matrices
4947
prefix : string, optional, default='NGMIX'
5048
to specify columns in input catalogue
5149
snr_min : float, optional, default=10
@@ -57,6 +55,9 @@ class metacal:
5755
rel_size_max : float, optional, default=3.0
5856
relative size maximum
5957
size_corr_ell : bool, optional, default=True
58+
global_R_weight : str, optional,
59+
weight column name for global response matrix; default is ``None``
60+
(unweighted mean)
6061
sigma_eps : float, optional
6162
ellipticity dispersion (one component) for computation
6263
of weights; default is 0.34
@@ -74,21 +75,20 @@ def __init__(
7475
mask,
7576
masking_type='gal',
7677
step=0.01,
77-
stat_operator=np.mean,
7878
prefix='NGMIX',
7979
snr_min=10,
8080
snr_max=500,
8181
rel_size_min=0.5,
8282
rel_size_max=3.0,
8383
size_corr_ell=True,
84+
global_R_weight=None,
8485
sigma_eps=0.34,
8586
col_2d=True,
8687
verbose=False,
8788
):
8889

8990
self._masking_type = masking_type
9091
self._step = step
91-
self._stat_operator = stat_operator
9292

9393
# Cuts
9494
self._snr_min = snr_min
@@ -103,6 +103,8 @@ def __init__(
103103
+ f'rel_size_max={rel_size_max}, '
104104
+ f'size_corr_ell={size_corr_ell}'
105105
)
106+
107+
self._global_R_weight = global_R_weight
106108

107109
self._sigma_eps = sigma_eps
108110
self._col_2d = col_2d
@@ -204,7 +206,10 @@ def _read_data_ngmix(self, masked_data, m1, p1, m2, p2, ns):
204206
self._n_after_gal_mask = len(dict_tmp['flag'])
205207
if self._verbose:
206208
print(f"Number of objects on metacal input = {self._n_input}")
207-
print(f"Number of objects after galaxy selection masking = {self._n_after_gal_mask}")
209+
print(
210+
"Number of objects after galaxy selection masking ="
211+
+ f" {self._n_after_gal_mask}"
212+
)
208213

209214
return m1, p1, m2, p2, ns
210215

@@ -503,20 +508,20 @@ def _selection_response(self):
503508
h2 = 2 * self._step
504509

505510
self.R11_s = (
506-
self._stat_operator(self.ns['g1'][ma_p1])
507-
- self._stat_operator(self.ns['g1'][ma_m1])
511+
np.mean(self.ns['g1'][ma_p1])
512+
- np.mean(self.ns['g1'][ma_m1])
508513
) / h2
509514
self.R22_s = sign * (
510-
self._stat_operator(self.ns['g2'][ma_p2])
511-
- self._stat_operator(self.ns['g2'][ma_m2])
515+
np.mean(self.ns['g2'][ma_p2])
516+
- np.mean(self.ns['g2'][ma_m2])
512517
) / h2
513518
self.R12_s = (
514-
self._stat_operator(self.ns['g1'][ma_p2])
515-
- self._stat_operator(self.ns['g1'][ma_m2])
519+
np.mean(self.ns['g1'][ma_p2])
520+
- np.mean(self.ns['g1'][ma_m2])
516521
) / h2
517522
self.R21_s = (
518-
self._stat_operator(self.ns['g2'][ma_p1])
519-
- self._stat_operator(self.ns['g2'][ma_m1])
523+
np.mean(self.ns['g2'][ma_p1])
524+
- np.mean(self.ns['g2'][ma_m1])
520525
) / h2
521526

522527
self.R_selection = np.array([
@@ -530,8 +535,16 @@ def _total_response(self):
530535
...
531536
532537
"""
533-
R_ws = self._stat_operator(self.R_shear, 2)
534-
self.R = R_ws + self.R_selection
538+
if self._global_R_weight is None or self._global_R_weight == "None":
539+
print("Computing unweighted response")
540+
self.R_shear_global = np.mean(self.R_shear, axis=2)
541+
else:
542+
print("Computing response weighted by", self._global_R_weight)
543+
# Get weights of masked no-shear objects
544+
weights = self.ns[self._global_R_weight][self.mask_dict['ns']]
545+
self.R_shear_global = np.average(self.R_shear, axis=2, weights=weights)
546+
547+
self.R = self.R_shear_global + self.R_selection
535548

536549
def _return():
537550
"""Add docstring.

sp_validation/calibration.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
def get_calibrated_quantities(gal_metacal, shape_method='ngmix'):
2929
"""Get Calibrated Quantities.
3030
31-
Return catalogue quantities for objects calibrated for multiplicative bias.
31+
Return catalogue quantities for objects calibrated for multiplicative
32+
bias.
3233
3334
Parameters
3435
----------
@@ -97,7 +98,9 @@ def get_calibrated_m_c(gal_metacal, shape_method='ngmix'):
9798
9899
"""
99100
# Get m-calibrated quantities
100-
g_corr, g_uncorr, w, mask_metacal = get_calibrated_quantities(gal_metacal)
101+
g_corr, g_uncorr, w, mask_metacal = get_calibrated_quantities(
102+
gal_metacal
103+
)
101104

102105
# Additive bias
103106
c = np.zeros(2)
@@ -106,7 +109,8 @@ def get_calibrated_m_c(gal_metacal, shape_method='ngmix'):
106109
for comp in (0, 1):
107110
c[comp] = np.mean(g_uncorr[comp])
108111

109-
# MKDEBUG TODO: Use std of mean instead, which is consistent with jackknife
112+
# MKDEBUG TODO: Use std of mean instead,
113+
# which is consistent with jackknife
110114
c_err[comp] = np.std(g_uncorr[comp])
111115

112116
# Shear estimate corrected for additive bias
@@ -269,19 +273,31 @@ def get_w_des(cat_gal, num_bins):
269273

270274
for i in range(num_bins):
271275
for j in range(num_bins):
272-
bin_mask = (df_gal['snr_log_bins'] == i) & (df_gal['size_ratio_log_bins'] == j)
276+
bin_mask = (
277+
(df_gal['snr_log_bins'] == i)
278+
& (df_gal['size_ratio_log_bins'] == j)
279+
)
273280
ngal = np.sum(bin_mask)
274-
shape_noise = 0.5*(np.sum(df_gal[bin_mask]['e1_uncal']**2)/ngal+np.sum(df_gal[bin_mask]['e2_uncal']**2)/ngal)
275-
response = 0.5*(np.average(df_gal[bin_mask]['R_g11'])+np.average(df_gal[bin_mask]['R_g22']))
276-
df_gal.loc[bin_mask, 'w_des'] = response**2/shape_noise
281+
if ngal == 0:
282+
print(f"Zero galaxies in snr/size_ratio bin ({i},{j})")
283+
shape_noise = 0.5 * (
284+
np.sum(df_gal[bin_mask]['e1_uncal'] ** 2) / ngal
285+
+ np.sum(df_gal[bin_mask]['e2_uncal'] ** 2) / ngal
286+
)
287+
response = 0.5 * (
288+
np.average(df_gal[bin_mask]['R_g11'])
289+
+ np.average(df_gal[bin_mask]['R_g22'])
290+
)
291+
df_gal.loc[bin_mask, 'w_des'] = response ** 2 / shape_noise
277292

278293
return np.array(df_gal['w_des'])
279294

280295

281296
def get_alpha_leakage_per_object(cat_gal, num_bins, weight_type='des'):
282297
"""
283298
Compute the leakage per object (Li et al. 2024)
284-
Return an array of leakage coefficients obtained by binning in SNR and size.
299+
Return an array of leakage coefficients obtained by binning in
300+
SNR and size.
285301
286302
Parameters
287303
----------
@@ -293,13 +309,18 @@ def get_alpha_leakage_per_object(cat_gal, num_bins, weight_type='des'):
293309
Returns
294310
-------
295311
alpha_1 : np.array
296-
Array containing the correction coefficient for the PSF leakage per object for the first component.
312+
Array containing the correction coefficient for the PSF leakage
313+
per object for the first component.
297314
alpha_2 : np.array
298-
Array containing the correction coefficient for the PSF leakage per object for the second component.
315+
Array containing the correction coefficient for the PSF leakage
316+
per object for the second component.
299317
"""
300318
assert weight_type in ['des', 'iv'], "weight_type must be either 'des' or 'iv'"
301-
#Compute the size ratio
302-
size_ratio = cat_gal['NGMIX_Tpsf_NOSHEAR']/(cat_gal['NGMIX_T_NOSHEAR']+cat_gal['NGMIX_Tpsf_NOSHEAR'])
319+
# Compute the size ratio
320+
size_ratio = (
321+
cat_gal['NGMIX_Tpsf_NOSHEAR']
322+
/ (cat_gal['NGMIX_T_NOSHEAR'] + cat_gal['NGMIX_Tpsf_NOSHEAR'])
323+
)
303324

304325
df_gal = pd.DataFrame(np.array([
305326
np.array(cat_gal['e1'], dtype=np.float64),
@@ -327,7 +348,12 @@ def get_alpha_leakage_per_object(cat_gal, num_bins, weight_type='des'):
327348
mask_binr = df_gal['bin_R'].values == ibin_r
328349

329350
#bin in snr
330-
df_gal.loc[mask_binr, 'bin_snr'] = pd.qcut(df_gal.loc[mask_binr, 'snr'], n_bins_snr, labels=False, retbins=False)
351+
df_gal.loc[mask_binr, 'bin_snr'] = pd.qcut(
352+
df_gal.loc[mask_binr, 'snr'],
353+
n_bins_snr,
354+
labels=False,
355+
retbins=False
356+
)
331357

332358
#group by bin
333359
df_gal_grouped = df_gal.groupby(['bin_R', 'bin_snr'])

0 commit comments

Comments
 (0)