gammasimtools 0.19.0__py3-none-any.whl → 0.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/METADATA +1 -3
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/RECORD +43 -41
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/entry_points.txt +2 -2
- simtools/_version.py +2 -2
- simtools/applications/calculate_incident_angles.py +182 -0
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +17 -14
- simtools/applications/db_add_value_from_json_to_db.py +6 -9
- simtools/applications/db_generate_compound_indexes.py +7 -3
- simtools/applications/db_get_file_from_db.py +11 -23
- simtools/applications/derive_trigger_rates.py +91 -0
- simtools/applications/plot_simtel_events.py +73 -31
- simtools/applications/validate_file_using_schema.py +7 -4
- simtools/configuration/commandline_parser.py +17 -11
- simtools/data_model/validate_data.py +8 -3
- simtools/db/db_handler.py +83 -26
- simtools/db/db_model_upload.py +11 -16
- simtools/dependencies.py +10 -5
- simtools/layout/array_layout_utils.py +37 -5
- simtools/model/array_model.py +18 -1
- simtools/model/site_model.py +25 -0
- simtools/production_configuration/derive_corsika_limits.py +9 -34
- simtools/ray_tracing/incident_angles.py +706 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +2 -2
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +22 -29
- simtools/schemas/model_parameters/stars.schema.yml +1 -1
- simtools/schemas/production_tables.schema.yml +5 -0
- simtools/simtel/simtel_config_writer.py +17 -19
- simtools/simtel/simtel_io_event_histograms.py +253 -516
- simtools/simtel/simtel_io_event_reader.py +51 -2
- simtools/simtel/simtel_io_event_writer.py +31 -11
- simtools/simtel/simtel_io_metadata.py +1 -1
- simtools/simtel/simtel_table_reader.py +3 -3
- simtools/telescope_trigger_rates.py +119 -0
- simtools/testing/log_inspector.py +13 -11
- simtools/utils/geometry.py +20 -0
- simtools/visualization/plot_incident_angles.py +431 -0
- simtools/visualization/plot_simtel_event_histograms.py +376 -0
- simtools/visualization/visualize.py +1 -3
- simtools/applications/calculate_trigger_rate.py +0 -187
- simtools/applications/generate_sim_telarray_histograms.py +0 -196
- simtools/simtel/simtel_io_histogram.py +0 -623
- simtools/simtel/simtel_io_histograms.py +0 -556
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/top_level.txt +0 -0
- /simtools/visualization/{simtel_event_plots.py → plot_simtel_events.py} +0 -0
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
"""Reads the content of multiples files from sim_telarray."""
|
|
2
|
-
|
|
3
|
-
import copy
|
|
4
|
-
import logging
|
|
5
|
-
|
|
6
|
-
import numpy as np
|
|
7
|
-
from ctapipe.io import write_table
|
|
8
|
-
from eventio import EventIOFile, Histograms
|
|
9
|
-
from eventio.search_utils import yield_toplevel_of_type
|
|
10
|
-
|
|
11
|
-
from simtools import version
|
|
12
|
-
from simtools.io.hdf5_handler import fill_hdf5_table
|
|
13
|
-
from simtools.simtel.simtel_io_histogram import (
|
|
14
|
-
HistogramIdNotFoundError,
|
|
15
|
-
InconsistentHistogramFormatError,
|
|
16
|
-
SimtelIOHistogram,
|
|
17
|
-
)
|
|
18
|
-
from simtools.utils.names import sanitize_name
|
|
19
|
-
|
|
20
|
-
__all__ = [
|
|
21
|
-
"SimtelIOHistograms",
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SimtelIOHistograms:
|
|
26
|
-
"""
|
|
27
|
-
Read the content of either multiple histogram (.hdata, or .hdata.zst) or sim_telarray files.
|
|
28
|
-
|
|
29
|
-
Allow both the .hdata.zst histogram and the .simtel.zst output file type.
|
|
30
|
-
It uses the SimtelIOHistogram class to deal with individual files.
|
|
31
|
-
Histogram files are ultimately handled by using eventio library.
|
|
32
|
-
|
|
33
|
-
Parameters
|
|
34
|
-
----------
|
|
35
|
-
histogram_files: list
|
|
36
|
-
List of sim_telarray histogram files (str of Path).
|
|
37
|
-
test: bool
|
|
38
|
-
If True, only a fraction of the histograms will be processed, leading to a much shorter\
|
|
39
|
-
runtime.
|
|
40
|
-
area_from_distribution: bool
|
|
41
|
-
If true, the area thrown (the area in which the simulated events are distributed)
|
|
42
|
-
in the trigger rate calculation is estimated based on the event distribution.
|
|
43
|
-
The expected shape of the distribution of events as function of the core distance is
|
|
44
|
-
triangular up to the maximum distance. The weighted mean radius of the triangular
|
|
45
|
-
distribution is 2/3 times the upper edge. Therefore, when using the
|
|
46
|
-
``area_from_distribution`` flag, the mean distance times 3/2, returns just the position of
|
|
47
|
-
the upper edge in the triangle distribution with little impact of the binning and little
|
|
48
|
-
dependence on the scatter area defined in the simulation. This is special useful when
|
|
49
|
-
calculating trigger rate for individual telescopes.
|
|
50
|
-
If false, the area thrown is estimated based on the maximum distance as given in
|
|
51
|
-
the simulation configuration.
|
|
52
|
-
energy_range: list
|
|
53
|
-
The energy range used in the simulation. It must be passed as a list of floats and the
|
|
54
|
-
energy must be in TeV (as in the CORSIKA configuration).
|
|
55
|
-
This argument is only needed and used if histogram_file is a .hdata file, in which case the
|
|
56
|
-
energy range cannot be retrieved directly from the file.
|
|
57
|
-
view_cone: list
|
|
58
|
-
The view cone used in the simulation. It must be passed as a list of floats and the
|
|
59
|
-
view cone must be in deg (as in the CORSIKA configuration).
|
|
60
|
-
This argument is only needed and used if histogram_file is a .hdata file, in which case the
|
|
61
|
-
view cone cannot be retrieved directly from the file.
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
def __init__(
|
|
65
|
-
self,
|
|
66
|
-
histogram_files,
|
|
67
|
-
test=False,
|
|
68
|
-
area_from_distribution=False,
|
|
69
|
-
energy_range=None,
|
|
70
|
-
view_cone=None,
|
|
71
|
-
):
|
|
72
|
-
"""Initialize SimtelIOHistograms."""
|
|
73
|
-
self._logger = logging.getLogger(__name__)
|
|
74
|
-
if not isinstance(histogram_files, list):
|
|
75
|
-
histogram_files = [histogram_files]
|
|
76
|
-
self.histogram_files = histogram_files
|
|
77
|
-
self.view_cone = view_cone
|
|
78
|
-
self.energy_range = energy_range
|
|
79
|
-
self._is_test = test
|
|
80
|
-
self._combined_hists = None
|
|
81
|
-
self._list_of_histograms = None
|
|
82
|
-
self.__meta_dict = None
|
|
83
|
-
self.area_from_distribution = area_from_distribution
|
|
84
|
-
|
|
85
|
-
def calculate_trigger_rates(self, print_info=False, stack_files=False):
|
|
86
|
-
"""
|
|
87
|
-
Calculate the triggered and simulated event rate considering the histograms in each file.
|
|
88
|
-
|
|
89
|
-
It returns also a list with the tables where the energy dependent trigger rate for each
|
|
90
|
-
file can be found.
|
|
91
|
-
|
|
92
|
-
Parameters
|
|
93
|
-
----------
|
|
94
|
-
print_info: bool
|
|
95
|
-
if True, prints out the information about the histograms such as energy range, area,
|
|
96
|
-
etc.
|
|
97
|
-
stack_files: bool
|
|
98
|
-
if True, stack the histograms from the different files into single histograms.
|
|
99
|
-
Useful to increase event statistics when calculating the trigger rate.
|
|
100
|
-
|
|
101
|
-
Returns
|
|
102
|
-
-------
|
|
103
|
-
sim_event_rates: list of astropy.Quantity[1/time]
|
|
104
|
-
The simulated event rates.
|
|
105
|
-
triggered_event_rates: list of astropy.Quantity[1/time]
|
|
106
|
-
The triggered event rates.
|
|
107
|
-
triggered_event_rate_uncertainties: list of astropy.Quantity[1/time]
|
|
108
|
-
The uncertainties in the triggered event rates.
|
|
109
|
-
trigger_rate_in_tables: list of astropy.QTable
|
|
110
|
-
The energy dependent trigger rates.
|
|
111
|
-
Only filled if stack_files is False.
|
|
112
|
-
"""
|
|
113
|
-
if stack_files:
|
|
114
|
-
(
|
|
115
|
-
sim_event_rates,
|
|
116
|
-
triggered_event_rates,
|
|
117
|
-
triggered_event_rate_uncertainties,
|
|
118
|
-
) = self._rates_for_stacked_files()
|
|
119
|
-
trigger_rate_in_tables = []
|
|
120
|
-
else:
|
|
121
|
-
(
|
|
122
|
-
sim_event_rates,
|
|
123
|
-
triggered_event_rates,
|
|
124
|
-
triggered_event_rate_uncertainties,
|
|
125
|
-
trigger_rate_in_tables,
|
|
126
|
-
) = self._rates_for_each_file(print_info)
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
sim_event_rates,
|
|
130
|
-
triggered_event_rates,
|
|
131
|
-
triggered_event_rate_uncertainties,
|
|
132
|
-
trigger_rate_in_tables,
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
def _fill_stacked_events(self):
|
|
136
|
-
"""
|
|
137
|
-
Retrieve the simulated and triggered event histograms from the stacked histograms instead.
|
|
138
|
-
|
|
139
|
-
Returns
|
|
140
|
-
-------
|
|
141
|
-
first_hist_file: dict
|
|
142
|
-
The simulated 2D event histogram.
|
|
143
|
-
second_hist_file: dict
|
|
144
|
-
The triggered 2D event histogram.
|
|
145
|
-
|
|
146
|
-
Raises
|
|
147
|
-
------
|
|
148
|
-
HistogramIdNotFoundError:
|
|
149
|
-
if histogram ids not found. Problem with the file.
|
|
150
|
-
"""
|
|
151
|
-
sim_hist = None
|
|
152
|
-
trig_hist = None
|
|
153
|
-
for _, one_hist in enumerate(self.combined_hists):
|
|
154
|
-
if one_hist["id"] == 1:
|
|
155
|
-
sim_hist = one_hist
|
|
156
|
-
elif one_hist["id"] == 2:
|
|
157
|
-
trig_hist = one_hist
|
|
158
|
-
|
|
159
|
-
if sim_hist is None or trig_hist is None:
|
|
160
|
-
msg = (
|
|
161
|
-
"Simulated and triggered histograms were not found in the stacked histograms."
|
|
162
|
-
" Please check sim_telarray files!"
|
|
163
|
-
)
|
|
164
|
-
self._logger.error(msg)
|
|
165
|
-
raise HistogramIdNotFoundError
|
|
166
|
-
|
|
167
|
-
return sim_hist, trig_hist
|
|
168
|
-
|
|
169
|
-
def get_stacked_num_events(self):
|
|
170
|
-
"""
|
|
171
|
-
Return stacked number of simulated events and triggered events.
|
|
172
|
-
|
|
173
|
-
Returns
|
|
174
|
-
-------
|
|
175
|
-
int:
|
|
176
|
-
total number of simulated events for the stacked dataset.
|
|
177
|
-
int:
|
|
178
|
-
total number of triggered events for the stacked dataset.
|
|
179
|
-
"""
|
|
180
|
-
stacked_num_simulated_events = 0
|
|
181
|
-
stacked_num_triggered_events = 0
|
|
182
|
-
for _, file in enumerate(self.histogram_files):
|
|
183
|
-
simtel_hist_instance = SimtelIOHistogram(
|
|
184
|
-
file,
|
|
185
|
-
area_from_distribution=self.area_from_distribution,
|
|
186
|
-
energy_range=self.energy_range,
|
|
187
|
-
view_cone=self.view_cone,
|
|
188
|
-
)
|
|
189
|
-
_simulated, _triggered = simtel_hist_instance.total_number_of_events
|
|
190
|
-
stacked_num_simulated_events += _simulated
|
|
191
|
-
stacked_num_triggered_events += _triggered
|
|
192
|
-
return stacked_num_simulated_events, stacked_num_triggered_events
|
|
193
|
-
|
|
194
|
-
def _rates_for_stacked_files(self):
|
|
195
|
-
"""
|
|
196
|
-
Calculate trigger rate for the stacked case.
|
|
197
|
-
|
|
198
|
-
Returns
|
|
199
|
-
-------
|
|
200
|
-
sim_event_rates: list of astropy.Quantity[1/time]
|
|
201
|
-
The simulated event rates.
|
|
202
|
-
triggered_event_rates: list of astropy.Quantity[1/time]
|
|
203
|
-
The triggered event rates.
|
|
204
|
-
triggered_event_rate_uncertainties: list of astropy.Quantity[1/time]
|
|
205
|
-
The uncertainties in the triggered event rates.
|
|
206
|
-
trigger_rate_in_tables: list of astropy.QTable
|
|
207
|
-
The energy dependent trigger rates.
|
|
208
|
-
Only filled if stack_files is False.
|
|
209
|
-
"""
|
|
210
|
-
logging.info("Estimates for the stacked histograms:")
|
|
211
|
-
sim_hist, trig_hist = self._fill_stacked_events()
|
|
212
|
-
# Using a dummy instance of SimtelIOHistogram to calculate the trigger rate for the
|
|
213
|
-
# stacked files
|
|
214
|
-
simtel_hist_instance = SimtelIOHistogram(
|
|
215
|
-
self.histogram_files[0],
|
|
216
|
-
area_from_distribution=self.area_from_distribution,
|
|
217
|
-
energy_range=self.energy_range,
|
|
218
|
-
view_cone=self.view_cone,
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
stacked_num_simulated_events, stacked_num_triggered_events = self.get_stacked_num_events()
|
|
222
|
-
logging.info(f"Total number of simulated events: {stacked_num_simulated_events} events")
|
|
223
|
-
logging.info(f"Total number of triggered events: {stacked_num_triggered_events} events")
|
|
224
|
-
obs_time = simtel_hist_instance.estimate_observation_time(stacked_num_simulated_events)
|
|
225
|
-
logging.info(
|
|
226
|
-
"Estimated equivalent observation time corresponding to the number of"
|
|
227
|
-
f"events simulated: {obs_time.value} s"
|
|
228
|
-
)
|
|
229
|
-
sim_event_rate = stacked_num_simulated_events / obs_time
|
|
230
|
-
logging.info(f"Simulated event rate: {sim_event_rate.value:.4e} Hz")
|
|
231
|
-
(
|
|
232
|
-
triggered_event_rate,
|
|
233
|
-
_,
|
|
234
|
-
) = simtel_hist_instance.compute_system_trigger_rate(
|
|
235
|
-
events_histogram=sim_hist, triggered_events_histogram=trig_hist
|
|
236
|
-
)
|
|
237
|
-
triggered_event_rate_uncertainty = simtel_hist_instance.estimate_trigger_rate_uncertainty(
|
|
238
|
-
triggered_event_rate, stacked_num_simulated_events, stacked_num_triggered_events
|
|
239
|
-
)
|
|
240
|
-
logging.info(
|
|
241
|
-
f"System trigger event rate for stacked files: "
|
|
242
|
-
f"{triggered_event_rate.value:.4e} \u00b1 "
|
|
243
|
-
f"{triggered_event_rate_uncertainty.value:.4e} Hz"
|
|
244
|
-
)
|
|
245
|
-
return (
|
|
246
|
-
[sim_event_rate],
|
|
247
|
-
[triggered_event_rate],
|
|
248
|
-
[triggered_event_rate_uncertainty],
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
def _rates_for_each_file(self, print_info=False):
|
|
252
|
-
"""
|
|
253
|
-
Calculate trigger rate for each file.
|
|
254
|
-
|
|
255
|
-
Returns
|
|
256
|
-
-------
|
|
257
|
-
sim_event_rates: list of astropy.Quantity[1/time]
|
|
258
|
-
The simulated event rates.
|
|
259
|
-
triggered_event_rates: list of astropy.Quantity[1/time]
|
|
260
|
-
The triggered event rates.
|
|
261
|
-
triggered_event_rate_uncertainties: list of astropy.Quantity[1/time]
|
|
262
|
-
The uncertainties in the triggered event rates.
|
|
263
|
-
"""
|
|
264
|
-
triggered_event_rates = []
|
|
265
|
-
sim_event_rates = []
|
|
266
|
-
trigger_rate_in_tables = []
|
|
267
|
-
triggered_event_rate_uncertainties = []
|
|
268
|
-
for i_file, file in enumerate(self.histogram_files):
|
|
269
|
-
simtel_hist_instance = SimtelIOHistogram(
|
|
270
|
-
file,
|
|
271
|
-
area_from_distribution=self.area_from_distribution,
|
|
272
|
-
energy_range=self.energy_range,
|
|
273
|
-
view_cone=self.view_cone,
|
|
274
|
-
)
|
|
275
|
-
if print_info:
|
|
276
|
-
simtel_hist_instance.print_info()
|
|
277
|
-
|
|
278
|
-
_simulated_events, _triggered_events = simtel_hist_instance.total_number_of_events
|
|
279
|
-
logging.info(f"Histogram {i_file + 1}:")
|
|
280
|
-
logging.info(f"Total number of simulated events: {_simulated_events} events")
|
|
281
|
-
logging.info(f"Total number of triggered events: {_triggered_events} events")
|
|
282
|
-
|
|
283
|
-
obs_time = simtel_hist_instance.estimate_observation_time(_simulated_events)
|
|
284
|
-
logging.info(
|
|
285
|
-
f"Estimated equivalent observation time corresponding to the number of "
|
|
286
|
-
f"events simulated: {obs_time.value} s"
|
|
287
|
-
)
|
|
288
|
-
if obs_time != 0:
|
|
289
|
-
sim_event_rate = _simulated_events / obs_time
|
|
290
|
-
else:
|
|
291
|
-
sim_event_rate = 0.0 * obs_time.unit
|
|
292
|
-
logging.warning("Observation time is zero, cannot calculate event rate.")
|
|
293
|
-
sim_event_rates.append(sim_event_rate)
|
|
294
|
-
logging.info(f"Simulated event rate: {sim_event_rate.value:.4e} Hz")
|
|
295
|
-
|
|
296
|
-
(
|
|
297
|
-
triggered_event_rate,
|
|
298
|
-
triggered_event_rate_uncertainty,
|
|
299
|
-
) = simtel_hist_instance.compute_system_trigger_rate()
|
|
300
|
-
logging.info(
|
|
301
|
-
f"System trigger event rate: "
|
|
302
|
-
# pylint: disable=E1101
|
|
303
|
-
f"{triggered_event_rate.value:.4e} \u00b1 "
|
|
304
|
-
# pylint: disable=E1101
|
|
305
|
-
f"{triggered_event_rate_uncertainty.value:.4e} Hz"
|
|
306
|
-
)
|
|
307
|
-
triggered_event_rates.append(triggered_event_rate)
|
|
308
|
-
triggered_event_rate_uncertainties.append(triggered_event_rate_uncertainty)
|
|
309
|
-
trigger_rate_in_tables.append(simtel_hist_instance.trigger_info_in_table())
|
|
310
|
-
return (
|
|
311
|
-
sim_event_rates,
|
|
312
|
-
triggered_event_rates,
|
|
313
|
-
triggered_event_rate_uncertainties,
|
|
314
|
-
trigger_rate_in_tables,
|
|
315
|
-
)
|
|
316
|
-
|
|
317
|
-
@property
|
|
318
|
-
def number_of_files(self):
|
|
319
|
-
"""Returns number of histograms."""
|
|
320
|
-
return len(self.histogram_files)
|
|
321
|
-
|
|
322
|
-
def _check_consistency(self, first_hist_file, second_hist_file):
|
|
323
|
-
"""
|
|
324
|
-
Check whether two histograms have the same format.
|
|
325
|
-
|
|
326
|
-
Raises an error in case they are not consistent.
|
|
327
|
-
|
|
328
|
-
Parameters
|
|
329
|
-
----------
|
|
330
|
-
first_hist_file: dict
|
|
331
|
-
One histogram from a single file.
|
|
332
|
-
second_hist_file: dict
|
|
333
|
-
One histogram from a single file.
|
|
334
|
-
|
|
335
|
-
Raises
|
|
336
|
-
------
|
|
337
|
-
InconsistentHistogramFormatError:
|
|
338
|
-
if the format of the histograms have inconsistent dimensions.
|
|
339
|
-
"""
|
|
340
|
-
for key_to_test in [
|
|
341
|
-
"lower_x",
|
|
342
|
-
"upper_x",
|
|
343
|
-
"n_bins_x",
|
|
344
|
-
"title",
|
|
345
|
-
]:
|
|
346
|
-
if first_hist_file[key_to_test] != second_hist_file[key_to_test]:
|
|
347
|
-
msg = "Trying to add histograms with inconsistent dimensions"
|
|
348
|
-
self._logger.error(msg)
|
|
349
|
-
raise InconsistentHistogramFormatError
|
|
350
|
-
|
|
351
|
-
@property
|
|
352
|
-
def list_of_histograms(self):
|
|
353
|
-
"""
|
|
354
|
-
Returns a list with the histograms for each file.
|
|
355
|
-
|
|
356
|
-
Returns
|
|
357
|
-
-------
|
|
358
|
-
list:
|
|
359
|
-
List of histograms.
|
|
360
|
-
"""
|
|
361
|
-
if self._list_of_histograms is None:
|
|
362
|
-
self._list_of_histograms = []
|
|
363
|
-
for file in self.histogram_files:
|
|
364
|
-
with EventIOFile(file) as f:
|
|
365
|
-
for o in yield_toplevel_of_type(f, Histograms):
|
|
366
|
-
hists = o.parse()
|
|
367
|
-
self._list_of_histograms.append(hists)
|
|
368
|
-
return self._list_of_histograms
|
|
369
|
-
|
|
370
|
-
@property
|
|
371
|
-
def combined_hists(self):
|
|
372
|
-
"""
|
|
373
|
-
Combine histograms of same type of histogram.
|
|
374
|
-
|
|
375
|
-
Histograms are read from various lists into a single histogram list.
|
|
376
|
-
"""
|
|
377
|
-
# Processing and combining histograms from multiple files
|
|
378
|
-
if self._combined_hists is None:
|
|
379
|
-
self._combined_hists = []
|
|
380
|
-
for histogram_index, hists_one_file in enumerate(self.list_of_histograms):
|
|
381
|
-
if histogram_index == 0:
|
|
382
|
-
# First file
|
|
383
|
-
self._combined_hists = copy.copy(hists_one_file)
|
|
384
|
-
|
|
385
|
-
else:
|
|
386
|
-
for hist, this_combined_hist in zip(hists_one_file, self._combined_hists):
|
|
387
|
-
self._check_consistency(hist, this_combined_hist)
|
|
388
|
-
|
|
389
|
-
this_combined_hist["data"] = np.add(
|
|
390
|
-
this_combined_hist["data"], hist["data"]
|
|
391
|
-
)
|
|
392
|
-
|
|
393
|
-
self._logger.debug(f"End of reading {len(self.histogram_files)} files")
|
|
394
|
-
return self._combined_hists
|
|
395
|
-
|
|
396
|
-
@combined_hists.setter
|
|
397
|
-
def combined_hists(self, new_combined_hists):
|
|
398
|
-
"""
|
|
399
|
-
Setter for combined_hists.
|
|
400
|
-
|
|
401
|
-
Parameters
|
|
402
|
-
----------
|
|
403
|
-
new_combined_hists:
|
|
404
|
-
Combined histograms.
|
|
405
|
-
"""
|
|
406
|
-
self._combined_hists = new_combined_hists
|
|
407
|
-
|
|
408
|
-
def plot_one_histogram(self, histogram_index, ax):
|
|
409
|
-
"""
|
|
410
|
-
Plot a single histogram referent to the index histogram_index.
|
|
411
|
-
|
|
412
|
-
Parameters
|
|
413
|
-
----------
|
|
414
|
-
histogram_index: int
|
|
415
|
-
Index of the histogram to be plotted.
|
|
416
|
-
ax: matplotlib.axes.Axes
|
|
417
|
-
Instance of matplotlib.axes.Axes in which to plot the histogram.
|
|
418
|
-
"""
|
|
419
|
-
hist = self.combined_hists[histogram_index]
|
|
420
|
-
ax.set_title(hist["title"])
|
|
421
|
-
|
|
422
|
-
def _get_bins(hist, axis=0):
|
|
423
|
-
ax_str = "x" if axis == 0 else "y"
|
|
424
|
-
return np.linspace(
|
|
425
|
-
hist["lower_" + ax_str],
|
|
426
|
-
hist["upper_" + ax_str],
|
|
427
|
-
hist["n_bins_" + ax_str] + 1,
|
|
428
|
-
)
|
|
429
|
-
|
|
430
|
-
def _get_ax_lim(hist, axis=0):
|
|
431
|
-
if np.sum(hist["data"]) == 0:
|
|
432
|
-
return 0, 1
|
|
433
|
-
|
|
434
|
-
bins = _get_bins(hist, axis=axis)
|
|
435
|
-
|
|
436
|
-
if hist["data"].ndim == 1:
|
|
437
|
-
non_zero = np.where(hist["data"] != 0)
|
|
438
|
-
else:
|
|
439
|
-
marginal = np.sum(hist["data"], axis=axis)
|
|
440
|
-
non_zero = np.where(marginal != 0)
|
|
441
|
-
|
|
442
|
-
return bins[non_zero[0][0]], bins[non_zero[0][-1] + 1]
|
|
443
|
-
|
|
444
|
-
if hist["n_bins_y"] > 0:
|
|
445
|
-
# 2D histogram
|
|
446
|
-
|
|
447
|
-
xlim = _get_ax_lim(hist, axis=0)
|
|
448
|
-
ylim = _get_ax_lim(hist, axis=1)
|
|
449
|
-
|
|
450
|
-
if np.sum(hist["data"]) == 0:
|
|
451
|
-
ax.text(
|
|
452
|
-
0.5,
|
|
453
|
-
0.5,
|
|
454
|
-
"EMPTY",
|
|
455
|
-
horizontalalignment="center",
|
|
456
|
-
verticalalignment="center",
|
|
457
|
-
transform=ax.transAxes,
|
|
458
|
-
)
|
|
459
|
-
return
|
|
460
|
-
|
|
461
|
-
x_bins = _get_bins(hist, axis=0)
|
|
462
|
-
y_bins = _get_bins(hist, axis=1)
|
|
463
|
-
|
|
464
|
-
ax.pcolormesh(x_bins, y_bins, hist["data"])
|
|
465
|
-
ax.set_xlim(xlim)
|
|
466
|
-
ax.set_ylim(ylim)
|
|
467
|
-
|
|
468
|
-
else:
|
|
469
|
-
# 1D histogram
|
|
470
|
-
|
|
471
|
-
xlim = _get_ax_lim(hist, axis=0)
|
|
472
|
-
|
|
473
|
-
if np.sum(hist["data"]) == 0:
|
|
474
|
-
ax.text(
|
|
475
|
-
0.5,
|
|
476
|
-
0.5,
|
|
477
|
-
"EMPTY",
|
|
478
|
-
horizontalalignment="center",
|
|
479
|
-
verticalalignment="center",
|
|
480
|
-
transform=ax.transAxes,
|
|
481
|
-
)
|
|
482
|
-
return
|
|
483
|
-
|
|
484
|
-
x_bins = _get_bins(hist, axis=0)
|
|
485
|
-
centers = 0.5 * (x_bins[:-1] + x_bins[1:])
|
|
486
|
-
ax.hist(centers, bins=x_bins, weights=hist["data"])
|
|
487
|
-
ax.set_xlim(xlim)
|
|
488
|
-
|
|
489
|
-
@property
|
|
490
|
-
def _meta_dict(self):
|
|
491
|
-
"""
|
|
492
|
-
Define the meta dictionary for exporting the histograms.
|
|
493
|
-
|
|
494
|
-
Returns
|
|
495
|
-
-------
|
|
496
|
-
dict
|
|
497
|
-
Meta dictionary for the hdf5 files with the histograms.
|
|
498
|
-
"""
|
|
499
|
-
if self.__meta_dict is None:
|
|
500
|
-
self.__meta_dict = {
|
|
501
|
-
"simtools_version": version.__version__,
|
|
502
|
-
"note": "Only lower bin edges are given.",
|
|
503
|
-
}
|
|
504
|
-
return self.__meta_dict
|
|
505
|
-
|
|
506
|
-
def export_histograms(self, hdf5_file_name, overwrite=False):
|
|
507
|
-
"""
|
|
508
|
-
Export sim_telarray histograms to hdf5 files.
|
|
509
|
-
|
|
510
|
-
Parameters
|
|
511
|
-
----------
|
|
512
|
-
hdf5_file_name: str
|
|
513
|
-
Name of the file to be saved with the hdf5 tables.
|
|
514
|
-
overwrite: bool
|
|
515
|
-
If True overwrites histograms already saved in the hdf5 file.
|
|
516
|
-
"""
|
|
517
|
-
self._logger.info(f"Exporting histograms to {hdf5_file_name}.")
|
|
518
|
-
for histogram in self.combined_hists:
|
|
519
|
-
x_bin_edges_list = np.linspace(
|
|
520
|
-
histogram["lower_x"],
|
|
521
|
-
histogram["upper_x"],
|
|
522
|
-
num=histogram["n_bins_x"] + 1,
|
|
523
|
-
endpoint=True,
|
|
524
|
-
)
|
|
525
|
-
if histogram["n_bins_y"] > 0:
|
|
526
|
-
y_bin_edges_list = np.linspace(
|
|
527
|
-
histogram["lower_y"],
|
|
528
|
-
histogram["upper_y"],
|
|
529
|
-
num=histogram["n_bins_y"] + 1,
|
|
530
|
-
endpoint=True,
|
|
531
|
-
)
|
|
532
|
-
else:
|
|
533
|
-
y_bin_edges_list = None
|
|
534
|
-
|
|
535
|
-
self._meta_dict["Title"] = sanitize_name(histogram["title"])
|
|
536
|
-
|
|
537
|
-
table = fill_hdf5_table(
|
|
538
|
-
hist=histogram["data"],
|
|
539
|
-
x_bin_edges=x_bin_edges_list,
|
|
540
|
-
y_bin_edges=y_bin_edges_list,
|
|
541
|
-
x_label=None,
|
|
542
|
-
y_label=None,
|
|
543
|
-
meta_data=self._meta_dict,
|
|
544
|
-
)
|
|
545
|
-
|
|
546
|
-
self._logger.debug(
|
|
547
|
-
f"Writing histogram with name {self._meta_dict['Title']} to {hdf5_file_name}."
|
|
548
|
-
)
|
|
549
|
-
# overwrite takes precedence over append
|
|
550
|
-
write_table(
|
|
551
|
-
table,
|
|
552
|
-
hdf5_file_name,
|
|
553
|
-
f"/{self._meta_dict['Title']}",
|
|
554
|
-
append=not overwrite,
|
|
555
|
-
overwrite=overwrite,
|
|
556
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|