hawc_hal.maptree.map_tree.MapTree.__iter__()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 14
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 14
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
import os
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...
2
import numpy as np
3
import pandas as pd
4
5
from threeML.io.rich_display import display
6
from threeML.io.file_utils import sanitize_filename
7
8
from ..serialize import Serialization
9
from from_root_file import from_root_file
0 ignored issues
show
Coding Style introduced by
Relative import 'from_root_file', should be 'hawc_hal.maptree.from_root_file'
Loading history...
introduced by
first party import "from from_root_file import from_root_file" should be placed before "from ..serialize import Serialization"
Loading history...
10
from from_hdf5_file import from_hdf5_file
0 ignored issues
show
Coding Style introduced by
Relative import 'from_hdf5_file', should be 'hawc_hal.maptree.from_hdf5_file'
Loading history...
introduced by
first party import "from from_hdf5_file import from_hdf5_file" should be placed before "from ..serialize import Serialization"
Loading history...
11
12
import astropy.units as u
0 ignored issues
show
introduced by
third party import "import astropy.units as u" should be placed before "from from_root_file import from_root_file"
Loading history...
13
14
15
def map_tree_factory(map_tree_file, roi):
0 ignored issues
show
Coding Style introduced by
This function 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...
16
17
    # Sanitize files in input (expand variables and so on)
18
    map_tree_file = sanitize_filename(map_tree_file)
19
20
    if os.path.splitext(map_tree_file)[-1] == '.root':
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
21
22
        return MapTree.from_root_file(map_tree_file, roi)
23
24
    else:
25
26
        return MapTree.from_hdf5(map_tree_file, roi)
