Passed
Push — master ( 573345...9597ff )
by Giacomo
06:15
created

ResponseBin._get_en_th1d()   A

Complexity

Conditions 3

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 23
rs 9.8
c 0
b 0
f 0
cc 3
nop 6
1
from ..psf_fast import PSFWrapper, InvalidPSF
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Unused Code introduced by
Unused InvalidPSF imported from psf_fast
Loading history...
2
import numpy as np
0 ignored issues
show
introduced by
Unable to import 'numpy'
Loading history...
introduced by
external import "import numpy as np" should be placed before "from ..psf_fast import PSFWrapper, InvalidPSF"
Loading history...
3
import pandas as pd
0 ignored issues
show
introduced by
Unable to import 'pandas'
Loading history...
introduced by
external import "import pandas as pd" should be placed before "from ..psf_fast import PSFWrapper, InvalidPSF"
Loading history...
4
5
from threeML.exceptions.custom_exceptions import custom_warnings
0 ignored issues
show
introduced by
Unable to import 'threeML.exceptions.custom_exceptions'
Loading history...
Unused Code introduced by
Unused custom_warnings imported from threeML.exceptions.custom_exceptions
Loading history...
introduced by
external import "from threeML.exceptions.custom_exceptions import custom_warnings" should be placed before "from ..psf_fast import PSFWrapper, InvalidPSF"
Loading history...
6
7
8
class ResponseBin(object):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
best-practice introduced by
Too many instance attributes (12/7)
Loading history...
9
10
    def __init__(self, name, min_dec, max_dec, dec_center,
0 ignored issues
show
best-practice introduced by
Too many arguments (13/5)
Loading history...
11
                 sim_n_sig_events, sim_n_bg_events,
12
                 sim_energy_bin_low, sim_energy_bin_centers, sim_energy_bin_hi,
13
                 sim_differential_photon_fluxes, sim_signal_events_per_bin,
14
                 psf):
15
16
        self._name = name
17
        self._min_dec = min_dec
18
        self._max_dec = max_dec
19
        self._dec_center = dec_center
20
        self._sim_n_sig_events = sim_n_sig_events
21
        self._sim_n_bg_events = sim_n_bg_events
22
        self._sim_energy_bin_low = sim_energy_bin_low
23
        self._sim_energy_bin_centers = sim_energy_bin_centers
24
        self._sim_energy_bin_hi = sim_energy_bin_hi
25
        self._sim_differential_photon_fluxes = sim_differential_photon_fluxes
26
        self._sim_signal_events_per_bin = sim_signal_events_per_bin
27
        self._psf = psf  # type: PSFWrapper
28
29
    @staticmethod
30
    def _get_en_th1d(open_ttree, dec_id, dec_id_label, analysis_bin_id, analysis_bin_id_label, prefix):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
best-practice introduced by
Too many arguments (6/5)
Loading history...
31
32
        nh_name = "nh%i" % analysis_bin_id
33
34
        en_sig_label = "En%s_dec%i_%s" % (prefix, dec_id, nh_name)
35
36
        this_en_th1d = open_ttree.Get("%s/%s/%s" % (dec_id_label, analysis_bin_id_label, en_sig_label))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
37
38
        if not this_en_th1d:
39
40
            # Some old responses have a slightly different label. Try with that
41
            nh_name = "nh%02i" % analysis_bin_id
42
43
            en_sig_label = "En%s_dec%i_%s" % (prefix, dec_id, nh_name)
44
45
            this_en_th1d = open_ttree.Get("%s/%s/%s" % (dec_id_label, analysis_bin_id_label, en_sig_label))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
46
47
            if not this_en_th1d:
48
49
                raise IOError("Could not find TH1D named %s" % this_en_th1d)
50
51
        return this_en_th1d, nh_name
52
53
    @classmethod
54
    def from_ttree(cls, open_ttree, dec_id, analysis_bin_id, log_log_spectrum, min_dec, dec_center, max_dec):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
best-practice introduced by
Too many arguments (8/5)
Loading history...
Comprehensibility introduced by
This function exceeds the maximum number of variables (30/15).
Loading history...
55
56
        from ..root_handler import ROOT
57
58
        # Compute the labels as used in the response file
59
        dec_id_label = "dec_%02i" % dec_id
