Coverage for src/galsbi/ucat/filters_util.py: 99%

135 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-13 03:24 +0000

1# Copyright (C) 2018 ETH Zurich, Institute for Particle Physics and Astrophysics 

2 

3""" 

4Created Sept 2021 

5author: Tomasz Kacprzak 

6 

7This script manipulates filter information. It can create the filters_collection.h5 

8file, which contains all listed filters we use. 

9""" 

10 

11import os 

12from collections import OrderedDict 

13 

14import h5py 

15import numpy as np 

16from cosmic_toolbox import logger 

17from scipy.integrate import simpson as simps 

18 

19LOGGER = logger.get_logger(__file__) 

20 

21 

22def create_filter_collection(dirpath_res): 

23 """ 

24 Create a filter collection file 

25 Currently supported instruments: DECam, VISTA, GenericBessel 

26 """ 

27 

28 def add_decam_filters(filters_collect): 

29 # data downloaded from: 

30 # https://noirlab.edu/science/programs/ctio/filters/Dark-Energy-Camera 

31 filepath_filters = os.path.join(dirpath_res, "filters/scidoc0434.txt") 

32 # LAMBDA g r i z Y atm 

33 filter_data = np.loadtxt(filepath_filters).T 

34 atm = filter_data[-1] 

35 lam = filter_data[0] 

36 for i, b in enumerate(["g", "r", "i", "z", "Y"]): 

37 filters_collect[f"DECam_{b}"] = dict(amp=filter_data[i + 1], lam=lam) 

38 filters_collect[f"DECamNoAtm_{b}"] = dict( 

39 amp=filter_data[i + 1] / atm, lam=lam 

40 ) 

41 LOGGER.info(f"added DECam {b}-band") 

42 

43 b = "u" 

44 decam_u_lam, decam_u_amp = np.loadtxt( 

45 os.path.join(dirpath_res, "filters/DECam_2014_u.res") 

46 ).T 

47 filters_collect[f"DECam_{b}"] = dict(amp=decam_u_amp, lam=decam_u_lam) 

48 LOGGER.info(f"added DECam {b}-band") 

49 

50 def add_vista_filters(filters_collect): 

51 bands = ["H", "J", "Ks"] 

52 for b in bands: 

53 # VISTA filters from Will Hartley priv. comm. 

54 lam, amp = np.loadtxt( 

55 os.path.join(dirpath_res, f"filters/VISTA_Filters_at80K_forETC_{b}.res") 

56 ).T 

57 filters_collect[f"VISTA_{b}"] = dict(amp=amp, lam=lam) 

58 LOGGER.info(f"added VISTA {b}-band") 

59 

60 def add_bessel_filters(filters_collect): 

61 # generic Bessel filters from from 

62 # http://adsabs.harvard.edu/abs/1990PASP..102.1181B 

63 # http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?mode=browse&gname=Generic&asttype= 

64 bands = ["B", "I", "R", "U", "V"] 

65 

66 for b in bands: 

67 lam, amp = np.loadtxt( 

68 os.path.join(dirpath_res, f"filters/Generic_Bessell.{b}.dat") 

69 ).T 

70 filters_collect[f"GenericBessel_{b}"] = dict(amp=amp, lam=lam) 

71 LOGGER.info(f"added GenericBessel {b}-band") 

72 

73 def add_johnson_filters(filters_collect): 

74 # generic Bessel filters from from 

75 # http://adsabs.harvard.edu/abs/1990PASP..102.1181B 

76 # http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?mode=browse&gname=Generic&asttype= 

77 bands = ["U", "B", "V", "R", "I", "J", "M"] 

78 

79 for b in bands: 

80 lam, amp = np.loadtxt( 

81 os.path.join(dirpath_res, f"filters/Generic_Johnson.{b}.dat") 

82 ).T 

83 filters_collect[f"GenericJohnson_{b}"] = dict(amp=amp, lam=lam) 

84 LOGGER.info(f"added GenericJohnson {b}-band") 

85 

86 def add_cosmos_filters(filters_collect): 