27
28
29
class MapTree(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...
30
31
    def __init__(self, analysis_bins, roi):
32
33
        self._analysis_bins = analysis_bins
34
        self._roi = roi
35
36
    @classmethod
37
    def from_hdf5(cls, map_tree_file, roi):
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...
38
39
        data_analysis_bins = from_hdf5_file(map_tree_file, roi)
40
41
        return cls(data_analysis_bins, roi)
42
43
    @classmethod
44
    def from_root_file(cls, map_tree_file, roi):
45
        """
46
        Create a MapTree object from a ROOT file and a ROI. Do not use this directly, use map_tree_factory instead.
47
48
        :param map_tree_file:
49
        :param roi:
50
        :return:
51
        """
52
53
        data_analysis_bins = from_root_file(map_tree_file, roi)
54
55
        return cls(data_analysis_bins, roi)
56
57
    def __iter__(self):
58
        """
59
        This allows to loop over the analysis bins as in:
60
61
        for analysis_bin in maptree:
62
63
            ... do something ...
64
65
        :return: analysis bin_name iterator
66
        """
67
68
        for analysis_bin in self._analysis_bins:
69
70
            yield analysis_bin
71
72
    def __getitem__(self, item):
73
        """
74
        This allows to access the analysis bins by name:
75
76
        first_analysis_bin = maptree["bin_name 0"]
77
78
        :param item: string for access by name
79
        :return: the analysis bin_name
80
        """
81
82
        try:
83
84
            return self._analysis_bins[item]
85
86
        except IndexError:
87
88
            raise IndexError("Analysis bin_name with index %i does not exist" % (item))
89
90
    def __len__(self):
91
92
        return len(self._analysis_bins)
93
94
    @property
95
    def analysis_bins_labels(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...
96
97
        return self._analysis_bins.keys()
98
99
    def display(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...
100
101
        df = pd.DataFrame()
0 ignored issues
show
Coding Style Naming introduced by
Variable name "df" doesn't conform to snake_case naming style ('(([a-z_][a-z0-9_]2,30)|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$' pattern)

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...
102
103
        df['Bin'] = self._analysis_bins.keys()
104
        df['Nside'] = [self._analysis_bins[bin_id].nside for bin_id in self._analysis_bins]
105
        df['Scheme'] = [self._analysis_bins[bin_id].scheme for bin_id in self._analysis_bins]
106
107
        # Compute observed counts, background counts, how many pixels we have in the ROI and
108
        # the sky area they cover
109
        n_bins = len(self._analysis_bins)
110
111
        obs_counts = np.zeros(n_bins)
112
        bkg_counts = np.zeros_like(obs_counts)
113
        n_pixels = np.zeros(n_bins, dtype=int)
114
        sky_area = np.zeros_like(obs_counts)
115
116
        size = 0
117
118
        for i, bin_id in enumerate(self._analysis_bins):
119
120
            analysis_bin = self._analysis_bins[bin_id]
121
122
            sparse_obs = analysis_bin.observation_map.as_partial()
123
            sparse_bkg = analysis_bin.background_map.as_partial()
124
125
            size += sparse_obs.nbytes
126
            size += sparse_bkg.nbytes
127
128
            obs_counts[i] = sparse_obs.sum()
129
            bkg_counts[i] = sparse_bkg.sum()
130
            n_pixels[i] = sparse_obs.shape[0]
131
            sky_area[i] = n_pixels[i] * analysis_bin.observation_map.pixel_area
132
133
        df['Obs counts'] = obs_counts
134
        df['Bkg counts'] = bkg_counts
135
        df['obs/bkg'] = obs_counts / bkg_counts
136
        df['Pixels in ROI'] = n_pixels
137
        df['Area (deg^2)'] = sky_area
138
139
        display(df)
140
141
        first_bin_id = self._analysis_bins.keys()[0]
142
        print("This Map Tree contains %.3f transits in the first bin" \
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after print.
Loading history...
143
            % self._analysis_bins[first_bin_id].n_transits)
144
        print("Total data size: %.2f Mb" % (size * u.byte).to(u.megabyte).value)
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after print.
Loading history...
Bug introduced by
The Module astropy.units does not seem to have a member named byte.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Module astropy.units does not seem to have a member named megabyte.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
145
146
    def write(self, filename):
147
        """
148
        Export the tree to a HDF5 file.
149
150
        NOTE: if an ROI has been applied, only the data within the ROI will be saved.
151
152
        :param filename: output filename. Use an extension .hd5 or .hdf5 to ensure proper handling by downstream
153
        software
154
        :return: None
155
        """
156
157
        # Make a dataframe with the ordered list of bin names
158
        # bin_names = map(lambda x:x.name, self._analysis_bins)
159
160
        # Create a dataframe with a multi-index, with the energy bin name as first level and the HEALPIX pixel ID
161
        # as the second level
162
        multi_index_keys = []
163
        dfs = []
164
        all_metas = []
165
166
        for bin_id in self._analysis_bins:
167
168
            analysis_bin = self._analysis_bins[bin_id]
169
170
            assert bin_id == analysis_bin.name, \
171
                'Bin name inconsistency: {} != {}'.format(bin_id, analysis_bin.name)
172
173
            multi_index_keys.append(analysis_bin.name)
174
175
            this_df, this_meta = analysis_bin.to_pandas()
176
177
            dfs.append(this_df)
178
            all_metas.append(pd.Series(this_meta))
179
180
        analysis_bins_df = pd.concat(dfs, axis=0, keys=multi_index_keys)
181
        meta_df = pd.concat(all_metas, axis=1, keys=multi_index_keys).T
182
183
        with Serialization(filename, mode='w') as serializer:
184
185
            serializer.store_pandas_object('/analysis_bins', analysis_bins_df)
186
            serializer.store_pandas_object('/analysis_bins_meta', meta_df)
187
188
            # Write the ROI
189
            if self._roi is not None:
190
191
                serializer.store_pandas_object('/ROI', pd.Series(), **self._roi.to_dict())
192
193
            else:
194
195
                serializer.store_pandas_object('/ROI', pd.Series())
196