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
« 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
3"""
4Created Sept 2021
5author: Tomasz Kacprzak
7This script manipulates filter information. It can create the filters_collection.h5
8file, which contains all listed filters we use.
9"""
11import os
12from collections import OrderedDict
14import h5py
15import numpy as np
16from cosmic_toolbox import logger
17from scipy.integrate import simpson as simps
19LOGGER = logger.get_logger(__file__)
22def create_filter_collection(dirpath_res):
23 """
24 Create a filter collection file
25 Currently supported instruments: DECam, VISTA, GenericBessel
26 """
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")
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")
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")
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"]
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")
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"]
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")
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
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}")
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
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}")
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)
216 return filters_collect
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]
227 LOGGER.info(f"wrote {filepath_collection} with {n_filters} filters")
228 LOGGER.info(filters_collect.keys())
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
244class UseShortFilterNames:
245 """
246 Interface between short and long filter names
247 """
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()}
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 ]
260 out = self.func(**kw)
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_
271 def __getattr__(self, name):
272 return getattr(self.func, name)
275def get_default_full_filter_names(filters):
276 filters_full_names = {f: f for f in filters}
278 return filters_full_names
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