60
        analysis_bin_id_label = "nh_%02i" % analysis_bin_id
61
62
        # Read the histogram of the simulated events detected in this bin_name
63
        # NOTE: we do not copy this TH1D instance because we won't use it after the
64
        # file is closed
65
66
        this_en_sig_th1d, nh_name = cls._get_en_th1d(open_ttree, dec_id, dec_id_label, analysis_bin_id, analysis_bin_id_label,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (126/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
67
                                                     'Sig')
68
69
        # The sum of the histogram is the total number of simulated events detected
70
        # in this analysis bin_name
71
        sim_n_sig_events = this_en_sig_th1d.Integral()
72
73
        # Now let's see what has been simulated, i.e., the differential flux
74
        # at the center of each bin_name of the en_sig histogram
75
        sim_energy_bin_low = np.zeros(this_en_sig_th1d.GetNbinsX())
76
        sim_energy_bin_centers = np.zeros(this_en_sig_th1d.GetNbinsX())
77
        sim_energy_bin_hi = np.zeros(this_en_sig_th1d.GetNbinsX())
78
        sim_signal_events_per_bin = np.zeros_like(sim_energy_bin_centers)
79
        sim_differential_photon_fluxes = np.zeros_like(sim_energy_bin_centers)
80
81
        for i in range(sim_energy_bin_centers.shape[0]):
82
            # Remember: bin_name 0 is the underflow bin_name, that is why there
83
            # is a "i+1" and not just "i"
84
            bin_lo = this_en_sig_th1d.GetBinLowEdge(i+1)
85
            bin_center = this_en_sig_th1d.GetBinCenter(i + 1)
86
            bin_hi = this_en_sig_th1d.GetBinWidth(i+1) + bin_lo
87
88
            # Store the center of the logarithmic bin_name
89
            sim_energy_bin_low[i] = 10 ** bin_lo  # TeV
90
            sim_energy_bin_centers[i] = 10 ** bin_center  # TeV
91
            sim_energy_bin_hi[i] = 10 ** bin_hi  # TeV
92
93
            # Get from the simulated spectrum the value of the differential flux
94
            # at the center energy
95
            sim_differential_photon_fluxes[i] = 10 ** log_log_spectrum.Eval(bin_center)  # TeV^-1 cm^-1 s^-1
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
96
97
            # Get from the histogram the detected events in each log-energy bin_name
98
            sim_signal_events_per_bin[i] = this_en_sig_th1d.GetBinContent(i + 1)
99
100
        # Read the histogram of the bkg events detected in this bin_name
101
        # NOTE: we do not copy this TH1D instance because we won't use it after the
102
        # file is closed
103
104
        this_en_bg_th1d, _ = cls._get_en_th1d(open_ttree, dec_id, dec_id_label, analysis_bin_id, analysis_bin_id_label,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
105
                                              'Bg')
106
107
        # The sum of the histogram is the total number of simulated events detected
108
        # in this analysis bin_name
109
        sim_n_bg_events = this_en_bg_th1d.Integral()
110
111
        # Now read the various TF1(s) for PSF, signal and background
112
113
        # Read the PSF and make a copy (so it will stay when we close the file)
114
115
        psf_label_tf1 = "PSF_dec%i_%s_fit" % (dec_id, nh_name)
116
117
        psf_path = "%s/%s/%s" % (dec_id_label, analysis_bin_id_label, psf_label_tf1)
118
119
        tf1 = ROOT.TF1()
120
121
        open_ttree.GetObject(psf_path, tf1)
122
123
        psf_fun = PSFWrapper.from_TF1(tf1)
124
125
        return cls(analysis_bin_id, min_dec, max_dec, dec_center, sim_n_sig_events, sim_n_bg_events,
126
                   sim_energy_bin_low,
127
                   sim_energy_bin_centers,
128
                   sim_energy_bin_hi,
129
                   sim_differential_photon_fluxes, sim_signal_events_per_bin,
130
                   psf_fun)
131
132
    def to_pandas(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
133
134
        # In the metadata let's save all single values (floats)
135
        meta = {'min_dec': self._min_dec,
136
                'max_dec': self._max_dec,
137
                'declination_center': self._dec_center,
138
                'n_sim_signal_events': self._sim_n_sig_events,
139
                'n_sim_bkg_events': self._sim_n_bg_events
140
                }
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (remove 1 space).
Loading history...
141
142
        # Now make a dataframe containing the elements of the simulation
143
        items = (
144
            ('sim_energy_bin_low', pd.Series(self.sim_energy_bin_low)),
145
            ('sim_energy_bin_centers', pd.Series(self.sim_energy_bin_centers)),
146
            ('sim_energy_bin_hi', pd.Series(self.sim_energy_bin_hi)),
147
            ('sim_differential_photon_fluxes', pd.Series(self.sim_differential_photon_fluxes)),
148
            ('sim_signal_events_per_bin', pd.Series(self.sim_signal_events_per_bin))
149
        )
150
151
        df = pd.DataFrame.from_dict(dict(items))
0 ignored issues
show
Coding Style Naming introduced by
The name df does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
152
153
        return df, meta, self.psf.to_pandas()
154
155
    def combine_with_weights(self, other_response_bin, dec_center, w1, w2):
0 ignored issues
show
Coding Style Naming introduced by
The name w1 does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name w2 does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
156
        """
157
        Produce another response bin which is the weighted sum of this one and the other one passed.
158
159
        :param other_response_bin:
160
        :param w1:
161
        :param w2:
162
        :return:
163
        """
164
165
        assert np.isclose(w1+w2, 1.0), "Weights are not properly normalized"
166
167
        new_name = "interpolated_%s" % self._name
168
169
        # Use np.nan as declination boundaries to indicate that this is actually interpolated
170
        min_dec, max_dec = np.nan, np.nan
171
172
        n_sim_signal_events = w1 * self._sim_n_sig_events + w2 * other_response_bin._sim_n_sig_events
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (101/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
173
        n_sim_bkg_events = w1 * self._sim_n_bg_events + w2 * other_response_bin._sim_n_bg_events
174
175
        # We assume that the bin centers are the same
176
        assert np.allclose(self._sim_energy_bin_centers, other_response_bin._sim_energy_bin_centers)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _sim_energy_bin_centers was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
177
178
        sim_differential_photon_fluxes = w1 * self._sim_differential_photon_fluxes + \
179
                                         w2 * other_response_bin._sim_differential_photon_fluxes
180
181
        sim_signal_events_per_bin = w1 * self._sim_signal_events_per_bin + \
182
                                    w2 * other_response_bin._sim_signal_events_per_bin
183
184
        # Now interpolate the psf
185
        new_psf = self._psf.combine_with_other_psf(other_response_bin._psf, w1, w2)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _psf was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
186
187
        new_response_bin = ResponseBin(new_name, min_dec, max_dec, dec_center,
188
                                       n_sim_signal_events, n_sim_bkg_events,
189
                                       self._sim_energy_bin_low,
190
                                       self._sim_energy_bin_centers,
191
                                       self._sim_energy_bin_hi,
192
                                       sim_differential_photon_fluxes,
193
                                       sim_signal_events_per_bin,
194
                                       new_psf)
195
196
        return new_response_bin
197
198
    @property
199
    def name(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
200
        return self._name
201
202
    @property
203
    def declination_boundaries(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
204
        return (self._min_dec, self._max_dec)
205
206
    @property
207
    def declination_center(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
208
        return self._dec_center
209
210
    @property
211
    def psf(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
212
        return self._psf
213
214
    @property
215
    def n_sim_signal_events(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
216
        return self._sim_n_sig_events
217
218
    @property
219
    def n_sim_bkg_events(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
220
        return self._sim_n_bg_events
221
222
    @property
223
    def sim_energy_bin_low(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
224
        return self._sim_energy_bin_low
225
226
    @property
227
    def sim_energy_bin_centers(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
228
        return self._sim_energy_bin_centers
229
230
    @property
231
    def sim_energy_bin_hi(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
232
        return self._sim_energy_bin_hi
233
234
    @property
235
    def sim_differential_photon_fluxes(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
236
        return self._sim_differential_photon_fluxes
237
238
    @property
239
    def sim_signal_events_per_bin(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
240
        return self._sim_signal_events_per_bin
0 ignored issues
show
Coding Style introduced by
Final newline missing
Loading history...