gammasimtools 0.24.0__py3-none-any.whl → 0.26.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.24.0.dist-info → gammasimtools-0.26.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +134 -130
- {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +3 -1
- {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +2 -2
- simtools/application_control.py +78 -0
- simtools/applications/calculate_incident_angles.py +0 -2
- simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -2
- simtools/applications/db_add_file_to_db.py +1 -1
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
- simtools/applications/db_add_value_from_json_to_db.py +1 -1
- simtools/applications/db_generate_compound_indexes.py +1 -1
- simtools/applications/db_get_array_layouts_from_db.py +2 -6
- simtools/applications/db_get_file_from_db.py +1 -1
- simtools/applications/db_get_parameter_from_db.py +1 -1
- simtools/applications/db_inspect_databases.py +1 -1
- simtools/applications/db_upload_model_repository.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +1 -2
- simtools/applications/derive_mirror_rnda.py +1 -3
- simtools/applications/derive_psf_parameters.py +5 -1
- simtools/applications/derive_pulse_shape_parameters.py +194 -0
- simtools/applications/derive_trigger_rates.py +1 -1
- simtools/applications/docs_produce_array_element_report.py +2 -8
- simtools/applications/docs_produce_calibration_reports.py +1 -3
- simtools/applications/docs_produce_model_parameter_reports.py +0 -2
- simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
- simtools/applications/generate_array_config.py +0 -1
- simtools/applications/generate_corsika_histograms.py +48 -235
- simtools/applications/generate_regular_arrays.py +5 -35
- simtools/applications/generate_simtel_event_data.py +2 -2
- simtools/applications/maintain_simulation_model_add_production.py +2 -2
- simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
- simtools/applications/plot_array_layout.py +64 -108
- simtools/applications/plot_simulated_event_distributions.py +57 -0
- simtools/applications/plot_tabular_data.py +0 -1
- simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
- simtools/applications/production_derive_corsika_limits.py +1 -1
- simtools/applications/production_generate_grid.py +0 -1
- simtools/applications/run_application.py +1 -1
- simtools/applications/simulate_flasher.py +3 -4
- simtools/applications/simulate_illuminator.py +0 -1
- simtools/applications/simulate_pedestals.py +2 -6
- simtools/applications/simulate_prod.py +9 -28
- simtools/applications/simulate_prod_htcondor_generator.py +8 -1
- simtools/applications/submit_array_layouts.py +7 -7
- simtools/applications/submit_model_parameter_from_external.py +1 -3
- simtools/applications/validate_camera_efficiency.py +0 -1
- simtools/applications/validate_camera_fov.py +0 -1
- simtools/applications/validate_cumulative_psf.py +0 -2
- simtools/applications/validate_file_using_schema.py +49 -123
- simtools/applications/validate_optics.py +0 -13
- simtools/camera/camera_efficiency.py +1 -6
- simtools/camera/single_photon_electron_spectrum.py +2 -1
- simtools/configuration/commandline_parser.py +43 -8
- simtools/configuration/configurator.py +6 -11
- simtools/corsika/corsika_config.py +204 -99
- simtools/corsika/corsika_histograms.py +411 -1735
- simtools/corsika/primary_particle.py +1 -1
- simtools/data_model/metadata_collector.py +5 -2
- simtools/data_model/metadata_model.py +0 -4
- simtools/data_model/model_data_writer.py +27 -17
- simtools/data_model/schema.py +112 -5
- simtools/data_model/validate_data.py +80 -48
- simtools/db/db_handler.py +19 -8
- simtools/db/db_model_upload.py +2 -1
- simtools/db/mongo_db.py +133 -42
- simtools/dependencies.py +83 -44
- simtools/io/ascii_handler.py +4 -2
- simtools/io/table_handler.py +1 -1
- simtools/job_execution/htcondor_script_generator.py +0 -2
- simtools/layout/array_layout.py +4 -12
- simtools/layout/array_layout_utils.py +227 -58
- simtools/model/array_model.py +37 -18
- simtools/model/calibration_model.py +0 -4
- simtools/model/legacy_model_parameter.py +134 -0
- simtools/model/model_parameter.py +24 -14
- simtools/model/model_repository.py +18 -5
- simtools/model/model_utils.py +1 -6
- simtools/model/site_model.py +0 -4
- simtools/model/telescope_model.py +6 -11
- simtools/production_configuration/derive_corsika_limits.py +6 -11
- simtools/production_configuration/interpolation_handler.py +16 -16
- simtools/ray_tracing/incident_angles.py +5 -11
- simtools/ray_tracing/mirror_panel_psf.py +3 -7
- simtools/ray_tracing/psf_analysis.py +29 -27
- simtools/ray_tracing/psf_parameter_optimisation.py +822 -680
- simtools/ray_tracing/ray_tracing.py +6 -15
- simtools/reporting/docs_auto_report_generator.py +8 -13
- simtools/reporting/docs_read_parameters.py +70 -16
- simtools/runners/corsika_runner.py +15 -10
- simtools/runners/corsika_simtel_runner.py +9 -8
- simtools/runners/runner_services.py +17 -7
- simtools/runners/simtel_runner.py +11 -58
- simtools/runners/simtools_runner.py +2 -4
- simtools/schemas/model_parameters/flasher_pulse_exp_decay.schema.yml +2 -0
- simtools/schemas/model_parameters/flasher_pulse_shape.schema.yml +50 -0
- simtools/schemas/model_parameters/flasher_pulse_width.schema.yml +2 -0
- simtools/schemas/simulation_models_info.schema.yml +2 -0
- simtools/settings.py +154 -0
- simtools/sim_events/file_info.py +128 -0
- simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
- simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
- simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
- simtools/simtel/pulse_shapes.py +273 -0
- simtools/simtel/simtel_config_writer.py +146 -22
- simtools/simtel/simtel_table_reader.py +6 -4
- simtools/simtel/simulator_array.py +62 -23
- simtools/simtel/simulator_camera_efficiency.py +4 -6
- simtools/simtel/simulator_light_emission.py +101 -19
- simtools/simtel/simulator_ray_tracing.py +4 -10
- simtools/simulator.py +360 -353
- simtools/telescope_trigger_rates.py +3 -4
- simtools/testing/assertions.py +115 -8
- simtools/testing/configuration.py +2 -3
- simtools/testing/helpers.py +2 -3
- simtools/testing/log_inspector.py +5 -1
- simtools/testing/sim_telarray_metadata.py +1 -1
- simtools/testing/validate_output.py +69 -23
- simtools/utils/general.py +37 -0
- simtools/utils/geometry.py +0 -77
- simtools/utils/names.py +7 -9
- simtools/version.py +37 -0
- simtools/visualization/legend_handlers.py +21 -10
- simtools/visualization/plot_array_layout.py +312 -41
- simtools/visualization/plot_corsika_histograms.py +143 -605
- simtools/visualization/plot_mirrors.py +834 -0
- simtools/visualization/plot_pixels.py +2 -4
- simtools/visualization/plot_psf.py +0 -1
- simtools/visualization/plot_simtel_event_histograms.py +4 -4
- simtools/visualization/plot_simtel_events.py +6 -11
- simtools/visualization/plot_tables.py +8 -19
- simtools/visualization/visualize.py +22 -2
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
- simtools/applications/print_version.py +0 -53
- simtools/io/hdf5_handler.py +0 -139
- simtools/simtel/simtel_io_file_info.py +0 -62
- {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
|
@@ -1,680 +1,218 @@
|
|
|
1
1
|
"""Visualize Cherenkov photon distributions from CORSIKA."""
|
|
2
2
|
|
|
3
|
-
import logging
|
|
4
|
-
import re
|
|
5
3
|
from pathlib import Path
|
|
6
4
|
|
|
7
5
|
import matplotlib.pyplot as plt
|
|
8
6
|
import numpy as np
|
|
9
7
|
from astropy import units as u
|
|
10
|
-
from matplotlib import colors
|
|
11
|
-
from matplotlib.backends.backend_pdf import PdfPages
|
|
8
|
+
from matplotlib import colormaps, colors
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
from simtools.visualization.visualize import save_figures_to_single_document
|
|
14
11
|
|
|
15
12
|
|
|
16
|
-
def
|
|
13
|
+
def _plot_2d(hist_list, labels=None):
|
|
17
14
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Create the figure of a 2D plot. The parameter name indicate which plot.
|
|
21
|
-
Choices are "counts", "density", "direction", "time_altitude", and "num_photons_per_telescope".
|
|
15
|
+
Plot 2D Cherenkov photon distributions.
|
|
22
16
|
|
|
23
17
|
Parameters
|
|
24
18
|
----------
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"num_photons_per_telescope".
|
|
30
|
-
log_z: bool
|
|
31
|
-
if True, the intensity of the color bar is given in logarithmic scale.
|
|
19
|
+
hist_list: list
|
|
20
|
+
List of histogram dictionaries.
|
|
21
|
+
labels: list or None
|
|
22
|
+
Optional list of labels for the input files. If None, uses file names.
|
|
32
23
|
|
|
33
24
|
Returns
|
|
34
25
|
-------
|
|
35
26
|
list
|
|
36
|
-
List of figures
|
|
37
|
-
|
|
38
|
-
Raises
|
|
39
|
-
------
|
|
40
|
-
ValueError
|
|
41
|
-
if property is not allowed.
|
|
27
|
+
List of figures.
|
|
42
28
|
"""
|
|
43
|
-
if
|
|
44
|
-
|
|
45
|
-
f"This property does not exist. The valid entries are "
|
|
46
|
-
f"{histograms_instance.dict_2d_distributions}"
|
|
47
|
-
)
|
|
48
|
-
_logger.error(msg)
|
|
49
|
-
raise ValueError(msg)
|
|
50
|
-
_function = getattr(
|
|
51
|
-
histograms_instance,
|
|
52
|
-
histograms_instance.dict_2d_distributions[property_name]["function"],
|
|
53
|
-
)
|
|
54
|
-
hist_values, x_bin_edges, y_bin_edges = _function()
|
|
29
|
+
if not hist_list:
|
|
30
|
+
return []
|
|
55
31
|
|
|
56
32
|
all_figs = []
|
|
57
|
-
for i_hist, _ in enumerate(x_bin_edges):
|
|
58
|
-
fig, ax = plt.subplots()
|
|
59
|
-
if log_z is True:
|
|
60
|
-
norm = colors.LogNorm(vmin=1, vmax=np.amax([np.amax(hist_values[i_hist]), 2]))
|
|
61
|
-
else:
|
|
62
|
-
norm = None
|
|
63
|
-
mesh = ax.pcolormesh(
|
|
64
|
-
x_bin_edges[i_hist], y_bin_edges[i_hist], hist_values[i_hist], norm=norm
|
|
65
|
-
)
|
|
66
|
-
if (
|
|
67
|
-
histograms_instance.dict_2d_distributions[property_name]["x axis unit"]
|
|
68
|
-
is not u.dimensionless_unscaled
|
|
69
|
-
):
|
|
70
|
-
ax.set_xlabel(
|
|
71
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['x bin edges']} "
|
|
72
|
-
f"({histograms_instance.dict_2d_distributions[property_name]['x axis unit']})"
|
|
73
|
-
)
|
|
74
|
-
else:
|
|
75
|
-
ax.set_xlabel(
|
|
76
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['x bin edges']} "
|
|
77
|
-
)
|
|
78
|
-
if (
|
|
79
|
-
histograms_instance.dict_2d_distributions[property_name]["y axis unit"]
|
|
80
|
-
is not u.dimensionless_unscaled
|
|
81
|
-
):
|
|
82
|
-
ax.set_ylabel(
|
|
83
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['y bin edges']} "
|
|
84
|
-
f"({histograms_instance.dict_2d_distributions[property_name]['y axis unit']})"
|
|
85
|
-
)
|
|
86
|
-
else:
|
|
87
|
-
ax.set_ylabel(
|
|
88
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['y bin edges']} "
|
|
89
|
-
)
|
|
90
|
-
ax.set_xlim(np.amin(x_bin_edges[i_hist]), np.amax(x_bin_edges[i_hist]))
|
|
91
|
-
ax.set_ylim(np.amin(y_bin_edges[i_hist]), np.amax(y_bin_edges[i_hist]))
|
|
92
|
-
ax.set_facecolor("black")
|
|
93
|
-
fig.colorbar(mesh)
|
|
94
|
-
all_figs.append(fig)
|
|
95
|
-
if histograms_instance.individual_telescopes is False:
|
|
96
|
-
ax.set_title(
|
|
97
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['file name']}_all_tels"
|
|
98
|
-
)
|
|
99
|
-
else:
|
|
100
|
-
ax.text(
|
|
101
|
-
0.99,
|
|
102
|
-
0.99,
|
|
103
|
-
"tel. " + str(i_hist),
|
|
104
|
-
ha="right",
|
|
105
|
-
va="top",
|
|
106
|
-
transform=ax.transAxes,
|
|
107
|
-
color="white",
|
|
108
|
-
)
|
|
109
|
-
ax.set_title(
|
|
110
|
-
f"{histograms_instance.dict_2d_distributions[property_name]['file name']}"
|
|
111
|
-
f"_tel_index_{histograms_instance.telescope_indices[i_hist]}",
|
|
112
|
-
)
|
|
113
|
-
plt.close()
|
|
114
|
-
|
|
115
|
-
return all_figs
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def plot_2d_counts(histograms_instance, log_z=True):
|
|
119
|
-
"""
|
|
120
|
-
Plot the 2D histogram of the photon positions on the ground.
|
|
121
|
-
|
|
122
|
-
Parameters
|
|
123
|
-
----------
|
|
124
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
125
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
126
|
-
log_z: bool
|
|
127
|
-
if True, the intensity of the color bar is given in logarithmic scale.
|
|
128
|
-
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
list
|
|
132
|
-
List of figures for the given telescopes.
|
|
133
|
-
"""
|
|
134
|
-
return _kernel_plot_2d_photons(histograms_instance, "counts", log_z=log_z)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def plot_2d_density(histograms_instance, log_z=True):
|
|
138
|
-
"""
|
|
139
|
-
Plot the 2D histogram of the photon density distribution on the ground.
|
|
140
|
-
|
|
141
|
-
Parameters
|
|
142
|
-
----------
|
|
143
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
144
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
145
|
-
log_z: bool
|
|
146
|
-
if True, the intensity of the color bar is given in logarithmic scale.
|
|
147
|
-
|
|
148
|
-
Returns
|
|
149
|
-
-------
|
|
150
|
-
list
|
|
151
|
-
List of figures for the given telescopes.
|
|
152
33
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
Returns
|
|
169
|
-
-------
|
|
170
|
-
list
|
|
171
|
-
List of figures for the given telescopes.
|
|
172
|
-
|
|
173
|
-
"""
|
|
174
|
-
return _kernel_plot_2d_photons(histograms_instance, "direction", log_z=log_z)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def plot_2d_time_altitude(histograms_instance, log_z=True):
|
|
178
|
-
"""
|
|
179
|
-
Plot the 2D histogram of the time and altitude where the photon was produced.
|
|
180
|
-
|
|
181
|
-
Parameters
|
|
182
|
-
----------
|
|
183
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
184
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
185
|
-
log_z: bool
|
|
186
|
-
if True, the intensity of the color bar is given in logarithmic scale.
|
|
187
|
-
|
|
188
|
-
Returns
|
|
189
|
-
-------
|
|
190
|
-
list
|
|
191
|
-
List of figures for the given telescopes.
|
|
192
|
-
|
|
193
|
-
"""
|
|
194
|
-
return _kernel_plot_2d_photons(histograms_instance, "time_altitude", log_z=log_z)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def plot_2d_num_photons_per_telescope(histograms_instance, log_z=True):
|
|
198
|
-
"""
|
|
199
|
-
Plot the 2D histogram of the number of photons per event and per telescope.
|
|
200
|
-
|
|
201
|
-
Parameters
|
|
202
|
-
----------
|
|
203
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
204
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
205
|
-
log_z: bool
|
|
206
|
-
if True, the intensity of the color bar is given in logarithmic scale.
|
|
207
|
-
|
|
208
|
-
Returns
|
|
209
|
-
-------
|
|
210
|
-
list
|
|
211
|
-
List of figures for the given telescopes.
|
|
212
|
-
|
|
213
|
-
"""
|
|
214
|
-
return _kernel_plot_2d_photons(histograms_instance, "num_photons_per_telescope", log_z=log_z)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def _kernel_plot_1d_photons(histograms_instance, property_name, log_y=True):
|
|
218
|
-
"""
|
|
219
|
-
Create the figure of a 1D plot. The parameter property indicate which plot.
|
|
220
|
-
|
|
221
|
-
Parameters
|
|
222
|
-
----------
|
|
223
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
224
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
225
|
-
property_name: string
|
|
226
|
-
Name of the quantity. Choices are
|
|
227
|
-
"counts", "density", "direction", "time", "altitude", "num_photons_per_event", and
|
|
228
|
-
"num_photons_per_telescope".
|
|
229
|
-
log_y: bool
|
|
230
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
231
|
-
|
|
232
|
-
Returns
|
|
233
|
-
-------
|
|
234
|
-
list
|
|
235
|
-
List of figures for the given telescopes.
|
|
236
|
-
|
|
237
|
-
Raises
|
|
238
|
-
------
|
|
239
|
-
ValueError
|
|
240
|
-
if property is not allowed.
|
|
241
|
-
"""
|
|
242
|
-
if property_name not in histograms_instance.dict_1d_distributions:
|
|
243
|
-
msg = (
|
|
244
|
-
f"This property does not exist. The valid entries are "
|
|
245
|
-
f"{histograms_instance.dict_1d_distributions}"
|
|
246
|
-
)
|
|
247
|
-
_logger.error(msg)
|
|
248
|
-
raise ValueError(msg)
|
|
249
|
-
|
|
250
|
-
_function = getattr(
|
|
251
|
-
histograms_instance,
|
|
252
|
-
histograms_instance.dict_1d_distributions[property_name]["function"],
|
|
253
|
-
)
|
|
254
|
-
hist_values, bin_edges = _function()
|
|
255
|
-
all_figs = []
|
|
256
|
-
for i_hist, _ in enumerate(bin_edges):
|
|
257
|
-
fig, ax = plt.subplots()
|
|
258
|
-
ax.bar(
|
|
259
|
-
bin_edges[i_hist][:-1],
|
|
260
|
-
hist_values[i_hist],
|
|
261
|
-
align="edge",
|
|
262
|
-
width=np.abs(np.diff(bin_edges[i_hist])),
|
|
263
|
-
)
|
|
264
|
-
if (
|
|
265
|
-
histograms_instance.dict_1d_distributions[property_name]["axis unit"]
|
|
266
|
-
is not u.dimensionless_unscaled
|
|
267
|
-
):
|
|
268
|
-
ax.set_xlabel(
|
|
269
|
-
f"{histograms_instance.dict_1d_distributions[property_name]['bin edges']} "
|
|
270
|
-
f"({histograms_instance.dict_1d_distributions[property_name]['axis unit']})"
|
|
271
|
-
)
|
|
272
|
-
else:
|
|
273
|
-
ax.set_xlabel(
|
|
274
|
-
f"{histograms_instance.dict_1d_distributions[property_name]['bin edges']} "
|
|
275
|
-
)
|
|
276
|
-
if property_name == "density":
|
|
277
|
-
ax.set_ylabel(
|
|
278
|
-
f"Density ({histograms_instance.dict_1d_distributions[property_name]['axis unit']}"
|
|
279
|
-
r"$^{-2}$)"
|
|
34
|
+
for i_file, hist_dict in enumerate(hist_list):
|
|
35
|
+
hist_values = hist_dict["hist_values"]
|
|
36
|
+
x_bin_edges = hist_dict["x_bin_edges"]
|
|
37
|
+
y_bin_edges = hist_dict["y_bin_edges"]
|
|
38
|
+
|
|
39
|
+
for i_hist, _ in enumerate(x_bin_edges):
|
|
40
|
+
fig, ax = plt.subplots()
|
|
41
|
+
if hist_dict.get("log_z", False):
|
|
42
|
+
max_val = np.amax(hist_values[i_hist])
|
|
43
|
+
norm = colors.LogNorm(vmin=1, vmax=np.amax([max_val, 2]))
|
|
44
|
+
else:
|
|
45
|
+
norm = None
|
|
46
|
+
mesh = ax.pcolormesh(
|
|
47
|
+
x_bin_edges[i_hist], y_bin_edges[i_hist], hist_values[i_hist], norm=norm
|
|
280
48
|
)
|
|
281
|
-
|
|
282
|
-
ax.set_ylabel("
|
|
49
|
+
ax.set_xlabel(_get_axis_label(hist_dict["x_axis_title"], hist_dict["x_axis_unit"]))
|
|
50
|
+
ax.set_ylabel(_get_axis_label(hist_dict["y_axis_title"], hist_dict["y_axis_unit"]))
|
|
51
|
+
ax.set_xlim(np.amin(x_bin_edges[i_hist]), np.amax(x_bin_edges[i_hist]))
|
|
52
|
+
ax.set_ylim(np.amin(y_bin_edges[i_hist]), np.amax(y_bin_edges[i_hist]))
|
|
53
|
+
ax.set_facecolor("black")
|
|
54
|
+
cbar = fig.colorbar(mesh)
|
|
55
|
+
cbar.set_label(_get_axis_label(hist_dict["z_axis_title"], hist_dict["z_axis_unit"]))
|
|
56
|
+
|
|
57
|
+
if labels is not None and i_file < len(labels):
|
|
58
|
+
label = labels[i_file]
|
|
59
|
+
else:
|
|
60
|
+
label = Path(hist_dict.get("input_file_name", f"File {i_file}")).name
|
|
61
|
+
ax.set_title(f"{hist_dict['title']} - {label}")
|
|
62
|
+
|
|
63
|
+
all_figs.append(fig)
|
|
64
|
+
plt.close()
|
|
283
65
|
|
|
284
|
-
if log_y is True:
|
|
285
|
-
ax.set_yscale("log")
|
|
286
|
-
if histograms_instance.individual_telescopes is False:
|
|
287
|
-
ax.set_title(
|
|
288
|
-
f"{histograms_instance.dict_1d_distributions[property_name]['file name']}_all_tels"
|
|
289
|
-
)
|
|
290
|
-
else:
|
|
291
|
-
ax.set_title(
|
|
292
|
-
f"{histograms_instance.dict_1d_distributions[property_name]['file name']}"
|
|
293
|
-
f"_tel_index_{histograms_instance.telescope_indices[i_hist]}",
|
|
294
|
-
)
|
|
295
|
-
all_figs.append(fig)
|
|
296
|
-
plt.close(fig)
|
|
297
66
|
return all_figs
|
|
298
67
|
|
|
299
68
|
|
|
300
|
-
def
|
|
301
|
-
"""
|
|
302
|
-
|
|
69
|
+
def _get_histogram_label(hist_dict, i_file, labels):
|
|
70
|
+
"""Get label for histogram curve."""
|
|
71
|
+
if labels is not None and i_file < len(labels):
|
|
72
|
+
return labels[i_file]
|
|
73
|
+
return Path(hist_dict.get("input_file_name", f"File {i_file}")).name
|
|
303
74
|
|
|
304
|
-
Parameters
|
|
305
|
-
----------
|
|
306
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
307
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
308
|
-
log_y: bool
|
|
309
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
310
75
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return _kernel_plot_1d_photons(histograms_instance, "wavelength", log_y=log_y)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def plot_counts_distr(histograms_instance, log_y=True):
|
|
320
|
-
"""
|
|
321
|
-
Plot the 1D distribution, i.e. the radial distribution, of the photons on the ground.
|
|
322
|
-
|
|
323
|
-
Parameters
|
|
324
|
-
----------
|
|
325
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
326
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
327
|
-
log_y: bool
|
|
328
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
329
|
-
|
|
330
|
-
Returns
|
|
331
|
-
-------
|
|
332
|
-
list
|
|
333
|
-
List of figures for the given telescopes.
|
|
334
|
-
"""
|
|
335
|
-
return _kernel_plot_1d_photons(histograms_instance, "counts", log_y=log_y)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
def plot_density_distr(histograms_instance, log_y=True):
|
|
339
|
-
"""
|
|
340
|
-
Plot the photon density distribution on the ground.
|
|
341
|
-
|
|
342
|
-
Parameters
|
|
343
|
-
----------
|
|
344
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
345
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
346
|
-
log_y: bool
|
|
347
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
348
|
-
|
|
349
|
-
Returns
|
|
350
|
-
-------
|
|
351
|
-
list
|
|
352
|
-
List of figures for the given telescopes.
|
|
353
|
-
"""
|
|
354
|
-
return _kernel_plot_1d_photons(histograms_instance, "density", log_y=log_y)
|
|
76
|
+
def _extract_uncertainty(uncertainties, i_hist):
|
|
77
|
+
"""Extract uncertainty values if available."""
|
|
78
|
+
if uncertainties is not None and uncertainties[i_hist] is not None:
|
|
79
|
+
return uncertainties[i_hist]
|
|
80
|
+
return None
|
|
355
81
|
|
|
356
82
|
|
|
357
|
-
def
|
|
358
|
-
"""
|
|
359
|
-
|
|
83
|
+
def _plot_histogram_curve(ax, bin_centers, hist_values, uncertainties, color, label):
|
|
84
|
+
"""Plot a single histogram curve with or without error bars."""
|
|
85
|
+
common_params = {
|
|
86
|
+
"color": color,
|
|
87
|
+
"label": label,
|
|
88
|
+
"marker": "o",
|
|
89
|
+
"markersize": 3,
|
|
90
|
+
"linestyle": "-",
|
|
91
|
+
"linewidth": 0.5,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if uncertainties is not None:
|
|
95
|
+
ax.errorbar(
|
|
96
|
+
bin_centers,
|
|
97
|
+
hist_values,
|
|
98
|
+
yerr=uncertainties,
|
|
99
|
+
capsize=2,
|
|
100
|
+
capthick=0.5,
|
|
101
|
+
**common_params,
|
|
102
|
+
)
|
|
103
|
+
else:
|
|
104
|
+
ax.plot(bin_centers, hist_values, **common_params)
|
|
360
105
|
|
|
361
|
-
Parameters
|
|
362
|
-
----------
|
|
363
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
364
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
365
|
-
log_y: bool
|
|
366
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
367
106
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
""
|
|
373
|
-
|
|
107
|
+
def _configure_plot_scales(ax, hist):
|
|
108
|
+
"""Configure x and y axis scales."""
|
|
109
|
+
if len(hist["x_bins"]) > 3 and hist["x_bins"][3] == "log":
|
|
110
|
+
ax.set_xscale("log")
|
|
111
|
+
if hist["log_y"] is True:
|
|
112
|
+
ax.set_yscale("log")
|
|
374
113
|
|
|
375
114
|
|
|
376
|
-
def
|
|
115
|
+
def _plot_1d(hist_list, labels=None):
|
|
377
116
|
"""
|
|
378
|
-
Plot
|
|
117
|
+
Plot 1D Cherenkov photon distributions.
|
|
379
118
|
|
|
380
119
|
Parameters
|
|
381
120
|
----------
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
121
|
+
hist_list: list
|
|
122
|
+
List of histogram dictionaries from different files.
|
|
123
|
+
labels: list or None
|
|
124
|
+
Optional list of labels for the histogram curves. If None, uses file names.
|
|
386
125
|
|
|
387
126
|
Returns
|
|
388
127
|
-------
|
|
389
128
|
list
|
|
390
|
-
List of figures
|
|
129
|
+
List of figures.
|
|
391
130
|
"""
|
|
392
|
-
|
|
393
|
-
|
|
131
|
+
if not hist_list:
|
|
132
|
+
return []
|
|
394
133
|
|
|
395
|
-
|
|
396
|
-
""
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
Parameters
|
|
400
|
-
----------
|
|
401
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
402
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
403
|
-
log_y: bool
|
|
404
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
405
|
-
|
|
406
|
-
Returns
|
|
407
|
-
-------
|
|
408
|
-
list
|
|
409
|
-
List of figures for the given telescopes.
|
|
134
|
+
hist = hist_list[0]
|
|
135
|
+
plot_colors = colormaps["tab10"](np.linspace(0, 1, len(hist_list)))
|
|
136
|
+
fig, ax = plt.subplots()
|
|
410
137
|
|
|
411
|
-
|
|
412
|
-
|
|
138
|
+
for i_file, (hist_dict, color) in enumerate(zip(hist_list, plot_colors)):
|
|
139
|
+
hist_values = hist_dict["hist_values"]
|
|
140
|
+
x_bin_edges = hist_dict["x_bin_edges"]
|
|
141
|
+
uncertainties = hist_dict.get("uncertainties")
|
|
142
|
+
label = _get_histogram_label(hist_dict, i_file, labels)
|
|
413
143
|
|
|
144
|
+
for i_hist, x_edges in enumerate(x_bin_edges):
|
|
145
|
+
bin_centers = (x_edges[:-1] + x_edges[1:]) / 2
|
|
146
|
+
unc = _extract_uncertainty(uncertainties, i_hist)
|
|
147
|
+
_plot_histogram_curve(ax, bin_centers, hist_values[i_hist], unc, color, label)
|
|
414
148
|
|
|
415
|
-
|
|
416
|
-
"""
|
|
417
|
-
|
|
149
|
+
ax.set_xlabel(_get_axis_label(hist["x_axis_title"], hist["x_axis_unit"]))
|
|
150
|
+
ax.set_ylabel(_get_axis_label(hist["y_axis_title"], hist["y_axis_unit"]))
|
|
151
|
+
_configure_plot_scales(ax, hist)
|
|
152
|
+
ax.set_title(f"{hist['title']}")
|
|
153
|
+
ax.legend()
|
|
154
|
+
ax.grid(True, alpha=0.3)
|
|
418
155
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
422
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
423
|
-
log_y: bool
|
|
424
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
156
|
+
plt.close(fig)
|
|
157
|
+
return [fig]
|
|
425
158
|
|
|
426
|
-
Returns
|
|
427
|
-
-------
|
|
428
|
-
list
|
|
429
|
-
List of figures for the given telescopes.
|
|
430
159
|
|
|
431
|
-
|
|
432
|
-
|
|
160
|
+
def _get_axis_label(title, unit):
|
|
161
|
+
"""Return axis label with unit if applicable."""
|
|
162
|
+
if unit is not u.dimensionless_unscaled:
|
|
163
|
+
return f"{title} ({unit})"
|
|
164
|
+
return f"{title}"
|
|
433
165
|
|
|
434
166
|
|
|
435
|
-
def
|
|
436
|
-
|
|
437
|
-
):
|
|
438
|
-
"""
|
|
439
|
-
Plot the distribution of the quantity given by .
|
|
167
|
+
def _build_all_photon_figures(histograms_list, labels=None):
|
|
168
|
+
"""Build list of all photon histogram figures.
|
|
440
169
|
|
|
441
170
|
Parameters
|
|
442
171
|
----------
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
log_y: bool
|
|
448
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
449
|
-
bins: float
|
|
450
|
-
Number of bins for the histogram.
|
|
451
|
-
hist_range: 2-tuple
|
|
452
|
-
Tuple to define the range of the histogram.
|
|
172
|
+
histograms_list: list
|
|
173
|
+
List of CorsikaHistograms instances from different input files.
|
|
174
|
+
labels: list or None
|
|
175
|
+
Optional list of labels for the input files. If None, uses file names.
|
|
453
176
|
|
|
454
177
|
Returns
|
|
455
178
|
-------
|
|
456
179
|
list
|
|
457
|
-
List of figures
|
|
458
|
-
|
|
180
|
+
List of figures.
|
|
459
181
|
"""
|
|
460
|
-
|
|
461
|
-
event_header_element, bins=bins, hist_range=hist_range
|
|
462
|
-
)
|
|
463
|
-
fig, ax = plt.subplots()
|
|
464
|
-
ax.bar(
|
|
465
|
-
bin_edges[:-1],
|
|
466
|
-
hist_values,
|
|
467
|
-
align="edge",
|
|
468
|
-
width=np.abs(np.diff(bin_edges)),
|
|
469
|
-
)
|
|
470
|
-
if (
|
|
471
|
-
histograms_instance.event_information[event_header_element].unit
|
|
472
|
-
is not u.dimensionless_unscaled
|
|
473
|
-
):
|
|
474
|
-
ax.set_xlabel(
|
|
475
|
-
f"{event_header_element} ("
|
|
476
|
-
f"{histograms_instance.event_information[event_header_element].unit})"
|
|
477
|
-
)
|
|
478
|
-
else:
|
|
479
|
-
ax.set_xlabel(f"{event_header_element}")
|
|
480
|
-
ax.set_ylabel("Counts")
|
|
182
|
+
all_figs = []
|
|
481
183
|
|
|
482
|
-
if
|
|
483
|
-
|
|
484
|
-
ax.set_title(f"hist_1d_{event_header_element}")
|
|
485
|
-
return fig
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
def plot_2d_event_header_distribution(
|
|
489
|
-
histograms_instance,
|
|
490
|
-
event_header_element_1,
|
|
491
|
-
event_header_element_2,
|
|
492
|
-
log_z=True,
|
|
493
|
-
bins=50,
|
|
494
|
-
hist_range=None,
|
|
495
|
-
):
|
|
496
|
-
"""
|
|
497
|
-
Plot the distribution of the quantity given by CorsikaHistograms.
|
|
184
|
+
if not isinstance(histograms_list, list):
|
|
185
|
+
histograms_list = [histograms_list]
|
|
498
186
|
|
|
499
|
-
|
|
500
|
-
----------
|
|
501
|
-
histograms_instance: corsika.corsika_histograms.CorsikaHistograms
|
|
502
|
-
instance of corsika.corsika_histograms.CorsikaHistograms.
|
|
503
|
-
event_header_element_1: str
|
|
504
|
-
The first key to the CORSIKA event header element
|
|
505
|
-
event_header_element_2: str
|
|
506
|
-
The second key to the CORSIKA event header element.
|
|
507
|
-
log_z: bool
|
|
508
|
-
if True, the intensity of the Y axis is given in logarithmic scale.
|
|
509
|
-
bins: float
|
|
510
|
-
Number of bins for the histogram.
|
|
511
|
-
hist_range: 2-tuple
|
|
512
|
-
Tuple to define the range of the histogram.
|
|
187
|
+
hist_keys = list(histograms_list[0].hist.keys())
|
|
513
188
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
list
|
|
517
|
-
List of figures for the given telescopes.
|
|
189
|
+
for hist_key in hist_keys:
|
|
190
|
+
hist_from_all_files = [h.hist[hist_key] for h in histograms_list]
|
|
518
191
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
fig, ax = plt.subplots()
|
|
524
|
-
if log_z is True:
|
|
525
|
-
norm = colors.LogNorm(vmin=1, vmax=np.amax([np.amax(hist_values), 2]))
|
|
526
|
-
else:
|
|
527
|
-
norm = None
|
|
528
|
-
mesh = ax.pcolormesh(x_bin_edges, y_bin_edges, hist_values, norm=norm)
|
|
529
|
-
|
|
530
|
-
if (
|
|
531
|
-
histograms_instance.event_information[event_header_element_1].unit
|
|
532
|
-
is not u.dimensionless_unscaled
|
|
533
|
-
):
|
|
534
|
-
ax.set_xlabel(
|
|
535
|
-
f"{event_header_element_1} ("
|
|
536
|
-
f"{histograms_instance.event_information[event_header_element_1].unit})"
|
|
537
|
-
)
|
|
538
|
-
else:
|
|
539
|
-
ax.set_xlabel(f"{event_header_element_2}")
|
|
540
|
-
if (
|
|
541
|
-
histograms_instance.event_information[event_header_element_2].unit
|
|
542
|
-
is not u.dimensionless_unscaled
|
|
543
|
-
):
|
|
544
|
-
ax.set_ylabel(
|
|
545
|
-
f"{event_header_element_2} "
|
|
546
|
-
f"({histograms_instance.event_information[event_header_element_2].unit})"
|
|
547
|
-
)
|
|
548
|
-
else:
|
|
549
|
-
ax.set_ylabel(f"{event_header_element_2}")
|
|
192
|
+
if hist_from_all_files[0]["is_1d"]:
|
|
193
|
+
all_figs.extend(_plot_1d(hist_from_all_files, labels=labels))
|
|
194
|
+
else:
|
|
195
|
+
all_figs.extend(_plot_2d(hist_from_all_files, labels=labels))
|
|
550
196
|
|
|
551
|
-
|
|
552
|
-
ax.set_title(f"hist_2d_{event_header_element_1}_{event_header_element_2}")
|
|
553
|
-
fig.colorbar(mesh)
|
|
554
|
-
return fig
|
|
197
|
+
return all_figs
|
|
555
198
|
|
|
556
199
|
|
|
557
|
-
def
|
|
200
|
+
def export_all_photon_figures_pdf(histograms_instance, pdf_file_name, labels=None):
|
|
558
201
|
"""
|
|
559
|
-
|
|
202
|
+
Build and save all photon histogram figures into a single PDF.
|
|
560
203
|
|
|
561
204
|
Parameters
|
|
562
205
|
----------
|
|
563
|
-
|
|
564
|
-
|
|
206
|
+
histograms_instance: corsika.corsika_histograms.CorsikaHistograms or list
|
|
207
|
+
Single histogram instance or list of CorsikaHistograms instances from multiple files.
|
|
208
|
+
When a list is provided, 1D histograms from all files are combined into single plots
|
|
209
|
+
with different colors, while 2D histograms of the same type are plotted sequentially.
|
|
565
210
|
pdf_file_name: str or Path
|
|
566
|
-
Name of the pdf file.
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
plt.tight_layout()
|
|
571
|
-
pdf_pages.savefig(fig)
|
|
572
|
-
pdf_pages.close()
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
def build_all_photon_figures(histograms_instance, test: bool = False):
|
|
576
|
-
"""Return list of all photon histogram figures for the given instance.
|
|
577
|
-
|
|
578
|
-
When test is True, only generate the first two figure groups to reduce runtime.
|
|
211
|
+
Name of the output pdf file to save the histograms.
|
|
212
|
+
labels: list or None
|
|
213
|
+
Optional list of labels for the input files. If None, file names are used as labels.
|
|
214
|
+
The order should match the order of histograms_instance if it's a list.
|
|
579
215
|
"""
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
name
|
|
583
|
-
for name, obj in globals().items()
|
|
584
|
-
if name.startswith("plot_")
|
|
585
|
-
and "event_header_distribution" not in name
|
|
586
|
-
and callable(obj)
|
|
587
|
-
]
|
|
216
|
+
save_figures_to_single_document(
|
|
217
|
+
_build_all_photon_figures(histograms_instance, labels=labels), Path(pdf_file_name)
|
|
588
218
|
)
|
|
589
|
-
if test:
|
|
590
|
-
plot_function_names = plot_function_names[:2]
|
|
591
|
-
|
|
592
|
-
figure_list = []
|
|
593
|
-
module_obj = globals()
|
|
594
|
-
for fn_name in plot_function_names:
|
|
595
|
-
plot_fn = module_obj[fn_name]
|
|
596
|
-
figs = plot_fn(histograms_instance)
|
|
597
|
-
for fig in figs:
|
|
598
|
-
figure_list.append(fig)
|
|
599
|
-
return np.array(figure_list).flatten()
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
def export_all_photon_figures_pdf(histograms_instance, test: bool = False):
|
|
603
|
-
"""Build and save all photon histogram figures into a single PDF.
|
|
604
|
-
|
|
605
|
-
The PDF name is derived from the HDF5 file name core and written under output_path.
|
|
606
|
-
"""
|
|
607
|
-
figs = build_all_photon_figures(histograms_instance, test=test)
|
|
608
|
-
core_name = re.sub(r"\.hdf5$", "", Path(histograms_instance.hdf5_file_name).name)
|
|
609
|
-
output_file_name = Path(histograms_instance.output_path).joinpath(f"{core_name}.pdf")
|
|
610
|
-
save_figs_to_pdf(figs, output_file_name)
|
|
611
|
-
return output_file_name
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
def derive_event_1d_histograms(
|
|
615
|
-
histograms_instance,
|
|
616
|
-
event_1d_header_keys,
|
|
617
|
-
pdf: bool,
|
|
618
|
-
hdf5: bool,
|
|
619
|
-
overwrite: bool = False,
|
|
620
|
-
):
|
|
621
|
-
"""Create 1D event header histograms; optionally save to PDF and/or HDF5."""
|
|
622
|
-
figure_list = []
|
|
623
|
-
for key in event_1d_header_keys:
|
|
624
|
-
if pdf:
|
|
625
|
-
fig = plot_1d_event_header_distribution(histograms_instance, key)
|
|
626
|
-
figure_list.append(fig)
|
|
627
|
-
if hdf5:
|
|
628
|
-
histograms_instance.export_event_header_1d_histogram(
|
|
629
|
-
key, bins=50, hist_range=None, overwrite=overwrite
|
|
630
|
-
)
|
|
631
|
-
if pdf:
|
|
632
|
-
figs_array = np.array(figure_list).flatten()
|
|
633
|
-
pdf_name = Path(histograms_instance.output_path).joinpath(
|
|
634
|
-
f"{Path(histograms_instance.hdf5_file_name).name}_event_1d_histograms.pdf"
|
|
635
|
-
)
|
|
636
|
-
save_figs_to_pdf(figs_array, pdf_name)
|
|
637
|
-
return pdf_name
|
|
638
|
-
return None
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
def derive_event_2d_histograms(
|
|
642
|
-
histograms_instance,
|
|
643
|
-
event_2d_header_keys,
|
|
644
|
-
pdf: bool,
|
|
645
|
-
hdf5: bool,
|
|
646
|
-
overwrite: bool = False,
|
|
647
|
-
):
|
|
648
|
-
"""Create 2D event header histograms in pairs; optionally save PDF and/or HDF5.
|
|
649
|
-
|
|
650
|
-
If an odd number of keys is provided, the last one is ignored (with a warning).
|
|
651
|
-
"""
|
|
652
|
-
if len(event_2d_header_keys) % 2 == 1:
|
|
653
|
-
_logger.warning(
|
|
654
|
-
"An odd number of keys was passed to generate 2D histograms.\n"
|
|
655
|
-
"The last key is being ignored."
|
|
656
|
-
)
|
|
657
|
-
|
|
658
|
-
figure_list = []
|
|
659
|
-
for i, _ in enumerate(event_2d_header_keys[::2]):
|
|
660
|
-
if pdf:
|
|
661
|
-
fig = plot_2d_event_header_distribution(
|
|
662
|
-
histograms_instance, event_2d_header_keys[i], event_2d_header_keys[i + 1]
|
|
663
|
-
)
|
|
664
|
-
figure_list.append(fig)
|
|
665
|
-
if hdf5:
|
|
666
|
-
histograms_instance.export_event_header_2d_histogram(
|
|
667
|
-
event_2d_header_keys[i],
|
|
668
|
-
event_2d_header_keys[i + 1],
|
|
669
|
-
bins=50,
|
|
670
|
-
hist_range=None,
|
|
671
|
-
overwrite=overwrite,
|
|
672
|
-
)
|
|
673
|
-
if pdf:
|
|
674
|
-
figs_array = np.array(figure_list).flatten()
|
|
675
|
-
pdf_name = Path(histograms_instance.output_path).joinpath(
|
|
676
|
-
f"{Path(histograms_instance.hdf5_file_name).name}_event_2d_histograms.pdf"
|
|
677
|
-
)
|
|
678
|
-
save_figs_to_pdf(figs_array, pdf_name)
|
|
679
|
-
return pdf_name
|
|
680
|
-
return None
|