gammasimtools 0.15.0__py3-none-any.whl → 0.17.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.15.0.dist-info → gammasimtools-0.17.0.dist-info}/METADATA +5 -33
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/RECORD +243 -229
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/entry_points.txt +8 -3
- simtools/_version.py +2 -2
- simtools/applications/calculate_trigger_rate.py +10 -10
- simtools/applications/convert_all_model_parameters_from_simtel.py +16 -16
- simtools/applications/convert_model_parameter_from_simtel.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +5 -5
- simtools/applications/derive_psf_parameters.py +12 -9
- simtools/applications/docs_produce_array_element_report.py +3 -3
- simtools/applications/docs_produce_calibration_reports.py +49 -0
- simtools/applications/docs_produce_simulation_configuration_report.py +50 -0
- simtools/applications/{generate_simtel_array_histograms.py → generate_sim_telarray_histograms.py} +2 -2
- simtools/applications/generate_simtel_event_data.py +36 -46
- simtools/applications/merge_tables.py +104 -0
- simtools/applications/plot_array_layout.py +145 -258
- simtools/applications/production_derive_corsika_limits.py +35 -167
- simtools/applications/production_derive_statistics.py +159 -0
- simtools/applications/production_generate_grid.py +197 -0
- simtools/applications/simulate_light_emission.py +6 -13
- simtools/applications/simulate_prod.py +45 -21
- simtools/applications/simulate_prod_htcondor_generator.py +0 -1
- simtools/applications/submit_array_layouts.py +93 -0
- simtools/applications/validate_cumulative_psf.py +6 -4
- simtools/applications/validate_file_using_schema.py +7 -3
- simtools/applications/validate_optics.py +5 -4
- simtools/applications/verify_simulation_model_production_tables.py +52 -0
- simtools/camera/camera_efficiency.py +17 -42
- simtools/configuration/commandline_parser.py +32 -37
- simtools/configuration/configurator.py +10 -4
- simtools/corsika/corsika_config.py +120 -17
- simtools/corsika/primary_particle.py +46 -13
- simtools/data_model/format_checkers.py +9 -0
- simtools/data_model/metadata_collector.py +7 -3
- simtools/data_model/model_data_writer.py +3 -0
- simtools/data_model/schema.py +27 -16
- simtools/data_model/validate_data.py +27 -7
- simtools/db/db_handler.py +21 -15
- simtools/db/db_model_upload.py +2 -2
- simtools/io_operations/io_handler.py +2 -2
- simtools/io_operations/io_table_handler.py +345 -0
- simtools/job_execution/htcondor_script_generator.py +2 -2
- simtools/job_execution/job_manager.py +7 -121
- simtools/layout/array_layout.py +1 -0
- simtools/layout/array_layout_utils.py +385 -0
- simtools/model/array_model.py +68 -29
- simtools/model/model_parameter.py +76 -51
- simtools/model/model_repository.py +134 -0
- simtools/model/model_utils.py +43 -1
- simtools/model/site_model.py +3 -2
- simtools/model/telescope_model.py +4 -4
- simtools/production_configuration/{calculate_statistical_errors_grid_point.py → calculate_statistical_uncertainties_grid_point.py} +101 -116
- simtools/production_configuration/derive_corsika_limits.py +239 -111
- simtools/production_configuration/derive_corsika_limits_grid.py +189 -0
- simtools/production_configuration/derive_production_statistics.py +155 -0
- simtools/production_configuration/derive_production_statistics_handler.py +152 -0
- simtools/production_configuration/generate_production_grid.py +364 -0
- simtools/production_configuration/interpolation_handler.py +303 -96
- simtools/ray_tracing/mirror_panel_psf.py +16 -20
- simtools/ray_tracing/psf_analysis.py +2 -2
- simtools/ray_tracing/ray_tracing.py +12 -7
- simtools/reporting/docs_read_parameters.py +426 -81
- simtools/runners/corsika_runner.py +11 -1
- simtools/runners/corsika_simtel_runner.py +84 -90
- simtools/runners/runner_services.py +22 -8
- simtools/runners/simtel_runner.py +27 -10
- simtools/schemas/model_parameter.metaschema.yml +4 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +1 -0
- simtools/schemas/model_parameters/adjust_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +2 -2
- simtools/schemas/model_parameters/array_window.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_file.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_depth.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_filter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_pixels.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +2 -2
- simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +2 -2
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +90 -1
- simtools/schemas/model_parameters/default_trigger.schema.yml +2 -2
- simtools/schemas/model_parameters/design_model.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_start.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +44 -3
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +2 -2
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
- simtools/schemas/model_parameters/flatfielding.schema.yml +2 -2
- simtools/schemas/model_parameters/focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/focus_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/gain_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photons.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_class.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_list.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +2 -2
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +2 -2
- simtools/schemas/model_parameters/num_gains.schema.yml +2 -2
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +2 -2
- simtools/schemas/model_parameters/optics_properties.schema.yml +2 -2
- simtools/schemas/model_parameters/pedestal_events.schema.yml +7 -3
- simtools/schemas/model_parameters/photon_delay.schema.yml +2 -2
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/qe_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/random_generator.schema.yml +2 -2
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +2 -2
- simtools/schemas/model_parameters/sampled_output.schema.yml +2 -2
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +2 -2
- simtools/schemas/production_configuration_metrics.schema.yml +2 -2
- simtools/simtel/simtel_config_reader.py +21 -17
- simtools/simtel/simtel_config_writer.py +258 -66
- simtools/simtel/simtel_io_event_reader.py +301 -194
- simtools/simtel/simtel_io_event_writer.py +207 -227
- simtools/simtel/simtel_io_file_info.py +62 -0
- simtools/simtel/simtel_io_histogram.py +10 -14
- simtools/simtel/simtel_io_histograms.py +2 -2
- simtools/simtel/simtel_io_metadata.py +106 -0
- simtools/simtel/simulator_array.py +28 -14
- simtools/simtel/simulator_camera_efficiency.py +12 -6
- simtools/simtel/simulator_light_emission.py +85 -45
- simtools/simtel/simulator_ray_tracing.py +16 -6
- simtools/simulator.py +286 -89
- simtools/testing/configuration.py +5 -0
- simtools/testing/helpers.py +18 -0
- simtools/testing/sim_telarray_metadata.py +212 -0
- simtools/testing/validate_output.py +16 -6
- simtools/utils/general.py +18 -27
- simtools/utils/names.py +32 -10
- simtools/visualization/plot_array_layout.py +242 -0
- simtools/visualization/plot_pixels.py +681 -0
- simtools/visualization/visualize.py +5 -221
- simtools/applications/production_generate_simulation_config.py +0 -162
- simtools/applications/production_scale_events.py +0 -185
- simtools/layout/ctao_array_layouts.py +0 -172
- simtools/production_configuration/event_scaler.py +0 -120
- simtools/production_configuration/generate_simulation_config.py +0 -158
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
"""Generate a reduced dataset from
|
|
1
|
+
"""Generate a reduced dataset from sim_telarray output files using astropy tables."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from dataclasses import dataclass
|
|
4
|
+
from dataclasses import dataclass
|
|
5
5
|
|
|
6
|
+
import astropy.units as u
|
|
6
7
|
import numpy as np
|
|
7
|
-
import
|
|
8
|
+
from astropy.table import Table
|
|
8
9
|
from eventio import EventIOFile
|
|
9
10
|
from eventio.simtel import (
|
|
10
11
|
ArrayEvent,
|
|
@@ -15,107 +16,132 @@ from eventio.simtel import (
|
|
|
15
16
|
TriggerInformation,
|
|
16
17
|
)
|
|
17
18
|
|
|
19
|
+
from simtools.corsika.primary_particle import PrimaryParticle
|
|
20
|
+
from simtools.simtel.simtel_io_file_info import get_corsika_run_header
|
|
18
21
|
from simtools.utils.geometry import calculate_circular_mean
|
|
19
22
|
|
|
20
|
-
DEFAULT_FILTERS = tables.Filters(complevel=5, complib="zlib", shuffle=True, bitshuffle=False)
|
|
21
|
-
|
|
22
23
|
|
|
23
24
|
@dataclass
|
|
24
|
-
class
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
25
|
+
class TableSchemas:
|
|
26
|
+
"""Define schemas for output tables with units."""
|
|
27
|
+
|
|
28
|
+
shower_schema = {
|
|
29
|
+
"shower_id": (np.uint32, None),
|
|
30
|
+
"event_id": (np.uint32, None),
|
|
31
|
+
"file_id": (np.uint32, None),
|
|
32
|
+
"simulated_energy": (np.float64, u.TeV),
|
|
33
|
+
"x_core": (np.float64, u.m),
|
|
34
|
+
"y_core": (np.float64, u.m),
|
|
35
|
+
"shower_azimuth": (np.float64, u.rad),
|
|
36
|
+
"shower_altitude": (np.float64, u.rad),
|
|
37
|
+
"area_weight": (np.float64, None),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
trigger_schema = {
|
|
41
|
+
"shower_id": (np.uint32, None),
|
|
42
|
+
"event_id": (np.uint32, None),
|
|
43
|
+
"file_id": (np.uint32, None),
|
|
44
|
+
"array_altitude": (np.float64, u.rad),
|
|
45
|
+
"array_azimuth": (np.float64, u.rad),
|
|
46
|
+
"telescope_list": (str, None), # Store as comma-separated string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
file_info_schema = {
|
|
50
|
+
"file_name": (str, None),
|
|
51
|
+
"file_id": (np.uint32, None),
|
|
52
|
+
"particle_id": (np.uint32, None),
|
|
53
|
+
"energy_min": (np.float64, u.TeV),
|
|
54
|
+
"energy_max": (np.float64, u.TeV),
|
|
55
|
+
"viewcone_min": (np.float64, u.deg),
|
|
56
|
+
"viewcone_max": (np.float64, u.deg),
|
|
57
|
+
"core_scatter_min": (np.float64, u.m),
|
|
58
|
+
"core_scatter_max": (np.float64, u.m),
|
|
59
|
+
"zenith": (np.float64, u.deg),
|
|
60
|
+
"azimuth": (np.float64, u.deg),
|
|
61
|
+
"nsb_level": (np.float64, None),
|
|
62
|
+
}
|
|
49
63
|
|
|
50
64
|
|
|
51
65
|
class SimtelIOEventDataWriter:
|
|
52
66
|
"""
|
|
53
|
-
|
|
67
|
+
Process sim_telarray events and write tables to file.
|
|
68
|
+
|
|
69
|
+
Extracts essential information from sim_telarray output files:
|
|
70
|
+
|
|
71
|
+
- Shower parameters (energy, core location, direction)
|
|
72
|
+
- Trigger patterns
|
|
73
|
+
- Telescope pointing
|
|
54
74
|
|
|
55
75
|
Attributes
|
|
56
76
|
----------
|
|
57
77
|
input_files : list
|
|
58
78
|
List of input file paths to process.
|
|
59
|
-
output_file : str
|
|
60
|
-
Path to the output file.
|
|
61
79
|
max_files : int, optional
|
|
62
80
|
Maximum number of files to process.
|
|
63
81
|
"""
|
|
64
82
|
|
|
65
|
-
def __init__(self, input_files,
|
|
83
|
+
def __init__(self, input_files, max_files=100):
|
|
66
84
|
"""Initialize class."""
|
|
67
85
|
self._logger = logging.getLogger(__name__)
|
|
68
86
|
self.input_files = input_files
|
|
69
|
-
self.output_file = output_file
|
|
70
87
|
try:
|
|
71
88
|
self.max_files = max_files if max_files < len(input_files) else len(input_files)
|
|
72
89
|
except TypeError as exc:
|
|
73
90
|
raise TypeError("No input files provided.") from exc
|
|
74
|
-
|
|
91
|
+
|
|
75
92
|
self.n_use = None
|
|
76
|
-
self.
|
|
77
|
-
self.
|
|
78
|
-
self.
|
|
79
|
-
self.file_names = []
|
|
93
|
+
self.shower_data = []
|
|
94
|
+
self.trigger_data = []
|
|
95
|
+
self.file_info = []
|
|
80
96
|
|
|
81
97
|
def process_files(self):
|
|
82
|
-
"""Process the input files and store them in an file."""
|
|
83
|
-
self.shower_id_offset = 0
|
|
84
|
-
|
|
85
|
-
for i, file in enumerate(self.input_files[: self.max_files], start=1):
|
|
86
|
-
self._logger.info(f"Processing file {i}/{self.max_files}: {file}")
|
|
87
|
-
self._process_file(file)
|
|
88
|
-
if i == 1 or len(self.event_data.simulated_energy) >= 1e7:
|
|
89
|
-
self._write_data(mode="w" if i == 1 else "a")
|
|
90
|
-
self.shower_id_offset += len(self.event_data.simulated_energy)
|
|
91
|
-
self._reset_data()
|
|
92
|
-
|
|
93
|
-
self._write_data(mode="a")
|
|
94
|
-
|
|
95
|
-
def get_event_data(self):
|
|
96
98
|
"""
|
|
97
|
-
|
|
99
|
+
Process input files and return tables.
|
|
98
100
|
|
|
99
101
|
Returns
|
|
100
102
|
-------
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
list
|
|
104
|
+
List of astropy tables containing processed data.
|
|
103
105
|
"""
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
for i, file in enumerate(self.input_files[: self.max_files]):
|
|
107
|
+
self._logger.info(f"Processing file {i + 1}/{self.max_files}: {file}")
|
|
108
|
+
self._process_file(i, file)
|
|
109
|
+
|
|
110
|
+
return self.create_tables()
|
|
111
|
+
|
|
112
|
+
def create_tables(self):
|
|
113
|
+
"""Create astropy tables from collected data."""
|
|
114
|
+
tables = []
|
|
115
|
+
for data, schema, name in [
|
|
116
|
+
(self.shower_data, TableSchemas.shower_schema, "SHOWERS"),
|
|
117
|
+
(self.trigger_data, TableSchemas.trigger_schema, "TRIGGERS"),
|
|
118
|
+
(self.file_info, TableSchemas.file_info_schema, "FILE_INFO"),
|
|
119
|
+
]:
|
|
120
|
+
table = Table(rows=data, names=schema.keys())
|
|
121
|
+
table.meta["EXTNAME"] = name
|
|
122
|
+
self._add_units_to_table(table, schema)
|
|
123
|
+
tables.append(table)
|
|
124
|
+
return tables
|
|
125
|
+
|
|
126
|
+
def _add_units_to_table(self, table, schema):
|
|
127
|
+
"""Add units to a single table's columns."""
|
|
128
|
+
for col, (_, unit) in schema.items():
|
|
129
|
+
if unit is not None:
|
|
130
|
+
table[col].unit = unit
|
|
131
|
+
|
|
132
|
+
def _process_file(self, file_id, file):
|
|
107
133
|
"""Process a single file and update data lists."""
|
|
134
|
+
self._process_file_info(file_id, file)
|
|
108
135
|
with EventIOFile(file) as f:
|
|
109
136
|
for eventio_object in f:
|
|
110
137
|
if isinstance(eventio_object, MCRunHeader):
|
|
111
138
|
self._process_mc_run_header(eventio_object)
|
|
112
139
|
elif isinstance(eventio_object, MCShower):
|
|
113
|
-
self._process_mc_shower(eventio_object)
|
|
140
|
+
self._process_mc_shower(eventio_object, file_id)
|
|
114
141
|
elif isinstance(eventio_object, MCEvent):
|
|
115
142
|
self._process_mc_event(eventio_object)
|
|
116
143
|
elif isinstance(eventio_object, ArrayEvent):
|
|
117
|
-
self._process_array_event(eventio_object)
|
|
118
|
-
self.file_names.append(str(file))
|
|
144
|
+
self._process_array_event(eventio_object, file_id)
|
|
119
145
|
|
|
120
146
|
def _process_mc_run_header(self, eventio_object):
|
|
121
147
|
"""Process MC run header and update data lists."""
|
|
@@ -123,36 +149,93 @@ class SimtelIOEventDataWriter:
|
|
|
123
149
|
self.n_use = mc_head["n_use"] # reuse factor n_use needed to extend the values below
|
|
124
150
|
self._logger.info(f"Shower reuse factor: {self.n_use} (viewcone: {mc_head['viewcone']})")
|
|
125
151
|
|
|
126
|
-
def
|
|
152
|
+
def _process_file_info(self, file_id, file):
|
|
153
|
+
"""Process file information and append to file info list."""
|
|
154
|
+
run_info = get_corsika_run_header(file)
|
|
155
|
+
particle = PrimaryParticle(
|
|
156
|
+
particle_id_type="eventio_id", particle_id=run_info.get("primary_id", 1)
|
|
157
|
+
)
|
|
158
|
+
self.file_info.append(
|
|
159
|
+
{
|
|
160
|
+
"file_name": str(file),
|
|
161
|
+
"file_id": file_id,
|
|
162
|
+
"particle_id": particle.corsika7_id,
|
|
163
|
+
"energy_min": run_info["E_range"][0],
|
|
164
|
+
"energy_max": run_info["E_range"][1],
|
|
165
|
+
"viewcone_min": run_info["viewcone"][0],
|
|
166
|
+
"viewcone_max": run_info["viewcone"][1],
|
|
167
|
+
"core_scatter_min": run_info["core_range"][0],
|
|
168
|
+
"core_scatter_max": run_info["core_range"][1],
|
|
169
|
+
"zenith": 90.0 - np.degrees(run_info["direction"][1]),
|
|
170
|
+
"azimuth": np.degrees(run_info["direction"][0]),
|
|
171
|
+
"nsb_level": self._get_preliminary_nsb_level(str(file)),
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
def _process_mc_shower(self, eventio_object, file_id):
|
|
127
176
|
"""
|
|
128
177
|
Process MC shower and update shower event list.
|
|
129
178
|
|
|
130
179
|
Duplicated entries 'self.n_use' times to match the number simulated events with
|
|
131
180
|
different core positions.
|
|
132
181
|
"""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
self.
|
|
136
|
-
|
|
137
|
-
|
|
182
|
+
shower = eventio_object.parse()
|
|
183
|
+
|
|
184
|
+
self.shower_data.extend(
|
|
185
|
+
{
|
|
186
|
+
"shower_id": shower["shower"],
|
|
187
|
+
"event_id": None, # filled in _process_mc_event
|
|
188
|
+
"file_id": file_id,
|
|
189
|
+
"simulated_energy": shower["energy"],
|
|
190
|
+
"x_core": None, # filled in _process_mc_event
|
|
191
|
+
"y_core": None, # filled in _process_mc_event
|
|
192
|
+
"shower_azimuth": shower["azimuth"],
|
|
193
|
+
"shower_altitude": shower["altitude"],
|
|
194
|
+
"area_weight": None, # filled in _process_mc_event
|
|
195
|
+
}
|
|
196
|
+
for _ in range(self.n_use)
|
|
197
|
+
)
|
|
138
198
|
|
|
139
199
|
def _process_mc_event(self, eventio_object):
|
|
140
|
-
"""
|
|
200
|
+
"""
|
|
201
|
+
Process MC event and update shower event list.
|
|
202
|
+
|
|
203
|
+
Expected to be called n_use times after _process_shower.
|
|
204
|
+
"""
|
|
141
205
|
event = eventio_object.parse()
|
|
142
206
|
|
|
143
|
-
self.
|
|
144
|
-
self.event_data.x_core.append(event["xcore"])
|
|
145
|
-
self.event_data.y_core.append(event["ycore"])
|
|
146
|
-
self.event_data.area_weight.append(event["aweight"])
|
|
207
|
+
shower_data_index = len(self.shower_data) - self.n_use + event["event_id"] % 100
|
|
147
208
|
|
|
148
|
-
|
|
209
|
+
try:
|
|
210
|
+
if self.shower_data[shower_data_index]["shower_id"] != event["shower_num"]:
|
|
211
|
+
raise IndexError
|
|
212
|
+
except IndexError as exc:
|
|
213
|
+
raise IndexError(
|
|
214
|
+
f"Inconsistent shower and MC event data for shower id {event['shower_num']}"
|
|
215
|
+
) from exc
|
|
216
|
+
|
|
217
|
+
self.shower_data[shower_data_index].update(
|
|
218
|
+
{
|
|
219
|
+
"event_id": event["event_id"],
|
|
220
|
+
"x_core": event["xcore"],
|
|
221
|
+
"y_core": event["ycore"],
|
|
222
|
+
"area_weight": event["aweight"],
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
def _process_array_event(self, eventio_object, file_id):
|
|
149
227
|
"""Process array event and update triggered event list."""
|
|
150
228
|
tracking_positions = []
|
|
229
|
+
telescopes = []
|
|
151
230
|
|
|
152
|
-
for
|
|
231
|
+
for obj in eventio_object:
|
|
153
232
|
if isinstance(obj, TriggerInformation):
|
|
154
|
-
|
|
155
|
-
|
|
233
|
+
trigger_info = obj.parse()
|
|
234
|
+
telescopes = (
|
|
235
|
+
trigger_info["triggered_telescopes"]
|
|
236
|
+
if len(trigger_info["triggered_telescopes"]) > 0
|
|
237
|
+
else []
|
|
238
|
+
)
|
|
156
239
|
if isinstance(obj, TrackingPosition):
|
|
157
240
|
tracking_position = obj.parse()
|
|
158
241
|
tracking_positions.append(
|
|
@@ -162,156 +245,53 @@ class SimtelIOEventDataWriter:
|
|
|
162
245
|
}
|
|
163
246
|
)
|
|
164
247
|
|
|
165
|
-
if tracking_positions:
|
|
166
|
-
self.
|
|
248
|
+
if len(telescopes) > 0 and tracking_positions:
|
|
249
|
+
self._fill_array_event(telescopes, tracking_positions, eventio_object.event_id, file_id)
|
|
167
250
|
|
|
168
|
-
def
|
|
169
|
-
"""
|
|
170
|
-
Process collected tracking positions and update triggered event list.
|
|
171
|
-
|
|
172
|
-
Use mean telescope tracking positions, averaged over all triggered telescopes.
|
|
173
|
-
"""
|
|
251
|
+
def _fill_array_event(self, telescopes, tracking_positions, event_id, file_id):
|
|
252
|
+
"""Add array event triggered events with tracking positions."""
|
|
174
253
|
altitudes = [pos["altitude"] for pos in tracking_positions]
|
|
175
254
|
azimuths = [pos["azimuth"] for pos in tracking_positions]
|
|
176
255
|
|
|
177
|
-
self.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
for name, desc in zip(table_names, descriptions):
|
|
220
|
-
path = f"/data/{name}"
|
|
221
|
-
table_dict[name] = (
|
|
222
|
-
output_file.create_table(
|
|
223
|
-
data_group, name, desc, name.replace("_", " ").title(), filters=DEFAULT_FILTERS
|
|
224
|
-
)
|
|
225
|
-
if mode == "w" or path not in output_file
|
|
226
|
-
else output_file.get_node(path)
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
return table_dict["reduced_data"], table_dict["triggered_data"], table_dict["file_names"]
|
|
230
|
-
|
|
231
|
-
def _write_event_data(self, reduced_table):
|
|
232
|
-
"""Fill event data tables."""
|
|
233
|
-
if len(self.event_data.simulated_energy) == 0:
|
|
234
|
-
return
|
|
235
|
-
row = reduced_table.row
|
|
236
|
-
for i, energy in enumerate(self.event_data.simulated_energy):
|
|
237
|
-
row["shower_id"] = (
|
|
238
|
-
self.event_data.shower_id[i] if i < len(self.event_data.shower_id) else 0
|
|
239
|
-
)
|
|
240
|
-
row["simulated_energy"] = energy
|
|
241
|
-
row["x_core"] = self.event_data.x_core[i] if i < len(self.event_data.x_core) else 0
|
|
242
|
-
row["y_core"] = self.event_data.y_core[i] if i < len(self.event_data.y_core) else 0
|
|
243
|
-
row["area_weight"] = (
|
|
244
|
-
self.event_data.area_weight[i] if i < len(self.event_data.area_weight) else 0
|
|
245
|
-
)
|
|
246
|
-
row["shower_azimuth"] = (
|
|
247
|
-
self.event_data.shower_azimuth[i] if i < len(self.event_data.shower_azimuth) else 0
|
|
248
|
-
)
|
|
249
|
-
row["shower_altitude"] = (
|
|
250
|
-
self.event_data.shower_altitude[i]
|
|
251
|
-
if i < len(self.event_data.shower_altitude)
|
|
252
|
-
else 0
|
|
253
|
-
)
|
|
254
|
-
row.append()
|
|
255
|
-
reduced_table.flush()
|
|
256
|
-
|
|
257
|
-
def _writer_triggered_data(self, triggered_table, vlarray):
|
|
258
|
-
"""Fill triggered event data tables."""
|
|
259
|
-
# Get or create VLArray for telescope lists
|
|
260
|
-
if len(self.triggered_data.triggered_id) == 0:
|
|
261
|
-
return
|
|
262
|
-
row = triggered_table.row
|
|
263
|
-
start_idx = vlarray.nrows
|
|
264
|
-
for i, triggered_id in enumerate(self.triggered_data.triggered_id):
|
|
265
|
-
row["triggered_id"] = triggered_id
|
|
266
|
-
row["array_altitudes"] = (
|
|
267
|
-
self.triggered_data.array_altitudes[i]
|
|
268
|
-
if i < len(self.triggered_data.array_altitudes)
|
|
269
|
-
else 0
|
|
270
|
-
)
|
|
271
|
-
row["array_azimuths"] = (
|
|
272
|
-
self.triggered_data.array_azimuths[i]
|
|
273
|
-
if i < len(self.triggered_data.array_azimuths)
|
|
274
|
-
else 0
|
|
275
|
-
)
|
|
276
|
-
row["telescope_list_index"] = start_idx + i # Index into the VLArray
|
|
277
|
-
row.append()
|
|
278
|
-
vlarray.append(
|
|
279
|
-
self.triggered_data.trigger_telescope_list_list[i]
|
|
280
|
-
if i < len(self.triggered_data.trigger_telescope_list_list)
|
|
281
|
-
else []
|
|
282
|
-
)
|
|
283
|
-
triggered_table.flush()
|
|
284
|
-
|
|
285
|
-
def _write_data(self, mode="a"):
|
|
286
|
-
"""Write data to HDF5 file."""
|
|
287
|
-
with tables.open_file(self.output_file, mode=mode) as f:
|
|
288
|
-
data_group = (
|
|
289
|
-
f.create_group("/", "data", "Data group")
|
|
290
|
-
if mode == "w" or "/data" not in f
|
|
291
|
-
else f.get_node("/data")
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
reduced_table, triggered_table, file_names_table = self._tables(f, data_group, mode)
|
|
295
|
-
self._write_event_data(reduced_table)
|
|
296
|
-
|
|
297
|
-
vlarray = (
|
|
298
|
-
f.create_vlarray(
|
|
299
|
-
data_group,
|
|
300
|
-
"trigger_telescope_list_list",
|
|
301
|
-
tables.Int16Atom(),
|
|
302
|
-
"List of triggered telescope IDs",
|
|
303
|
-
)
|
|
304
|
-
if mode == "w" or "/data/trigger_telescope_list_list" not in f
|
|
305
|
-
else f.get_node("/data/trigger_telescope_list_list")
|
|
306
|
-
)
|
|
307
|
-
self._writer_triggered_data(triggered_table, vlarray)
|
|
308
|
-
|
|
309
|
-
if self.file_names:
|
|
310
|
-
file_names_table.append([[name] for name in self.file_names])
|
|
311
|
-
file_names_table.flush()
|
|
312
|
-
|
|
313
|
-
def _reset_data(self):
|
|
314
|
-
"""Reset data structures for batch processing."""
|
|
315
|
-
self.event_data = ShowerEventData()
|
|
316
|
-
self.triggered_data = TriggeredEventData()
|
|
317
|
-
self.file_names = []
|
|
256
|
+
self.trigger_data.append(
|
|
257
|
+
{
|
|
258
|
+
"shower_id": self.shower_data[-1]["shower_id"],
|
|
259
|
+
"event_id": event_id,
|
|
260
|
+
"file_id": file_id,
|
|
261
|
+
"array_altitude": float(np.mean(altitudes)),
|
|
262
|
+
"array_azimuth": float(calculate_circular_mean(azimuths)),
|
|
263
|
+
"telescope_list": ",".join(map(str, telescopes)),
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def _get_preliminary_nsb_level(self, file):
|
|
268
|
+
"""
|
|
269
|
+
Return preliminary NSB level from file name.
|
|
270
|
+
|
|
271
|
+
Hardwired values are used for "dark", "half", and "full" NSB levels
|
|
272
|
+
(actual values are made up for this example). Will be replaced with
|
|
273
|
+
reading of sim_telarray metadata entry for NSB level (to be implemented,
|
|
274
|
+
see issue #1572).
|
|
275
|
+
|
|
276
|
+
Parameters
|
|
277
|
+
----------
|
|
278
|
+
file : str
|
|
279
|
+
File name to extract NSB level from.
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
float
|
|
284
|
+
NSB level extracted from file name.
|
|
285
|
+
"""
|
|
286
|
+
nsb_levels = {"dark": 1.0, "half": 2.0, "full": 5.0}
|
|
287
|
+
|
|
288
|
+
for key, value in nsb_levels.items():
|
|
289
|
+
try:
|
|
290
|
+
if key in file.lower():
|
|
291
|
+
self._logger.warning(f"NSB level set to hardwired value of {value}")
|
|
292
|
+
return value
|
|
293
|
+
except AttributeError as exc:
|
|
294
|
+
raise AttributeError("Invalid file name.") from exc
|
|
295
|
+
|
|
296
|
+
self._logger.warning("No NSB level found in file name, defaulting to 1.0")
|
|
297
|
+
return 1.0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""Read file info and run headers from sim_telarray files."""
|
|
3
|
+
|
|
4
|
+
from eventio import EventIOFile
|
|
5
|
+
from eventio.simtel import MCRunHeader, MCShower, RunHeader
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_corsika_run_number(file):
|
|
9
|
+
"""
|
|
10
|
+
Return the CORSIKA run number from a sim_telarray file.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
file: str
|
|
15
|
+
Path to the sim_telarray file.
|
|
16
|
+
|
|
17
|
+
Returns
|
|
18
|
+
-------
|
|
19
|
+
int, None
|
|
20
|
+
CORSIKA run number. Returns None if not found.
|
|
21
|
+
"""
|
|
22
|
+
run_header = get_corsika_run_header(file)
|
|
23
|
+
return run_header.get("run") if run_header else None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_corsika_run_header(file):
|
|
27
|
+
"""
|
|
28
|
+
Return the CORSIKA run header information from a sim_telarray file.
|
|
29
|
+
|
|
30
|
+
Reads both RunHeader and MCRunHeader object from file and
|
|
31
|
+
returns a merged dictionary. Adds primary id from the first event.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
file: str
|
|
36
|
+
Path to the sim_telarray file.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict, None
|
|
41
|
+
CORSIKA run header. Returns None if not found.
|
|
42
|
+
"""
|
|
43
|
+
run_header = None
|
|
44
|
+
mc_run_header = None
|
|
45
|
+
primary_id = None
|
|
46
|
+
|
|
47
|
+
with EventIOFile(file) as f:
|
|
48
|
+
for o in f:
|
|
49
|
+
if isinstance(o, RunHeader) and run_header is None:
|
|
50
|
+
run_header = o.parse()
|
|
51
|
+
elif isinstance(o, MCRunHeader) and mc_run_header is None:
|
|
52
|
+
mc_run_header = o.parse()
|
|
53
|
+
elif isinstance(o, MCShower): # get primary_id from first MCShower
|
|
54
|
+
primary_id = o.parse().get("primary_id")
|
|
55
|
+
if run_header and mc_run_header and primary_id is not None:
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
run_header = run_header or {}
|
|
59
|
+
mc_run_header = mc_run_header or {}
|
|
60
|
+
if primary_id is not None:
|
|
61
|
+
mc_run_header["primary_id"] = primary_id
|
|
62
|
+
return run_header | mc_run_header or None
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Reads the content of either a single histogram or
|
|
1
|
+
"""Reads the content of either a single histogram or sim_telarray output file."""
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import logging
|
|
@@ -11,7 +11,8 @@ from ctao_cr_spectra.definitions import IRFDOC_PROTON_SPECTRUM
|
|
|
11
11
|
from ctao_cr_spectra.spectral import cone_solid_angle
|
|
12
12
|
from eventio import EventIOFile, Histograms
|
|
13
13
|
from eventio.search_utils import yield_toplevel_of_type
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
from simtools.simtel.simtel_io_file_info import get_corsika_run_header
|
|
15
16
|
|
|
16
17
|
__all__ = [
|
|
17
18
|
"HistogramIdNotFoundError",
|
|
@@ -32,13 +33,13 @@ class SimtelIOHistogram:
|
|
|
32
33
|
"""
|
|
33
34
|
Reads and generates histograms from sim_telarray output.
|
|
34
35
|
|
|
35
|
-
Read the content of either a single histogram (.hdata, or .hdata.zst) or a single
|
|
36
|
+
Read the content of either a single histogram (.hdata, or .hdata.zst) or a single sim_telarray
|
|
36
37
|
output file (.simtel or .simtel.zst).
|
|
37
38
|
|
|
38
39
|
Parameters
|
|
39
40
|
----------
|
|
40
41
|
histogram_file: str
|
|
41
|
-
The histogram (.hdata.zst) or
|
|
42
|
+
The histogram (.hdata.zst) or sim_telarray (.simtel.zst) file.
|
|
42
43
|
area_from_distribution: bool
|
|
43
44
|
If true, the area thrown (the area in which the simulated events are distributed)
|
|
44
45
|
in the trigger rate calculation is estimated based on the event distribution.
|
|
@@ -135,14 +136,9 @@ class SimtelIOHistogram:
|
|
|
135
136
|
Returns
|
|
136
137
|
-------
|
|
137
138
|
dict:
|
|
138
|
-
dictionary with information about the simulation
|
|
139
|
+
dictionary with information about the simulation
|
|
139
140
|
"""
|
|
140
|
-
if self._config
|
|
141
|
-
with EventIOFile(self.histogram_file) as f:
|
|
142
|
-
self._config = next(
|
|
143
|
-
(obj.parse() for obj in f if isinstance(obj, MCRunHeader)), None
|
|
144
|
-
)
|
|
145
|
-
return self._config
|
|
141
|
+
return self._config if self._config else get_corsika_run_header(self.histogram_file)
|
|
146
142
|
|
|
147
143
|
@property
|
|
148
144
|
def total_number_of_events(self):
|
|
@@ -348,7 +344,7 @@ class SimtelIOHistogram:
|
|
|
348
344
|
for the triggered events.
|
|
349
345
|
"""
|
|
350
346
|
if self.trigger_rate is None:
|
|
351
|
-
# Get the simulated and triggered 2D histograms from the
|
|
347
|
+
# Get the simulated and triggered 2D histograms from the sim_telarray output file
|
|
352
348
|
if events_histogram is None and triggered_events_histogram is None:
|
|
353
349
|
events_histogram, triggered_events_histogram = self.fill_event_histogram_dicts()
|
|
354
350
|
# Calculate triggered/simulated event 1D histogram (energy dependent)
|
|
@@ -408,7 +404,7 @@ class SimtelIOHistogram:
|
|
|
408
404
|
"""
|
|
409
405
|
Produce the meta data to include in the tabulated form of the trigger rate per energy bin.
|
|
410
406
|
|
|
411
|
-
It shows some information from the input file (
|
|
407
|
+
It shows some information from the input file (sim_telarray file) and the final estimate
|
|
412
408
|
system trigger rate.
|
|
413
409
|
|
|
414
410
|
Returns
|
|
@@ -417,7 +413,7 @@ class SimtelIOHistogram:
|
|
|
417
413
|
dictionary with the metadata.
|
|
418
414
|
"""
|
|
419
415
|
return {
|
|
420
|
-
"
|
|
416
|
+
"sim_telarray_file": self.histogram_file,
|
|
421
417
|
"simulation_input": self.print_info(mode="silent"),
|
|
422
418
|
"system_trigger_rate (Hz)": self.trigger_rate.value,
|
|
423
419
|
}
|