test_edisp.py

Knödlseder Jürgen, 10/24/2018 10:00 PM

Download (6.34 KB)

 
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