test_edisp.py
1 |
#! /usr/bin/env python
|
---|---|
2 |
# ==========================================================================
|
3 |
# Test H.E.S.S. energy dispersion matrix and GCTAEdisp2D class
|
4 |
#
|
5 |
# Copyright (C) 2018 Juergen Knoedlseder
|
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 GNU General Public License
|
18 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 |
#
|
20 |
# ==========================================================================
|
21 |
import math |
22 |
import gammalib |
23 |
|
24 |
|
25 |
# =============================== #
|
26 |
# Test H.E.S.S. energy dispersion #
|
27 |
# =============================== #
|
28 |
def test_edisp(infile): |
29 |
"""
|
30 |
"""
|
31 |
# Open FITS file
|
32 |
fits = gammalib.GFits(infile) |
33 |
|
34 |
# Get energy dispersion extension
|
35 |
edisp = fits['EDISP']
|
36 |
|
37 |
# Get true energies
|
38 |
etrue_lo = edisp['ENERG_LO']
|
39 |
etrue_hi = edisp['ENERG_HI']
|
40 |
etrues = [] |
41 |
for i in range(etrue_lo.number()): |
42 |
etrue = math.sqrt(etrue_lo[0,i] * etrue_hi[0,i]) |
43 |
etrues.append(etrue) |
44 |
|
45 |
# Get migration values
|
46 |
migra_lo = edisp['MIGRA_LO']
|
47 |
migra_hi = edisp['MIGRA_HI']
|
48 |
migras = [] |
49 |
for i in range(migra_lo.number()): |
50 |
migra = 0.5*(migra_lo[0,i] + migra_hi[0,i]) |
51 |
migras.append(migra) |
52 |
|
53 |
# Get energy dispersion matrix
|
54 |
matrix = edisp['MATRIX']
|
55 |
|
56 |
# Get matrix dimensions
|
57 |
netrue = matrix.dim()[0]
|
58 |
nmigra = matrix.dim()[1]
|
59 |
noffset = matrix.dim()[2]
|
60 |
npix = netrue * nmigra |
61 |
|
62 |
# Loop over offset angles
|
63 |
#for ioffset in range(noffset):
|
64 |
for ioffset in range(1): |
65 |
|
66 |
# Integrate over migra
|
67 |
sum_migra = [] |
68 |
for ietrue in range(netrue): |
69 |
sum = 0.0
|
70 |
for imigra in range(nmigra): |
71 |
i = ioffset * npix + imigra * netrue + ietrue |
72 |
dmigra = migra_hi[0,imigra] - migra_lo[0,imigra] |
73 |
sum += matrix[0,i] * dmigra |
74 |
sum_migra.append(sum)
|
75 |
|
76 |
# Integrate over ereco
|
77 |
#
|
78 |
# Edisp(Ereco) = Edisp(migra) / Etrue
|
79 |
#
|
80 |
sum_ereco = [] |
81 |
for ietrue in range(netrue): |
82 |
sum = 0.0
|
83 |
for imigra in range(nmigra): |
84 |
i = ioffset * npix + imigra * netrue + ietrue |
85 |
ereco_min = migra_lo[0,imigra] * etrues[ietrue]
|
86 |
ereco_max = migra_hi[0,imigra] * etrues[ietrue]
|
87 |
dereco = ereco_max - ereco_min |
88 |
sum += matrix[0,i] / etrues[ietrue] * dereco |
89 |
sum_ereco.append(sum)
|
90 |
|
91 |
# Integrate over log(ereco)
|
92 |
#
|
93 |
# Edisp(Ereco) = Edisp(migra) * (Ereco / Etrue)
|
94 |
#
|
95 |
sum_logereco = [] |
96 |
for ietrue in range(netrue): |
97 |
sum = 0.0
|
98 |
for imigra in range(nmigra): |
99 |
i = ioffset * npix + imigra * netrue + ietrue |
100 |
ereco_min = migra_lo[0,imigra] * etrues[ietrue]
|
101 |
ereco_max = migra_hi[0,imigra] * etrues[ietrue]
|
102 |
ereco = math.sqrt(ereco_min * ereco_max) |
103 |
logereco_min = math.log(ereco_min) |
104 |
logereco_max = math.log(ereco_max) |
105 |
dlog10ereco = logereco_max - logereco_min |
106 |
sum += matrix[0,i] * ereco / etrues[ietrue] * dlog10ereco |
107 |
sum_logereco.append(sum)
|
108 |
|
109 |
# Integrate over log10(ereco)
|
110 |
#
|
111 |
# Edisp(Ereco) = Edisp(migra) * (ln(10) * Ereco) / Etrue)
|
112 |
#
|
113 |
sum_log10ereco = [] |
114 |
for ietrue in range(netrue): |
115 |
sum = 0.0
|
116 |
for imigra in range(nmigra): |
117 |
i = ioffset * npix + imigra * netrue + ietrue |
118 |
ereco_min = migra_lo[0,imigra] * etrues[ietrue]
|
119 |
ereco_max = migra_hi[0,imigra] * etrues[ietrue]
|
120 |
ereco = math.sqrt(ereco_min * ereco_max) |
121 |
log10ereco_min = math.log10(ereco_min) |
122 |
log10ereco_max = math.log10(ereco_max) |
123 |
dlog10ereco = log10ereco_max - log10ereco_min |
124 |
sum += matrix[0,i] * math.log(10.0) * ereco / etrues[ietrue] * dlog10ereco |
125 |
sum_log10ereco.append(sum)
|
126 |
|
127 |
# Dump results for all energy bins
|
128 |
for ietrue in range(netrue): |
129 |
result = '%2d %3d %8.5f %8.5f %8.5f %8.5f' % \
|
130 |
(ioffset, ietrue, sum_migra[ietrue], sum_ereco[ietrue], |
131 |
sum_logereco[ietrue], sum_log10ereco[ietrue]) |
132 |
print(result) |
133 |
|
134 |
# Return
|
135 |
return
|
136 |
|
137 |
|
138 |
# ====================== #
|
139 |
# Test GCTAEdisp2D class #
|
140 |
# ====================== #
|
141 |
def test_GCTAEdisp2D(infile): |
142 |
"""
|
143 |
"""
|
144 |
# Load energy dispersion
|
145 |
edisp2D = gammalib.GCTAEdisp2D(infile) |
146 |
|
147 |
# Fetch energy dispersion data
|
148 |
edisp2D.fetch() |
149 |
|
150 |
# Get matrix dimensions
|
151 |
netrue = edisp2D.table().axis_bins(0)
|
152 |
nmigra = edisp2D.table().axis_bins(1)
|
153 |
noffset = edisp2D.table().axis_bins(2)
|
154 |
npix = netrue * nmigra |
155 |
|
156 |
# Loop over offset angles
|
157 |
for ioffset in range(noffset): |
158 |
|
159 |
# Get theta
|
160 |
theta = edisp2D.table().axis_nodes(2)[ioffset]
|
161 |
|
162 |
# Loop over true energies
|
163 |
for ietrue in range(netrue): |
164 |
|
165 |
# Get log10 Etrue
|
166 |
logEsrc = edisp2D.table().axis_nodes(0)[ietrue]
|
167 |
etrue = gammalib.GEnergy() |
168 |
etrue.log10TeV(logEsrc) |
169 |
|
170 |
# Get energy boundaries
|
171 |
ereco_bounds = edisp2D.ebounds_obs(logEsrc, theta) |
172 |
|
173 |
#
|
174 |
ereco_min = ereco_bounds.emin() |
175 |
ereco_max = ereco_bounds.emax() |
176 |
|
177 |
#
|
178 |
prob = edisp2D.prob_erecobin(ereco_min, ereco_max, etrue, theta) |
179 |
result = 'Prob: %2d %3d %8.5f' % (ioffset, ietrue, prob)
|
180 |
print(result) |
181 |
|
182 |
# Return
|
183 |
return
|
184 |
|
185 |
|
186 |
# ======================== #
|
187 |
# Main routine entry point #
|
188 |
# ======================== #
|
189 |
if __name__ == '__main__': |
190 |
|
191 |
# Set filename
|
192 |
filename = '/project-data/hess/hess_dl3_dr1/data/hess_dl3_dr1_obs_id_020326.fits'
|
193 |
|
194 |
# Test file
|
195 |
test_edisp(filename) |
196 |
|
197 |
# Test GCTAEdisp2D
|
198 |
test_GCTAEdisp2D(filename) |
199 |
|
200 |
|