87 # https://ftp.iap.fr/pub/from_users/hjmcc/COSMOS2015/COSMOS2015_Laigle+.header 

88 # https://cosmos.astro.caltech.edu/page/photom 

89 filters = {} 

90 filters["Vircam_Ks"] = dict( 

91 filename="K_uv.res", telescope="VISTA" 

92 ) # Ks_MAG_AUTO 

93 filters["Vircam_Y"] = dict(filename="Y_uv.res", telescope="VISTA") # Y_MAG_AUTO 

94 filters["Vircam_H"] = dict(filename="H_uv.res", telescope="VISTA") # H_MAG_AUTO 

95 filters["Vircam_J"] = dict(filename="J_uv.res", telescope="VISTA") # J_MAG_AUTO 

96 filters["SuprimeCam_B"] = dict( 

97 filename="B_subaru.res", telescope="SUBARU" 

98 ) # B_MAG_AUTO 

99 filters["SuprimeCam_V"] = dict( 

100 filename="V_subaru.res", telescope="SUBARU" 

101 ) # V_MAG_AUTO 

102 filters["SuprimeCam_ip"] = dict( 

103 filename="i_subaru.res", telescope="SUBARU" 

104 ) # ip_MAG_AUTO 

105 filters["SuprimeCam_r"] = dict( 

106 filename="r_subaru.res", telescope="SUBARU" 

107 ) # r_MAG_AUTO 

108 filters["SuprimeCam_zp"] = dict( 

109 filename="z_subaru.res", telescope="SUBARU" 

110 ) # zp_MAG_AUTO 

111 filters["SuprimeCam_zpp"] = dict( 

112 filename="suprime_FDCCD_z.res", telescope="SUBARU" 

113 ) # zpp_MAG_AUTO 

114 filters["MegaPrime_u"] = dict( 

115 filename="u_megaprime_sagem.res", telescope="CFHT" 

116 ) # u_MAG_AUTO 

117 filters["SuprimeCam_IB427"] = dict( 

118 filename="IA427.SuprimeCam.pb", telescope="SUBARU" 

119 ) # IB427_MAG_AUTO 

120 filters["SuprimeCam_IB464"] = dict( 

121 filename="IA464.SuprimeCam.pb", telescope="SUBARU" 

122 ) # IB464_MAG_AUTO 

123 filters["SuprimeCam_IA484"] = dict( 

124 filename="IA484.SuprimeCam.pb", telescope="SUBARU" 

125 ) # IA484_MAG_AUTO 

126 filters["SuprimeCam_IB505"] = dict( 

127 filename="IA505.SuprimeCam.pb", telescope="SUBARU" 

128 ) # IB505_MAG_AUTO 

129 filters["SuprimeCam_IA527"] = dict( 

130 filename="IA527.SuprimeCam.pb", telescope="SUBARU" 

131 ) # IA527_MAG_AUTO 

132 filters["SuprimeCam_IB574"] = dict( 

133 filename="IA574.SuprimeCam.pb", telescope="SUBARU" 

134 ) # IB574_MAG_AUTO 

135 filters["SuprimeCam_IA624"] = dict( 

136 filename="IA624.SuprimeCam.pb", telescope="SUBARU" 

137 ) # IA624_MAG_AUTO 

138 filters["SuprimeCam_IA679"] = dict( 

139 filename="IA679.SuprimeCam.pb", telescope="SUBARU" 

140 ) # IA679_MAG_AUTO 

141 filters["SuprimeCam_IB709"] = dict( 

142 filename="IA709.SuprimeCam.pb", telescope="SUBARU" 

143 ) # IB709_MAG_AUTO 

144 filters["SuprimeCam_IA738"] = dict( 

145 filename="IA738.SuprimeCam.pb", telescope="SUBARU" 

146 ) # IA738_MAG_AUTO 

147 filters["SuprimeCam_IA767"] = dict( 

148 filename="IA767.SuprimeCam.pb", telescope="SUBARU" 

149 ) # IA767_MAG_AUTO 

150 filters["SuprimeCam_IB827"] = dict( 

151 filename="IA827.SuprimeCam.pb", telescope="SUBARU" 

152 ) # IB827_MAG_AUTO 

