gammasimtools 0.13.0__py3-none-any.whl → 0.14.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.13.0.dist-info → gammasimtools-0.14.0.dist-info}/METADATA +3 -3
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/RECORD +224 -217
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/entry_points.txt +3 -1
- simtools/_version.py +2 -2
- simtools/applications/db_add_file_to_db.py +15 -0
- simtools/applications/db_add_value_from_json_to_db.py +18 -1
- simtools/applications/derive_ctao_array_layouts.py +120 -0
- simtools/applications/derive_photon_electron_spectrum.py +29 -1
- simtools/applications/docs_produce_array_element_report.py +41 -16
- simtools/applications/docs_produce_model_parameter_reports.py +28 -8
- simtools/applications/{production_extract_mc_event_data.py → generate_simtel_event_data.py} +12 -20
- simtools/applications/print_version.py +81 -0
- simtools/applications/production_derive_corsika_limits.py +172 -39
- simtools/applications/production_scale_events.py +59 -36
- simtools/applications/run_application.py +41 -11
- simtools/applications/simulate_light_emission.py +115 -247
- simtools/applications/simulate_prod_htcondor_generator.py +2 -2
- simtools/camera/single_photon_electron_spectrum.py +163 -15
- simtools/data_model/model_data_writer.py +7 -6
- simtools/db/db_handler.py +14 -8
- simtools/dependencies.py +38 -3
- simtools/layout/array_layout.py +1 -0
- simtools/layout/ctao_array_layouts.py +172 -0
- simtools/model/array_model.py +3 -4
- simtools/model/model_parameter.py +30 -87
- simtools/production_configuration/derive_corsika_limits.py +222 -154
- simtools/production_configuration/event_scaler.py +2 -2
- simtools/reporting/docs_auto_report_generator.py +217 -0
- simtools/reporting/docs_read_parameters.py +192 -110
- simtools/schemas/application_workflow.metaschema.yml +3 -0
- simtools/schemas/model_parameter.metaschema.yml +13 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +6 -0
- simtools/schemas/model_parameters/adjust_gain.schema.yml +1 -1
- simtools/schemas/model_parameters/altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +3 -3
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +3 -3
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +3 -3
- simtools/schemas/model_parameters/array_window.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_depth.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_pixels.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_transmission.schema.yml +1 -1
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_observation_level.schema.yml +1 -1
- simtools/schemas/model_parameters/dark_events.schema.yml +1 -1
- simtools/schemas/model_parameters/disc_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/disc_start.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +1 -1
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +5 -5
- simtools/schemas/model_parameters/epsg_code.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_max_sum.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_noise.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/focus_offset.schema.yml +4 -4
- simtools/schemas/model_parameters/gain_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_horizontal.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_rotation.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_vertical.schema.yml +1 -1
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_external_trigger.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_var_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_wavelength.schema.yml +1 -1
- simtools/schemas/model_parameters/led_events.schema.yml +1 -1
- simtools/schemas/model_parameters/led_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/led_pulse_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +1 -1
- simtools/schemas/model_parameters/led_var_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +4 -4
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +4 -4
- simtools/schemas/model_parameters/mirror_class.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +3 -3
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +3 -3
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +45 -0
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +5 -5
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_reference_value.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +2 -2
- simtools/schemas/model_parameters/num_gains.schema.yml +1 -1
- simtools/schemas/model_parameters/pedestal_events.schema.yml +1 -1
- simtools/schemas/model_parameters/photon_delay.schema.yml +1 -1
- simtools/schemas/model_parameters/photons_per_run.schema.yml +1 -1
- simtools/schemas/model_parameters/pixel_cells.schema.yml +1 -1
- simtools/schemas/model_parameters/pixels_parallel.schema.yml +1 -1
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +4 -4
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +7 -3
- simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/qe_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +38 -0
- simtools/schemas/model_parameters/reference_point_altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_latitude.schema.yml +4 -1
- simtools/schemas/model_parameters/reference_point_longitude.schema.yml +4 -1
- simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +5 -5
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/stars.schema.yml +36 -0
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +6 -6
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +1 -1
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +1 -1
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +1 -1
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +4 -4
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +1 -1
- simtools/simtel/simtel_config_writer.py +70 -38
- simtools/simtel/simtel_io_event_reader.py +278 -0
- simtools/simtel/simtel_io_event_writer.py +317 -0
- simtools/simtel/simulator_light_emission.py +181 -67
- simtools/simulator.py +2 -2
- simtools/testing/configuration.py +17 -0
- simtools/utils/general.py +33 -7
- simtools/utils/geometry.py +19 -0
- simtools/utils/names.py +7 -1
- simtools/visualization/visualize.py +2 -2
- simtools/production_configuration/extract_mc_event_data.py +0 -253
- simtools/simtel/simtel_io_events.py +0 -265
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info/licenses}/LICENSE +0 -0
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/top_level.txt +0 -0
- /simtools/schemas/model_parameters/{nsb_skymap.schema.yml → nsb_sky_map.schema.yml} +0 -0
|
@@ -86,6 +86,18 @@ class ModelParameter:
|
|
|
86
86
|
self._is_config_file_up_to_date = False
|
|
87
87
|
self._is_exported_model_files_up_to_date = False
|
|
88
88
|
|
|
89
|
+
@property
|
|
90
|
+
def parameters(self):
|
|
91
|
+
"""
|
|
92
|
+
Model parameters dictionary.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
dict
|
|
97
|
+
Dictionary containing all model parameters
|
|
98
|
+
"""
|
|
99
|
+
return self._parameters
|
|
100
|
+
|
|
89
101
|
def _get_parameter_dict(self, par_name):
|
|
90
102
|
"""
|
|
91
103
|
Get model parameter dictionary as stored in the DB.
|
|
@@ -110,11 +122,11 @@ class ModelParameter:
|
|
|
110
122
|
If par_name does not match any parameter in this model.
|
|
111
123
|
"""
|
|
112
124
|
try:
|
|
113
|
-
return self.
|
|
125
|
+
return self.parameters[par_name]
|
|
114
126
|
except (KeyError, ValueError) as e:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
127
|
+
raise InvalidModelParameterError(
|
|
128
|
+
f"Parameter {par_name} was not found in the model {self.name}, {self.site}."
|
|
129
|
+
) from e
|
|
118
130
|
|
|
119
131
|
def get_parameter_value(self, par_name, parameter_dict=None):
|
|
120
132
|
"""
|
|
@@ -258,7 +270,7 @@ class ModelParameter:
|
|
|
258
270
|
|
|
259
271
|
def print_parameters(self):
|
|
260
272
|
"""Print parameters and their values for debugging purposes."""
|
|
261
|
-
for par in self.
|
|
273
|
+
for par in self.parameters:
|
|
262
274
|
print(f"{par} = {self.get_parameter_value(par)}")
|
|
263
275
|
|
|
264
276
|
def _set_config_file_directory_and_name(self):
|
|
@@ -298,21 +310,6 @@ class ModelParameter:
|
|
|
298
310
|
"""
|
|
299
311
|
return self._simulation_config_parameters.get(simulation_software)
|
|
300
312
|
|
|
301
|
-
def has_parameter(self, par_name):
|
|
302
|
-
"""Check if a parameter exists in the model.
|
|
303
|
-
|
|
304
|
-
Parameters
|
|
305
|
-
----------
|
|
306
|
-
par_name : str
|
|
307
|
-
Name of the parameter.
|
|
308
|
-
|
|
309
|
-
Returns
|
|
310
|
-
-------
|
|
311
|
-
bool
|
|
312
|
-
True if parameter exists in the model.
|
|
313
|
-
"""
|
|
314
|
-
return par_name in self._parameters
|
|
315
|
-
|
|
316
313
|
def _load_simulation_software_parameter(self):
|
|
317
314
|
"""Read simulation software parameters from DB."""
|
|
318
315
|
for simulation_software in self._simulation_config_parameters:
|
|
@@ -337,12 +334,12 @@ class ModelParameter:
|
|
|
337
334
|
if self.db is None:
|
|
338
335
|
return
|
|
339
336
|
|
|
340
|
-
if self.name
|
|
337
|
+
if self.name:
|
|
341
338
|
self._parameters = self.db.get_model_parameters(
|
|
342
339
|
self.site, self.name, self.collection, self.model_version
|
|
343
340
|
)
|
|
344
341
|
|
|
345
|
-
if self.site
|
|
342
|
+
if self.site:
|
|
346
343
|
self._parameters.update(
|
|
347
344
|
self.db.get_model_parameters(
|
|
348
345
|
self.site,
|
|
@@ -353,56 +350,11 @@ class ModelParameter:
|
|
|
353
350
|
)
|
|
354
351
|
self._load_simulation_software_parameter()
|
|
355
352
|
|
|
356
|
-
def set_extra_label(self, extra_label):
|
|
357
|
-
"""
|
|
358
|
-
Set an extra label for the name of the config file.
|
|
359
|
-
|
|
360
|
-
Notes
|
|
361
|
-
-----
|
|
362
|
-
The config file directory name is not affected by the extra label. Only the file name is \
|
|
363
|
-
changed. This is important for the ArrayModel class to export multiple config files in the\
|
|
364
|
-
same directory.
|
|
365
|
-
|
|
366
|
-
Parameters
|
|
367
|
-
----------
|
|
368
|
-
extra_label: str
|
|
369
|
-
Extra label to be appended to the original label.
|
|
370
|
-
"""
|
|
371
|
-
self._extra_label = extra_label
|
|
372
|
-
self._set_config_file_directory_and_name()
|
|
373
|
-
|
|
374
353
|
@property
|
|
375
354
|
def extra_label(self):
|
|
376
355
|
"""Return the extra label if defined, if not return ''."""
|
|
377
356
|
return self._extra_label if self._extra_label is not None else ""
|
|
378
357
|
|
|
379
|
-
def get_simtel_parameters(self, parameters=None):
|
|
380
|
-
"""
|
|
381
|
-
Get simtel parameters as name and value pairs.
|
|
382
|
-
|
|
383
|
-
Parameters
|
|
384
|
-
----------
|
|
385
|
-
parameters: dict
|
|
386
|
-
Parameters (simtools) to be renamed (if necessary)
|
|
387
|
-
|
|
388
|
-
Returns
|
|
389
|
-
-------
|
|
390
|
-
dict
|
|
391
|
-
simtel parameters as dict (sorted by parameter names)
|
|
392
|
-
|
|
393
|
-
"""
|
|
394
|
-
if parameters is None:
|
|
395
|
-
parameters = self._parameters
|
|
396
|
-
|
|
397
|
-
_simtel_parameter_value = {}
|
|
398
|
-
for key in parameters:
|
|
399
|
-
_par_name = names.get_simulation_software_name_from_parameter_name(
|
|
400
|
-
key, simulation_software="sim_telarray"
|
|
401
|
-
)
|
|
402
|
-
if _par_name is not None:
|
|
403
|
-
_simtel_parameter_value[_par_name] = parameters[key].get("value")
|
|
404
|
-
return dict(sorted(_simtel_parameter_value.items()))
|
|
405
|
-
|
|
406
358
|
def change_parameter(self, par_name, value):
|
|
407
359
|
"""
|
|
408
360
|
Change the value of an existing parameter.
|
|
@@ -421,29 +373,24 @@ class ModelParameter:
|
|
|
421
373
|
InvalidModelParameterError
|
|
422
374
|
If the parameter to be changed does not exist in this model.
|
|
423
375
|
"""
|
|
424
|
-
if par_name not in self.
|
|
425
|
-
|
|
426
|
-
self._logger.error(msg)
|
|
427
|
-
raise InvalidModelParameterError(msg)
|
|
376
|
+
if par_name not in self.parameters:
|
|
377
|
+
raise InvalidModelParameterError(f"Parameter {par_name} not in the model")
|
|
428
378
|
|
|
429
|
-
if isinstance(value, str)
|
|
430
|
-
value = gen.convert_string_to_list(value)
|
|
379
|
+
value = gen.convert_string_to_list(value) if isinstance(value, str) else value
|
|
431
380
|
|
|
381
|
+
par_type = self.get_parameter_type(par_name)
|
|
432
382
|
if not gen.validate_data_type(
|
|
433
|
-
reference_dtype=
|
|
383
|
+
reference_dtype=par_type,
|
|
434
384
|
value=value,
|
|
435
385
|
dtype=None,
|
|
436
386
|
allow_subtypes=True,
|
|
437
387
|
):
|
|
438
|
-
raise ValueError(
|
|
439
|
-
f"Could not cast {value} of type {type(value)} "
|
|
440
|
-
f"to {self.get_parameter_type(par_name)}."
|
|
441
|
-
)
|
|
388
|
+
raise ValueError(f"Could not cast {value} of type {type(value)} to {par_type}.")
|
|
442
389
|
|
|
443
390
|
self._logger.debug(
|
|
444
391
|
f"Changing parameter {par_name} from {self.get_parameter_value(par_name)} to {value}"
|
|
445
392
|
)
|
|
446
|
-
self.
|
|
393
|
+
self.parameters[par_name]["value"] = value
|
|
447
394
|
|
|
448
395
|
# In case parameter is a file, the model files will be outdated
|
|
449
396
|
if self.get_parameter_file_flag(par_name):
|
|
@@ -483,7 +430,7 @@ class ModelParameter:
|
|
|
483
430
|
|
|
484
431
|
"""
|
|
485
432
|
for par, value in kwargs.items():
|
|
486
|
-
if par in self.
|
|
433
|
+
if par in self.parameters:
|
|
487
434
|
self.change_parameter(par, value)
|
|
488
435
|
|
|
489
436
|
self._is_config_file_up_to_date = False
|
|
@@ -507,7 +454,7 @@ class ModelParameter:
|
|
|
507
454
|
def export_model_files(self):
|
|
508
455
|
"""Export the model files into the config file directory."""
|
|
509
456
|
# Removing parameter files added manually (which are not in DB)
|
|
510
|
-
pars_from_db = copy(self.
|
|
457
|
+
pars_from_db = copy(self.parameters)
|
|
511
458
|
if self._added_parameter_files is not None:
|
|
512
459
|
for par in self._added_parameter_files:
|
|
513
460
|
pars_from_db.pop(par)
|
|
@@ -517,18 +464,14 @@ class ModelParameter:
|
|
|
517
464
|
|
|
518
465
|
def export_config_file(self):
|
|
519
466
|
"""Export the config file used by sim_telarray."""
|
|
520
|
-
# Exporting model file
|
|
521
467
|
if not self._is_exported_model_files_up_to_date:
|
|
522
468
|
self.export_model_files()
|
|
523
469
|
|
|
524
|
-
# Using SimtelConfigWriter to write the config file.
|
|
525
470
|
self._load_simtel_config_writer()
|
|
526
471
|
self.simtel_config_writer.write_telescope_config_file(
|
|
527
472
|
config_file_path=self.config_file_path,
|
|
528
|
-
parameters=self.
|
|
529
|
-
config_parameters=self.
|
|
530
|
-
parameters=self._simulation_config_parameters["simtel"]
|
|
531
|
-
),
|
|
473
|
+
parameters=self.parameters,
|
|
474
|
+
config_parameters=self._simulation_config_parameters["simtel"],
|
|
532
475
|
)
|
|
533
476
|
|
|
534
477
|
@property
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
"""Calculate
|
|
1
|
+
"""Calculate CORSIKA thresholds for energy, radial distance, and viewcone."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
2
4
|
|
|
3
5
|
import astropy.units as u
|
|
4
6
|
import matplotlib.pyplot as plt
|
|
5
7
|
import numpy as np
|
|
6
|
-
|
|
7
|
-
from
|
|
8
|
-
from ctapipe.coordinates import GroundFrame, TiltedGroundFrame
|
|
8
|
+
|
|
9
|
+
from simtools.simtel.simtel_io_event_reader import SimtelIOEventDataReader
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class LimitCalculator:
|
|
12
13
|
"""
|
|
13
|
-
Compute thresholds
|
|
14
|
+
Compute thresholds for CORSIKA configuration for energy, radial distance, and viewcone.
|
|
14
15
|
|
|
15
16
|
Event data is read from the reduced MC event data file.
|
|
16
17
|
|
|
@@ -23,52 +24,14 @@ class LimitCalculator:
|
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
def __init__(self, event_data_file, telescope_list=None):
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Parameters
|
|
30
|
-
----------
|
|
31
|
-
event_data_file : str
|
|
32
|
-
Path to the reduced MC event data file.
|
|
33
|
-
telescope_list : list, optional
|
|
34
|
-
List of telescope IDs to filter the events (default is None).
|
|
35
|
-
"""
|
|
27
|
+
"""Initialize the LimitCalculator with the given event data file."""
|
|
28
|
+
self._logger = logging.getLogger(__name__)
|
|
36
29
|
self.event_data_file = event_data_file
|
|
37
30
|
self.telescope_list = telescope_list
|
|
38
|
-
|
|
39
|
-
self.
|
|
40
|
-
self.
|
|
41
|
-
self.
|
|
42
|
-
self.list_of_files = None
|
|
43
|
-
self.shower_sim_azimuth = None
|
|
44
|
-
self.shower_sim_altitude = None
|
|
45
|
-
self.array_azimuth = None
|
|
46
|
-
self.array_altitude = None
|
|
47
|
-
self.trigger_telescope_list_list = None
|
|
48
|
-
self.units = {}
|
|
49
|
-
self._read_event_data()
|
|
50
|
-
|
|
51
|
-
def _read_event_data(self):
|
|
52
|
-
"""Read the event data from the reduced MC event data file."""
|
|
53
|
-
with tables.open_file(self.event_data_file, mode="r") as f:
|
|
54
|
-
reduced_data = f.root.data.reduced_data
|
|
55
|
-
triggered_data = f.root.data.triggered_data
|
|
56
|
-
file_names = f.root.data.file_names
|
|
57
|
-
trigger_telescope_list_list = f.root.data.trigger_telescope_list_list
|
|
58
|
-
|
|
59
|
-
self.event_x_core = reduced_data.col("core_x")
|
|
60
|
-
self.event_y_core = reduced_data.col("core_y")
|
|
61
|
-
self.simulated = reduced_data.col("simulated")
|
|
62
|
-
self.shower_id_triggered = triggered_data.col("shower_id_triggered")
|
|
63
|
-
self.list_of_files = file_names.col("file_names")
|
|
64
|
-
self.shower_sim_azimuth = reduced_data.col("shower_sim_azimuth")
|
|
65
|
-
self.shower_sim_altitude = reduced_data.col("shower_sim_altitude")
|
|
66
|
-
self.array_altitude = reduced_data.col("array_altitudes")
|
|
67
|
-
self.array_azimuth = reduced_data.col("array_azimuths")
|
|
68
|
-
|
|
69
|
-
self.trigger_telescope_list_list = [
|
|
70
|
-
[np.int16(tel) for tel in event] for event in trigger_telescope_list_list
|
|
71
|
-
]
|
|
31
|
+
|
|
32
|
+
self.reader = SimtelIOEventDataReader(event_data_file, telescope_list=telescope_list)
|
|
33
|
+
self.event_data = self.reader.triggered_shower_data
|
|
34
|
+
self.triggered_data = self.reader.triggered_data
|
|
72
35
|
|
|
73
36
|
def _compute_limits(self, hist, bin_edges, loss_fraction, limit_type="lower"):
|
|
74
37
|
"""
|
|
@@ -94,40 +57,18 @@ class LimitCalculator:
|
|
|
94
57
|
total_events = np.sum(hist)
|
|
95
58
|
threshold = (1 - loss_fraction) * total_events
|
|
96
59
|
bin_index = np.searchsorted(cumulative_sum, threshold)
|
|
97
|
-
return bin_edges[bin_index] if limit_type == "upper" else bin_edges[-bin_index]
|
|
98
60
|
|
|
99
|
-
|
|
100
|
-
"""
|
|
101
|
-
Prepare the data required for computing limits.
|
|
61
|
+
return bin_edges[bin_index] if limit_type == "upper" else bin_edges[-bin_index]
|
|
102
62
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
mask = np.array(
|
|
111
|
-
[
|
|
112
|
-
all(tel in event for tel in self.telescope_list)
|
|
113
|
-
for event in self.trigger_telescope_list_list
|
|
114
|
-
]
|
|
115
|
-
)
|
|
116
|
-
shower_id_triggered_masked = self.shower_id_triggered[mask]
|
|
117
|
-
|
|
118
|
-
triggered_energies = self.simulated[shower_id_triggered_masked]
|
|
119
|
-
energy_bins = np.logspace(
|
|
120
|
-
np.log10(triggered_energies.min()), np.log10(triggered_energies.max()), 1000
|
|
121
|
-
)
|
|
122
|
-
event_x_core_shower, event_y_core_shower = self._transform_to_shower_coordinates()
|
|
123
|
-
core_distances_all = np.sqrt(event_x_core_shower**2 + event_y_core_shower**2)
|
|
124
|
-
core_distances_triggered = core_distances_all[shower_id_triggered_masked]
|
|
125
|
-
core_bins = np.linspace(
|
|
126
|
-
core_distances_triggered.min(), core_distances_triggered.max(), 1000
|
|
63
|
+
@property
|
|
64
|
+
def energy_bins(self):
|
|
65
|
+
"""Return bins for the energy histogram."""
|
|
66
|
+
return np.logspace(
|
|
67
|
+
np.log10(self.event_data.simulated_energy.min()),
|
|
68
|
+
np.log10(self.event_data.simulated_energy.max()),
|
|
69
|
+
1000,
|
|
127
70
|
)
|
|
128
71
|
|
|
129
|
-
return core_distances_triggered, triggered_energies, core_bins, energy_bins
|
|
130
|
-
|
|
131
72
|
def compute_lower_energy_limit(self, loss_fraction):
|
|
132
73
|
"""
|
|
133
74
|
Compute the lower energy limit in TeV based on the event loss fraction.
|
|
@@ -142,13 +83,19 @@ class LimitCalculator:
|
|
|
142
83
|
astropy.units.Quantity
|
|
143
84
|
Lower energy limit.
|
|
144
85
|
"""
|
|
145
|
-
|
|
86
|
+
hist, _ = np.histogram(self.event_data.simulated_energy, bins=self.energy_bins)
|
|
87
|
+
return (
|
|
88
|
+
self._compute_limits(hist, self.energy_bins, loss_fraction, limit_type="lower") * u.TeV
|
|
89
|
+
)
|
|
146
90
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
91
|
+
@property
|
|
92
|
+
def core_distance_bins(self):
|
|
93
|
+
"""Return bins for the core distance histogram."""
|
|
94
|
+
return np.linspace(
|
|
95
|
+
self.event_data.core_distance_shower.min(),
|
|
96
|
+
self.event_data.core_distance_shower.max(),
|
|
97
|
+
1000,
|
|
150
98
|
)
|
|
151
|
-
return lower_bin_edge_value * u.TeV
|
|
152
99
|
|
|
153
100
|
def compute_upper_radial_distance(self, loss_fraction):
|
|
154
101
|
"""
|
|
@@ -164,18 +111,29 @@ class LimitCalculator:
|
|
|
164
111
|
astropy.units.Quantity
|
|
165
112
|
Upper radial distance in m.
|
|
166
113
|
"""
|
|
167
|
-
|
|
114
|
+
hist, _ = np.histogram(self.event_data.core_distance_shower, bins=self.core_distance_bins)
|
|
115
|
+
return (
|
|
116
|
+
self._compute_limits(hist, self.core_distance_bins, loss_fraction, limit_type="upper")
|
|
117
|
+
* u.m
|
|
118
|
+
)
|
|
168
119
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
120
|
+
@property
|
|
121
|
+
def view_cone_bins(self):
|
|
122
|
+
"""Return bins for the viewcone histogram."""
|
|
123
|
+
return np.linspace(
|
|
124
|
+
self.triggered_data.angular_distance.min(),
|
|
125
|
+
self.triggered_data.angular_distance.max(),
|
|
126
|
+
1000,
|
|
172
127
|
)
|
|
173
|
-
return upper_bin_edge_value * u.m
|
|
174
128
|
|
|
175
129
|
def compute_viewcone(self, loss_fraction):
|
|
176
130
|
"""
|
|
177
131
|
Compute the viewcone based on the event loss fraction.
|
|
178
132
|
|
|
133
|
+
The shower IDs of triggered events are used to create a mask for the
|
|
134
|
+
azimuth and altitude of the triggered events. A mapping is created
|
|
135
|
+
between the triggered events and the simulated events using the shower IDs.
|
|
136
|
+
|
|
179
137
|
Parameters
|
|
180
138
|
----------
|
|
181
139
|
loss_fraction : float
|
|
@@ -186,75 +144,185 @@ class LimitCalculator:
|
|
|
186
144
|
astropy.units.Quantity
|
|
187
145
|
Viewcone radius in degrees.
|
|
188
146
|
"""
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
x_1 = np.cos(azimuth_diff) * np.cos(sim_altitude_rad)
|
|
194
|
-
y_1 = np.sin(azimuth_diff) * np.cos(sim_altitude_rad)
|
|
195
|
-
z_1 = np.sin(sim_altitude_rad)
|
|
196
|
-
x_2 = x_1 * np.sin(array_altitude_rad) - z_1 * np.cos(array_altitude_rad)
|
|
197
|
-
y_2 = y_1
|
|
198
|
-
z_2 = x_1 * np.cos(array_altitude_rad) + z_1 * np.sin(array_altitude_rad)
|
|
199
|
-
off_angles = np.arctan2(np.sqrt(x_2**2 + y_2**2), z_2) * (180.0 / np.pi)
|
|
200
|
-
angle_bins = np.linspace(off_angles.min(), off_angles.max(), 400)
|
|
201
|
-
hist, _ = np.histogram(off_angles, bins=angle_bins)
|
|
202
|
-
|
|
203
|
-
upper_bin_edge_value = self._compute_limits(
|
|
204
|
-
hist, angle_bins, loss_fraction, limit_type="upper"
|
|
147
|
+
hist, _ = np.histogram(self.triggered_data.angular_distance, bins=self.view_cone_bins)
|
|
148
|
+
return (
|
|
149
|
+
self._compute_limits(hist, self.view_cone_bins, loss_fraction, limit_type="upper")
|
|
150
|
+
* u.deg
|
|
205
151
|
)
|
|
206
|
-
return upper_bin_edge_value * u.deg
|
|
207
152
|
|
|
208
|
-
def
|
|
153
|
+
def plot_data(self, lower_energy_limit, upper_radial_distance, viewcone, output_path=None):
|
|
209
154
|
"""
|
|
210
|
-
|
|
155
|
+
Plot the core distances and energies of triggered events.
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
lower_energy_limit: astropy.units.Quantity
|
|
160
|
+
Lower energy limit to display on plots.
|
|
161
|
+
upper_radial_distance: astropy.units.Quantity
|
|
162
|
+
Upper radial distance limit to display on plots.
|
|
163
|
+
viewcone: astropy.units.Quantity
|
|
164
|
+
Viewcone radius to display on plots.
|
|
165
|
+
output_path: Path or str, optional
|
|
166
|
+
Directory to save plots. If None, plots will be displayed.
|
|
167
|
+
"""
|
|
168
|
+
event_counts = "Event Count"
|
|
169
|
+
plots = {
|
|
170
|
+
"core_vs_energy": {
|
|
171
|
+
"x_data": self.event_data.core_distance_shower,
|
|
172
|
+
"y_data": self.event_data.simulated_energy,
|
|
173
|
+
"bins": [self.core_distance_bins, self.energy_bins],
|
|
174
|
+
"plot_type": "histogram2d",
|
|
175
|
+
"plot_params": {"norm": "log", "cmap": "viridis"},
|
|
176
|
+
"labels": {
|
|
177
|
+
"x": "Core Distance [m]",
|
|
178
|
+
"y": "Energy [TeV]",
|
|
179
|
+
"title": "Triggered events: core distance vs energy",
|
|
180
|
+
},
|
|
181
|
+
"scales": {"y": "log"},
|
|
182
|
+
"colorbar_label": event_counts,
|
|
183
|
+
"filename": "core_vs_energy_distribution.png",
|
|
184
|
+
},
|
|
185
|
+
"energy_distribution": {
|
|
186
|
+
"x_data": self.event_data.simulated_energy,
|
|
187
|
+
"bins": np.logspace(-3, 0.0, 100),
|
|
188
|
+
"plot_type": "histogram",
|
|
189
|
+
"plot_params": {"histtype": "step", "color": "k", "lw": 2},
|
|
190
|
+
"labels": {
|
|
191
|
+
"x": "Energy [TeV]",
|
|
192
|
+
"y": event_counts,
|
|
193
|
+
"title": "Triggered events: energy distribution",
|
|
194
|
+
},
|
|
195
|
+
"scales": {"x": "log", "y": "log"},
|
|
196
|
+
"lines": {"x": lower_energy_limit.value},
|
|
197
|
+
"filename": "energy_distribution.png",
|
|
198
|
+
},
|
|
199
|
+
"core_distance": {
|
|
200
|
+
"x_data": self.event_data.core_distance_shower,
|
|
201
|
+
"bins": self.core_distance_bins,
|
|
202
|
+
"plot_type": "histogram",
|
|
203
|
+
"plot_params": {"histtype": "step", "color": "k", "lw": 2},
|
|
204
|
+
"labels": {
|
|
205
|
+
"x": "Core Distance [m]",
|
|
206
|
+
"y": event_counts,
|
|
207
|
+
"title": "Triggered events: core distance distribution",
|
|
208
|
+
},
|
|
209
|
+
"lines": {"x": upper_radial_distance.value},
|
|
210
|
+
"filename": "core_distance_distribution.png",
|
|
211
|
+
},
|
|
212
|
+
"core_xy": {
|
|
213
|
+
"x_data": self.event_data.x_core_shower,
|
|
214
|
+
"y_data": self.event_data.y_core_shower,
|
|
215
|
+
"bins": 100,
|
|
216
|
+
"plot_type": "histogram2d",
|
|
217
|
+
"plot_params": {"norm": "log", "cmap": "viridis"},
|
|
218
|
+
"labels": {
|
|
219
|
+
"x": "Core X [m]",
|
|
220
|
+
"y": "Core Y [m]",
|
|
221
|
+
"title": "Triggered events: core x vs core y",
|
|
222
|
+
},
|
|
223
|
+
"colorbar_label": event_counts,
|
|
224
|
+
"lines": {"x": upper_radial_distance.value, "y": upper_radial_distance.value},
|
|
225
|
+
"filename": "core_xy_distribution.png",
|
|
226
|
+
},
|
|
227
|
+
"view-cone": {
|
|
228
|
+
"x_data": self.triggered_data.angular_distance,
|
|
229
|
+
"bins": self.view_cone_bins,
|
|
230
|
+
"plot_type": "histogram",
|
|
231
|
+
"plot_params": {"histtype": "step", "color": "k", "lw": 2},
|
|
232
|
+
"labels": {
|
|
233
|
+
"x": "Distance to pointing direction [deg]",
|
|
234
|
+
"y": event_counts,
|
|
235
|
+
"title": "Triggered events: viewcone distribution",
|
|
236
|
+
},
|
|
237
|
+
"lines": {"x": viewcone.value},
|
|
238
|
+
"filename": "viewcone_distribution.png",
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for _, plot_args in plots.items():
|
|
243
|
+
filename = plot_args.pop("filename")
|
|
244
|
+
output_file = output_path / filename if output_path else None
|
|
245
|
+
self._create_plot(**plot_args, output_file=output_file)
|
|
246
|
+
|
|
247
|
+
def _create_plot(
|
|
248
|
+
self,
|
|
249
|
+
x_data,
|
|
250
|
+
y_data=None,
|
|
251
|
+
bins=None,
|
|
252
|
+
plot_type="histogram",
|
|
253
|
+
plot_params=None,
|
|
254
|
+
labels=None,
|
|
255
|
+
scales=None,
|
|
256
|
+
colorbar_label=None,
|
|
257
|
+
output_file=None,
|
|
258
|
+
lines=None,
|
|
259
|
+
):
|
|
260
|
+
"""
|
|
261
|
+
Create and save a plot with the given parameters.
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
x_data : array-like
|
|
266
|
+
Data for the x-axis or primary data for histograms.
|
|
267
|
+
y_data : array-like, optional
|
|
268
|
+
Data for the y-axis in scatter or 2D histograms.
|
|
269
|
+
bins : int, array-like, or list, optional
|
|
270
|
+
Bins specification for histograms.
|
|
271
|
+
plot_type : str, optional
|
|
272
|
+
Type of plot: 'histogram', 'histogram2d', or 'scatter'.
|
|
273
|
+
plot_params : dict, optional
|
|
274
|
+
Additional parameters to pass to the plotting function.
|
|
275
|
+
labels : dict, optional
|
|
276
|
+
Dictionary containing 'x', 'y', and 'title' labels.
|
|
277
|
+
scales : dict, optional
|
|
278
|
+
Dictionary containing 'x' and 'y' scale types ('log' or 'linear').
|
|
279
|
+
colorbar_label : str, optional
|
|
280
|
+
Label for the colorbar in 2D histograms.
|
|
281
|
+
output_file : Path, optional
|
|
282
|
+
File path to save the plot. If not provided, the plot will be displayed.
|
|
283
|
+
lines : dict, optional
|
|
284
|
+
Dictionary containing 'x' and 'y' values for reference lines.
|
|
211
285
|
|
|
212
286
|
Returns
|
|
213
287
|
-------
|
|
214
|
-
|
|
215
|
-
|
|
288
|
+
matplotlib.figure.Figure
|
|
289
|
+
The created figure object.
|
|
216
290
|
"""
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
plt.colorbar(label="Event Count")
|
|
256
|
-
plt.xlabel("Core Distance [m]")
|
|
257
|
-
plt.ylabel("Energy [TeV]")
|
|
258
|
-
plt.yscale("log")
|
|
259
|
-
plt.title("2D Histogram of Triggered Core Distance vs Energy")
|
|
260
|
-
plt.show()
|
|
291
|
+
fig = plt.figure(figsize=(8, 6))
|
|
292
|
+
plot_params = plot_params or {}
|
|
293
|
+
labels = labels or {}
|
|
294
|
+
scales = scales or {}
|
|
295
|
+
lines = lines or {}
|
|
296
|
+
|
|
297
|
+
if plot_type == "histogram":
|
|
298
|
+
plt.hist(x_data, bins=bins, **plot_params)
|
|
299
|
+
elif plot_type == "histogram2d":
|
|
300
|
+
plt.hist2d(x_data, y_data, bins=bins, **plot_params)
|
|
301
|
+
if colorbar_label:
|
|
302
|
+
plt.colorbar(label=colorbar_label)
|
|
303
|
+
elif plot_type == "scatter":
|
|
304
|
+
plt.scatter(x_data, y_data, **plot_params)
|
|
305
|
+
|
|
306
|
+
if "x" in lines:
|
|
307
|
+
plt.axvline(lines["x"], color="r", linestyle="--")
|
|
308
|
+
if "y" in lines:
|
|
309
|
+
plt.axhline(lines["y"], color="r", linestyle="--")
|
|
310
|
+
|
|
311
|
+
plt.xlabel(labels.get("x", ""))
|
|
312
|
+
plt.ylabel(labels.get("y", ""))
|
|
313
|
+
plt.title(labels.get("title", ""))
|
|
314
|
+
|
|
315
|
+
if "x" in scales:
|
|
316
|
+
plt.xscale(scales["x"])
|
|
317
|
+
if "y" in scales:
|
|
318
|
+
plt.yscale(scales["y"])
|
|
319
|
+
|
|
320
|
+
if output_file:
|
|
321
|
+
self._logger.info(f"Saving plot to {output_file}")
|
|
322
|
+
plt.savefig(output_file, dpi=300, bbox_inches="tight")
|
|
323
|
+
plt.close()
|
|
324
|
+
else:
|
|
325
|
+
plt.tight_layout()
|
|
326
|
+
plt.show()
|
|
327
|
+
|
|
328
|
+
return fig
|
|
@@ -68,9 +68,9 @@ class EventScaler:
|
|
|
68
68
|
The scaling factor.
|
|
69
69
|
"""
|
|
70
70
|
metric_results = self.evaluator.calculate_metrics()
|
|
71
|
-
uncertainty_effective_area = metric_results.get("uncertainty_effective_area"
|
|
71
|
+
uncertainty_effective_area = metric_results.get("uncertainty_effective_area")
|
|
72
72
|
current_max_error = uncertainty_effective_area.get("max_error")
|
|
73
|
-
target_max_error = self.metrics.get("uncertainty_effective_area"
|
|
73
|
+
target_max_error = self.metrics.get("uncertainty_effective_area").get("target_error")[
|
|
74
74
|
"value"
|
|
75
75
|
]
|
|
76
76
|
|