153 filters["SuprimeCam_NB711"] = dict( 

154 filename="NB711.SuprimeCam.pb", telescope="SUBARU" 

155 ) # NB711_MAG_AUTO 

156 filters["SuprimeCam_NB816"] = dict( 

157 filename="NB816.SuprimeCam.pb", telescope="SUBARU" 

158 ) # NB816_MAG_AUTO 

159 filters["wircam_H"] = dict( 

160 filename="wircam_H.res", telescope="SUBARU" 

161 ) # Hw_MAG_AUTO 

162 filters["wircam_Ks"] = dict( 

163 filename="wircam_Ks.res", telescope="SUBARU" 

164 ) # Ksw_MAG_AUTO 

165 filters["irac_ch1"] = dict( 

166 filename="irac_ch1.res", telescope="SPITZER" 

167 ) # SPLASH_1_MAG 

168 filters["irac_ch2"] = dict( 

169 filename="irac_ch2.res", telescope="SPITZER" 

170 ) # SPLASH_2_MAG 

171 filters["irac_ch3"] = dict( 

172 filename="irac_ch3.res", telescope="SPITZER" 

173 ) # SPLASH_3_MAG 

174 filters["irac_ch4"] = dict( 

175 filename="irac_ch4.res", telescope="SPITZER" 

176 ) # SPLASH_4_MAG 

177 filters["mips_24"] = dict(filename="mips24.res", telescope="SPITZER") # MAG_24 

178 filters["GALEX_FUV"] = dict( 

179 filename="galex1500.res", telescope="GALEX" 

180 ) # MAG_GALEX_FUV 

181 filters["GALEX_NUV"] = dict( 

182 filename="galex2500.res", telescope="GALEX" 

183 ) # MAG_GALEX_NUV 

184 

185 for f in filters: 

186 lam, amp = np.loadtxt( 

187 os.path.join( 

188 dirpath_res, "filters/filters_cosmos2015", filters[f]["filename"] 

189 ) 

190 ).T 

191 filters_collect[f] = dict(amp=amp, lam=lam) 

192 LOGGER.info(f"added Cosmos2015 {f}") 

193 

194 def add_hsc_filters(filters_collect): 

195 # https://hsc-release.mtk.nao.ac.jp/doc/index.php/survey__pdr3/ 

196 # https://hsc-release.mtk.nao.ac.jp/doc/wp-content/uploads/2021/08/hsc_responses_all_rev4.zip 

197 

198 bands = ["g", "r", "r2", "i", "i2", "z", "y"] 

199 for b in bands: 

200 path = os.path.join( 

201 dirpath_res, "filters/filters_hsc_v2018", f"hsc_{b}_v2018.dat" 

202 ) 

203 lam, amp = np.loadtxt(path, comments="#").T 

204 filters_collect[f"HyperSuprimeCam_{b}"] = dict(amp=amp, lam=lam) 

205 LOGGER.info(f"added HyperSuprimeCam_{b}") 

206 

207 LOGGER.info("============ creating filter collection") 

208 filters_collect = {} 

209 add_decam_filters(filters_collect) 

210 add_vista_filters(filters_collect) 

211 add_bessel_filters(filters_collect) 

212 add_johnson_filters(filters_collect) 

213 add_cosmos_filters(filters_collect) 

214 add_hsc_filters(filters_collect) 

215 

216 return filters_collect 

217 

218 

219def store_filter_collection(filepath_collection, filters_collect): 

220 # store collection 

221 n_filters = len(filters_collect) 

222 with h5py.File(filepath_collection, "w") as f: 

223 for b in filters_collect: 

224 for k in filters_collect[b]: 

225 f[f"{b}/{k}"] = filters_collect[b][k] 

226 

227 LOGGER.info(f"wrote {filepath_collection} with {n_filters} filters") 

228 LOGGER.info(filters_collect.keys()) 

229 

230 

231def load_filters(filepath_filters, filter_names=None, lam_scale=1): 

232 filters = OrderedDict() 

233 with h5py.File(filepath_filters, "r") as f: 

234 filter_names = list(f.keys()) if filter_names is None else filter_names 

235 for b in filter_names: 

236 amp = np.array(f[b]["amp"]) 

237 lam = np.array(f[b]["lam"]) * lam_scale 

238 integ = simps(x=lam, y=amp / lam) 

239 LOGGER.debug(f"filter {b} integral={integ:2.5e}") 

240 filters[b] = dict(amp=amp, lam=lam, integ=integ) 

241 return filters 

242 

243 

244class UseShortFilterNames: 

245 """ 

246 Interface between short and long filter names 

247 """ 

248 

249 def __init__(self, func, filters_full_names): 

250 self.func = func 

251 self.filters_full_names = filters_full_names 

252 self.filters_full_names_rev = {ff: fs for fs, ff in filters_full_names.items()} 

253 

254 def __call__(self, **kw): 

255 if "filter_names" in kw: 

256 kw["filter_names"] = [ 

257 self.filters_full_names[f] for f in kw["filter_names"] 

258 ] 

259 

260 out = self.func(**kw) 

261 

262 if not isinstance(out, dict): 

263 return out 

264 else: 

265 out_ = {} 

266 for k in out: 

267 if k in self.filters_full_names_rev: 

268 out_[self.filters_full_names_rev[k]] = out[k] 

269 return out_ 

270 

271 def __getattr__(self, name): 

272 return getattr(self.func, name) 

273 

274 

275def get_default_full_filter_names(filters): 

276 filters_full_names = {f: f for f in filters} 

277 

278 return filters_full_names 

279 

280 

281# 'Ks_MAG_AUTO' Ks_uv.res 

282# 'Y_MAG_AUTO' Y_uv.res 

283# 'H_MAG_AUTO' H_uv.res 

284# 'J_MAG_AUTO' J_uv.res 

285# 'B_MAG_AUTO' B_subaru.res 

286# 'V_MAG_AUTO' V_subaru.res 

287# 'ip_MAG_AUTO' i_Subaru.res 

288# 'r_MAG_AUTO' r_subaru.res 

289# 'zp_MAG_AUTO' z_subaru.res 

290# 'zpp_MAG_AUTO' suprime_FDCCD_z.res 

291# 'u_MAG_AUTO' u_megaprime_sagem.res 

292# 'IB427_MAG_AUTO' IB427.SuprimeCam.pb 

293# 'IB464_MAG_AUTO' IB464.SuprimeCam.pb 

294# 'IA484_MAG_AUTO' IA484.SuprimeCam.pb 

295# 'IB505_MAG_AUTO' IB505.SuprimeCam.pb 

296# 'IA527_MAG_AUTO' IA527.SuprimeCam.pb 

297# 'IB574_MAG_AUTO' IB574.SuprimeCam.pb 

298# 'IA624_MAG_AUTO' IA624.SuprimeCam.pb 

299# 'IA679_MAG_AUTO' IA679.SuprimeCam.pb 

300# 'IB709_MAG_AUTO' IB709.SuprimeCam.pb 

301# 'IA738_MAG_AUTO' IA738.SuprimeCam.pb 

302# 'IA767_MAG_AUTO' IA767.SuprimeCam.pb 

303# 'IB827_MAG_AUTO' IB827.SuprimeCam.pb 

304# 'NB711_MAG_AUTO' NB711.SuprimeCam.pb 

305# 'NB816_MAG_AUTO' NB816.SuprimeCam.pb 

306# 'Hw_MAG_AUTO' wircam_H.res 

307# 'Ksw_MAG_AUTO' wircam_Ks.res 

308# 'yHSC_MAG_AUTO' y_HSC.txt 

309# 'SPLASH_1_MAG', irac_ch1.res 

310# 'SPLASH_2_MAG', irac_ch2.res 

311# 'SPLASH_3_MAG', irac_ch3.res 

312# 'SPLASH_4_MAG', irac_ch4.res 

313# 'MAG_24', mips24.res 

314# 'MAG_GALEX_FUV' galex1500.res 

315# 'MAG_GALEX_NUV' galex2500.res