gammasimtools 0.18.0__py3-none-any.whl → 0.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.20.0.dist-info}/METADATA +24 -69
- gammasimtools-0.20.0.dist-info/RECORD +395 -0
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.20.0.dist-info}/entry_points.txt +11 -4
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.20.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +16 -3
- simtools/applications/calculate_incident_angles.py +182 -0
- simtools/applications/convert_all_model_parameters_from_simtel.py +4 -3
- simtools/applications/convert_geo_coordinates_of_array_elements.py +3 -3
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +17 -14
- simtools/applications/db_add_value_from_json_to_db.py +8 -10
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +8 -13
- simtools/applications/db_generate_compound_indexes.py +65 -0
- simtools/applications/db_get_file_from_db.py +12 -24
- simtools/applications/db_get_parameter_from_db.py +4 -4
- simtools/applications/db_inspect_databases.py +20 -10
- simtools/applications/derive_mirror_rnda.py +17 -11
- simtools/applications/derive_psf_parameters.py +59 -309
- simtools/applications/derive_trigger_rates.py +91 -0
- simtools/applications/docs_produce_array_element_report.py +1 -1
- simtools/applications/docs_produce_calibration_reports.py +1 -1
- simtools/applications/docs_produce_model_parameter_reports.py +1 -1
- simtools/applications/docs_produce_simulation_configuration_report.py +1 -1
- simtools/applications/generate_corsika_histograms.py +1 -1
- simtools/applications/generate_default_metadata.py +8 -24
- simtools/applications/generate_simtel_event_data.py +11 -11
- simtools/applications/maintain_simulation_model_add_production_table.py +71 -0
- simtools/applications/maintain_simulation_model_compare_productions.py +98 -0
- simtools/applications/{verify_simulation_model_production_tables.py → maintain_simulation_model_verify_production_tables.py} +9 -1
- simtools/applications/merge_tables.py +2 -2
- simtools/applications/plot_array_layout.py +3 -3
- simtools/applications/plot_simtel_events.py +421 -0
- simtools/applications/plot_tabular_data.py +9 -2
- simtools/applications/plot_tabular_data_for_model_parameter.py +2 -1
- simtools/applications/print_version.py +8 -9
- simtools/applications/production_derive_corsika_limits.py +6 -7
- simtools/applications/production_derive_statistics.py +1 -1
- simtools/applications/production_generate_grid.py +2 -2
- simtools/applications/production_merge_corsika_limits.py +214 -0
- simtools/applications/run_application.py +47 -113
- simtools/applications/simulate_calibration_events.py +166 -0
- simtools/applications/simulate_flasher.py +141 -0
- simtools/applications/{simulate_light_emission.py → simulate_illuminator.py} +35 -99
- simtools/applications/simulate_prod.py +6 -24
- simtools/applications/simulate_prod_htcondor_generator.py +7 -0
- simtools/applications/submit_array_layouts.py +2 -1
- simtools/applications/submit_model_parameter_from_external.py +1 -1
- simtools/applications/validate_camera_efficiency.py +30 -12
- simtools/applications/validate_camera_fov.py +1 -1
- simtools/applications/validate_cumulative_psf.py +1 -1
- simtools/applications/validate_file_using_schema.py +9 -5
- simtools/applications/validate_optics.py +1 -1
- simtools/camera/camera_efficiency.py +61 -45
- simtools/camera/single_photon_electron_spectrum.py +1 -1
- simtools/configuration/commandline_parser.py +46 -11
- simtools/configuration/configurator.py +4 -4
- simtools/corsika/corsika_config.py +45 -25
- simtools/corsika/corsika_histograms.py +6 -5
- simtools/data_model/data_reader.py +2 -3
- simtools/data_model/metadata_collector.py +32 -36
- simtools/data_model/metadata_model.py +15 -12
- simtools/data_model/model_data_writer.py +13 -32
- simtools/data_model/schema.py +74 -24
- simtools/data_model/validate_data.py +42 -12
- simtools/db/db_handler.py +125 -62
- simtools/db/db_model_upload.py +14 -19
- simtools/dependencies.py +98 -30
- simtools/io/ascii_handler.py +279 -0
- simtools/{io_operations → io}/io_handler.py +25 -3
- simtools/job_execution/htcondor_script_generator.py +15 -4
- simtools/layout/array_layout.py +1 -1
- simtools/layout/array_layout_utils.py +51 -12
- simtools/model/array_model.py +41 -5
- simtools/model/flasher_model.py +106 -0
- simtools/model/model_parameter.py +4 -4
- simtools/model/model_repository.py +197 -2
- simtools/model/site_model.py +25 -0
- simtools/model/telescope_model.py +3 -1
- simtools/production_configuration/derive_corsika_limits.py +336 -427
- simtools/production_configuration/derive_production_statistics_handler.py +7 -6
- simtools/production_configuration/generate_production_grid.py +9 -11
- simtools/production_configuration/merge_corsika_limits.py +528 -0
- simtools/ray_tracing/incident_angles.py +706 -0
- simtools/ray_tracing/mirror_panel_psf.py +1 -0
- simtools/ray_tracing/psf_parameter_optimisation.py +792 -0
- simtools/ray_tracing/ray_tracing.py +6 -2
- simtools/reporting/docs_read_parameters.py +150 -62
- simtools/runners/corsika_runner.py +1 -1
- simtools/runners/corsika_simtel_runner.py +14 -5
- simtools/runners/runner_services.py +10 -5
- simtools/runners/simtools_runner.py +267 -0
- simtools/schemas/application_workflow.metaschema.yml +101 -68
- simtools/schemas/input/MST_mirror_2f_measurements.schema.yml +1 -1
- simtools/schemas/input/single_pe_spectrum.schema.yml +1 -1
- simtools/schemas/metadata.metaschema.yml +577 -3
- simtools/schemas/model_parameter.metaschema.yml +6 -6
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +4 -4
- 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.schema.yml +1 -1
- simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +1 -1
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +1 -1
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +1 -1
- simtools/schemas/model_parameters/array_layouts.schema.yml +1 -1
- simtools/schemas/model_parameters/array_triggers.schema.yml +1 -1
- 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_shaping.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/atmospheric_profile.schema.yml +1 -1
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +1 -1
- simtools/schemas/model_parameters/axes_offsets.schema.yml +1 -1
- 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_file.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_degraded_map.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_depth.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_filter.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_filter_incidence_angle.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/correct_nsb_spectrum_to_telescope_altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_first_interaction_height.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_longitudinal_shower_development.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_observation_level.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +3 -3
- simtools/schemas/model_parameters/dark_events.schema.yml +1 -1
- simtools/schemas/model_parameters/default_trigger.schema.yml +1 -1
- simtools/schemas/model_parameters/design_model.schema.yml +1 -1
- simtools/schemas/model_parameters/disc_ac_coupled.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_pulse_shape.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_pedsub.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +1 -1
- 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_shaping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +1 -1
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/epsg_code.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_ac_coupled.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_long_event_threshold.schema.yml +35 -0
- simtools/schemas/model_parameters/fadc_long_sum_bins.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_long_sum_offset.schema.yml +38 -0
- 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_pulse_shape.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/fake_mirror_list.schema.yml +1 -1
- simtools/schemas/model_parameters/flatfielding.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/focus_offset.schema.yml +1 -1
- 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/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +50 -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 +1 -1
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +1 -1
- 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_list.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +1 -1
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +2 -2
- 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_sky_map.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +23 -30
- simtools/schemas/model_parameters/num_gains.schema.yml +1 -1
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +1 -1
- simtools/schemas/model_parameters/optics_properties.schema.yml +1 -1
- simtools/schemas/model_parameters/parabolic_dish.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_photoelectron_spectrum.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +1 -1
- 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_incidence_angle.schema.yml +11 -1
- simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +1 -1
- simtools/schemas/model_parameters/qe_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +1 -1
- simtools/schemas/model_parameters/random_focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/random_generator.schema.yml +1 -1
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_latitude.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_longitude.schema.yml +1 -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/sampled_output.schema.yml +1 -1
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +1 -1
- 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_incidence_angle.schema.yml +11 -1
- simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +11 -1
- simtools/schemas/model_parameters/secondary_mirror_segmentation.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 +2 -2
- 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 +1 -1
- 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 +1 -1
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +1 -1
- simtools/schemas/plot_configuration.metaschema.yml +5 -2
- simtools/schemas/production_configuration_metrics.schema.yml +12 -2
- simtools/schemas/production_tables.schema.yml +7 -2
- simtools/simtel/simtel_config_reader.py +2 -2
- simtools/simtel/simtel_config_writer.py +33 -23
- simtools/simtel/simtel_io_event_histograms.py +483 -0
- simtools/simtel/simtel_io_event_reader.py +65 -43
- simtools/simtel/simtel_io_event_writer.py +40 -20
- simtools/simtel/simtel_io_metadata.py +1 -1
- simtools/simtel/simtel_table_reader.py +95 -13
- simtools/simtel/simulator_array.py +138 -10
- simtools/simtel/simulator_camera_efficiency.py +32 -23
- simtools/simtel/simulator_light_emission.py +437 -271
- simtools/simtel/simulator_ray_tracing.py +1 -1
- simtools/simulator.py +105 -147
- simtools/telescope_trigger_rates.py +119 -0
- simtools/testing/configuration.py +24 -26
- simtools/testing/helpers.py +2 -2
- simtools/testing/log_inspector.py +52 -0
- simtools/testing/validate_output.py +87 -37
- simtools/utils/general.py +125 -255
- simtools/utils/geometry.py +56 -0
- simtools/utils/names.py +1 -1
- simtools/visualization/legend_handlers.py +180 -264
- simtools/visualization/plot_array_layout.py +20 -8
- simtools/visualization/plot_incident_angles.py +431 -0
- simtools/visualization/plot_pixels.py +1 -1
- simtools/visualization/plot_simtel_event_histograms.py +376 -0
- simtools/visualization/plot_simtel_events.py +816 -0
- simtools/visualization/plot_tables.py +133 -37
- simtools/visualization/visualize.py +1 -100
- gammasimtools-0.18.0.dist-info/RECORD +0 -376
- simtools/applications/calculate_trigger_rate.py +0 -187
- simtools/applications/generate_sim_telarray_histograms.py +0 -196
- simtools/production_configuration/derive_corsika_limits_grid.py +0 -232
- simtools/simtel/simtel_io_histogram.py +0 -621
- simtools/simtel/simtel_io_histograms.py +0 -552
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.20.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.20.0.dist-info}/top_level.txt +0 -0
- /simtools/{io_operations → io}/hdf5_handler.py +0 -0
- /simtools/{io_operations → io}/legacy_data_handler.py +0 -0
- /simtools/{io_operations/io_table_handler.py → io/table_handler.py} +0 -0
|
@@ -1,456 +1,365 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Derive CORSIKA limits from a reduced event data file."""
|
|
2
2
|
|
|
3
|
+
import datetime
|
|
3
4
|
import logging
|
|
4
5
|
|
|
5
6
|
import astropy.units as u
|
|
6
|
-
import matplotlib.pyplot as plt
|
|
7
7
|
import numpy as np
|
|
8
|
-
from
|
|
8
|
+
from astropy.table import Column, Table
|
|
9
9
|
|
|
10
|
-
from simtools.
|
|
10
|
+
from simtools.data_model.metadata_collector import MetadataCollector
|
|
11
|
+
from simtools.io import ascii_handler, io_handler
|
|
12
|
+
from simtools.layout.array_layout_utils import get_array_elements_from_db_for_layouts
|
|
13
|
+
from simtools.simtel.simtel_io_event_histograms import SimtelIOEventHistograms
|
|
14
|
+
from simtools.visualization import plot_simtel_event_histograms
|
|
11
15
|
|
|
16
|
+
_logger = logging.getLogger(__name__)
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
|
|
19
|
+
def generate_corsika_limits_grid(args_dict, db_config=None):
|
|
20
|
+
"""
|
|
21
|
+
Generate CORSIKA limits.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
args_dict : dict
|
|
26
|
+
Dictionary containing command line arguments.
|
|
27
|
+
db_config : dict, optional
|
|
28
|
+
Database configuration dictionary.
|
|
29
|
+
"""
|
|
30
|
+
if args_dict.get("array_layout_name"):
|
|
31
|
+
telescope_configs = get_array_elements_from_db_for_layouts(
|
|
32
|
+
args_dict["array_layout_name"],
|
|
33
|
+
args_dict.get("site"),
|
|
34
|
+
args_dict.get("model_version"),
|
|
35
|
+
db_config,
|
|
36
|
+
)
|
|
37
|
+
else:
|
|
38
|
+
telescope_configs = ascii_handler.collect_data_from_file(args_dict["telescope_ids"])[
|
|
39
|
+
"telescope_configs"
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
results = []
|
|
43
|
+
for array_name, telescope_ids in telescope_configs.items():
|
|
44
|
+
_logger.info(
|
|
45
|
+
f"Processing file: {args_dict['event_data_file']} with telescope config: {array_name}"
|
|
46
|
+
)
|
|
47
|
+
result = _process_file(
|
|
48
|
+
args_dict["event_data_file"],
|
|
49
|
+
array_name,
|
|
50
|
+
telescope_ids,
|
|
51
|
+
args_dict["loss_fraction"],
|
|
52
|
+
args_dict["plot_histograms"],
|
|
53
|
+
)
|
|
54
|
+
result["layout"] = array_name
|
|
55
|
+
results.append(result)
|
|
56
|
+
|
|
57
|
+
write_results(results, args_dict)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _process_file(file_path, array_name, telescope_ids, loss_fraction, plot_histograms):
|
|
61
|
+
"""
|
|
62
|
+
Compute limits for a given event data file and telescope configuration.
|
|
63
|
+
|
|
64
|
+
Compute limits for energy, radial distance, and viewcone.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
file_path : str
|
|
69
|
+
Path to the event data file.
|
|
70
|
+
array_name : str
|
|
71
|
+
Name of the telescope array configuration.
|
|
72
|
+
telescope_ids : list[int]
|
|
73
|
+
List of telescope IDs to filter the events.
|
|
74
|
+
loss_fraction : float
|
|
75
|
+
Fraction of events to be lost.
|
|
76
|
+
plot_histograms : bool
|
|
77
|
+
Whether to plot histograms.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
dict
|
|
82
|
+
Dictionary containing the computed limits and metadata.
|
|
14
83
|
"""
|
|
15
|
-
|
|
84
|
+
histograms = SimtelIOEventHistograms(
|
|
85
|
+
file_path, array_name=array_name, telescope_list=telescope_ids
|
|
86
|
+
)
|
|
87
|
+
histograms.fill()
|
|
88
|
+
|
|
89
|
+
limits = {
|
|
90
|
+
"lower_energy_limit": compute_lower_energy_limit(histograms, loss_fraction),
|
|
91
|
+
"upper_radius_limit": compute_upper_radius_limit(histograms, loss_fraction),
|
|
92
|
+
"viewcone_radius": compute_viewcone(histograms, loss_fraction),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if plot_histograms:
|
|
96
|
+
plot_simtel_event_histograms.plot(
|
|
97
|
+
histograms.histograms,
|
|
98
|
+
output_path=io_handler.IOHandler().get_output_directory(),
|
|
99
|
+
limits=limits,
|
|
100
|
+
array_name=array_name,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return limits
|
|
104
|
+
|
|
16
105
|
|
|
17
|
-
|
|
106
|
+
def write_results(results, args_dict):
|
|
107
|
+
"""
|
|
108
|
+
Write the computed limits as astropy table to file.
|
|
18
109
|
|
|
19
110
|
Parameters
|
|
20
111
|
----------
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
112
|
+
results : list[dict]
|
|
113
|
+
List of computed limits.
|
|
114
|
+
args_dict : dict
|
|
115
|
+
Dictionary containing command line arguments.
|
|
116
|
+
"""
|
|
117
|
+
table = _create_results_table(results, args_dict["loss_fraction"])
|
|
118
|
+
|
|
119
|
+
output_dir = io_handler.IOHandler().get_output_directory("corsika_limits")
|
|
120
|
+
output_file = output_dir / args_dict["output_file"]
|
|
121
|
+
|
|
122
|
+
table.write(output_file, format="ascii.ecsv", overwrite=True)
|
|
123
|
+
_logger.info(f"Results saved to {output_file}")
|
|
124
|
+
|
|
125
|
+
MetadataCollector.dump(args_dict, output_file)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _create_results_table(results, loss_fraction):
|
|
27
129
|
"""
|
|
130
|
+
Convert list of simulation results to an astropy Table with metadata.
|
|
131
|
+
|
|
132
|
+
Round values to appropriate precision and add metadata.
|
|
28
133
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
""
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"upper_radius_limit": None,
|
|
68
|
-
"viewcone_radius": None,
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
results : list[dict]
|
|
137
|
+
Computed limits per file and telescope configuration.
|
|
138
|
+
loss_fraction : float
|
|
139
|
+
Fraction of lost events (added to metadata).
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
astropy.table.Table
|
|
144
|
+
Table with computed limits.
|
|
145
|
+
"""
|
|
146
|
+
cols = [
|
|
147
|
+
"primary_particle",
|
|
148
|
+
"array_name",
|
|
149
|
+
"telescope_ids",
|
|
150
|
+
"zenith",
|
|
151
|
+
"azimuth",
|
|
152
|
+
"nsb_level",
|
|
153
|
+
"lower_energy_limit",
|
|
154
|
+
"upper_radius_limit",
|
|
155
|
+
"viewcone_radius",
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
columns = {name: [] for name in cols}
|
|
159
|
+
units = {}
|
|
160
|
+
|
|
161
|
+
for res in results:
|
|
162
|
+
_process_result_row(res, cols, columns, units)
|
|
163
|
+
|
|
164
|
+
table_cols = _create_table_columns(cols, columns, units)
|
|
165
|
+
table = Table(table_cols)
|
|
166
|
+
|
|
167
|
+
table.meta.update(
|
|
168
|
+
{
|
|
169
|
+
"created": datetime.datetime.now().isoformat(),
|
|
170
|
+
"description": "Lookup table for CORSIKA limits computed from simulations.",
|
|
171
|
+
"loss_fraction": loss_fraction,
|
|
69
172
|
}
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
return table
|
|
70
176
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Dictionary containing the computed limits.
|
|
84
|
-
"""
|
|
85
|
-
self._fill_histograms()
|
|
86
|
-
|
|
87
|
-
self.limits["lower_energy_limit"] = self.compute_lower_energy_limit(loss_fraction)
|
|
88
|
-
self.limits["upper_radius_limit"] = self.compute_upper_radius_limit(loss_fraction)
|
|
89
|
-
self.limits["viewcone_radius"] = self.compute_viewcone(loss_fraction)
|
|
90
|
-
|
|
91
|
-
return self.limits
|
|
92
|
-
|
|
93
|
-
def _fill_histogram_and_bin_edges(self, name, data, bins, hist1d=True):
|
|
94
|
-
"""
|
|
95
|
-
Fill histogram and bin edges and it both to histogram dictionary.
|
|
96
|
-
|
|
97
|
-
Adds histogram to existing histogram if it exists, otherwise initializes it.
|
|
98
|
-
|
|
99
|
-
"""
|
|
100
|
-
if name in self.histograms:
|
|
101
|
-
if hist1d:
|
|
102
|
-
bins = self.histograms[f"{name}_bin_edges"]
|
|
103
|
-
hist, _ = np.histogram(data, bins=bins)
|
|
104
|
-
self.histograms[name] += hist
|
|
105
|
-
else:
|
|
106
|
-
x_bins = self.histograms[f"{name}_bin_x_edges"]
|
|
107
|
-
y_bins = self.histograms[f"{name}_bin_y_edges"]
|
|
108
|
-
hist, _, _ = np.histogram2d(data[0], data[1], bins=[x_bins, y_bins])
|
|
109
|
-
self.histograms[name] += hist
|
|
177
|
+
|
|
178
|
+
def _process_result_row(res, cols, columns, units):
|
|
179
|
+
"""Process a single result row and add values to columns."""
|
|
180
|
+
for k in cols:
|
|
181
|
+
val = res.get(k, None)
|
|
182
|
+
if val is not None:
|
|
183
|
+
val = _round_value(k, val)
|
|
184
|
+
_logger.debug(f"Adding {k}: {val} to column data")
|
|
185
|
+
|
|
186
|
+
if hasattr(val, "unit"):
|
|
187
|
+
columns[k].append(val.value)
|
|
188
|
+
units[k] = val.unit
|
|
110
189
|
else:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
self._fill_histogram_and_bin_edges(
|
|
139
|
-
"core_distance", event_data.core_distance_shower, self.core_distance_bins
|
|
140
|
-
)
|
|
141
|
-
self._fill_histogram_and_bin_edges(
|
|
142
|
-
"angular_distance", triggered_data.angular_distance, self.view_cone_bins
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
xy_bins = np.linspace(
|
|
146
|
-
-1.0 * self.core_distance_bins.max(),
|
|
147
|
-
self.core_distance_bins.max(),
|
|
148
|
-
len(self.core_distance_bins),
|
|
149
|
-
)
|
|
150
|
-
self._fill_histogram_and_bin_edges(
|
|
151
|
-
"shower_cores",
|
|
152
|
-
(event_data.x_core_shower, event_data.y_core_shower),
|
|
153
|
-
[xy_bins, xy_bins],
|
|
154
|
-
hist1d=False,
|
|
155
|
-
)
|
|
156
|
-
self._fill_histogram_and_bin_edges(
|
|
157
|
-
"core_vs_energy",
|
|
158
|
-
(event_data.core_distance_shower, event_data.simulated_energy),
|
|
159
|
-
[self.core_distance_bins, self.energy_bins],
|
|
160
|
-
hist1d=False,
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
def _compute_limits(self, hist, bin_edges, loss_fraction, limit_type="lower"):
|
|
164
|
-
"""
|
|
165
|
-
Compute the limits based on the loss fraction.
|
|
166
|
-
|
|
167
|
-
Add or subtract one bin to be on the safe side of the limit.
|
|
168
|
-
|
|
169
|
-
Parameters
|
|
170
|
-
----------
|
|
171
|
-
hist : np.ndarray
|
|
172
|
-
1D histogram array.
|
|
173
|
-
bin_edges : np.ndarray
|
|
174
|
-
Array of bin edges.
|
|
175
|
-
loss_fraction : float
|
|
176
|
-
Fraction of events to be lost.
|
|
177
|
-
limit_type : str, optional
|
|
178
|
-
Type of limit ('lower' or 'upper'). Default is 'lower'.
|
|
179
|
-
|
|
180
|
-
Returns
|
|
181
|
-
-------
|
|
182
|
-
float
|
|
183
|
-
Bin edge value corresponding to the threshold.
|
|
184
|
-
"""
|
|
185
|
-
total_events = np.sum(hist)
|
|
186
|
-
threshold = (1 - loss_fraction) * total_events
|
|
187
|
-
if limit_type == "upper":
|
|
188
|
-
cum = np.cumsum(hist)
|
|
189
|
-
idx = np.searchsorted(cum, threshold) + 1
|
|
190
|
-
return bin_edges[min(idx, len(bin_edges) - 1)]
|
|
191
|
-
if limit_type == "lower":
|
|
192
|
-
cum = np.cumsum(hist[::-1])
|
|
193
|
-
idx = np.searchsorted(cum, threshold) + 1
|
|
194
|
-
return bin_edges[max(len(bin_edges) - 1 - idx, 0)]
|
|
195
|
-
raise ValueError("limit_type must be 'lower' or 'upper'")
|
|
196
|
-
|
|
197
|
-
@property
|
|
198
|
-
def energy_bins(self):
|
|
199
|
-
"""Return bins for the energy histogram."""
|
|
200
|
-
return np.logspace(
|
|
201
|
-
np.log10(self.file_info.get("energy_min", 1.0e-3 * u.TeV).to("TeV").value),
|
|
202
|
-
np.log10(self.file_info.get("energy_max", 1.0e3 * u.TeV).to("TeV").value),
|
|
203
|
-
100,
|
|
204
|
-
)
|
|
190
|
+
columns[k].append(val)
|
|
191
|
+
if k not in units:
|
|
192
|
+
units[k] = None
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _round_value(key, val):
|
|
196
|
+
"""Round value based on key type."""
|
|
197
|
+
if key == "lower_energy_limit":
|
|
198
|
+
return np.floor(val * 1e3) / 1e3
|
|
199
|
+
if key == "upper_radius_limit":
|
|
200
|
+
return np.ceil(val / 25) * 25
|
|
201
|
+
if key == "viewcone_radius":
|
|
202
|
+
return np.ceil(val / 0.25) * 0.25
|
|
203
|
+
return val
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _create_table_columns(cols, columns, units):
|
|
207
|
+
"""Create table columns with appropriate data types."""
|
|
208
|
+
table_cols = []
|
|
209
|
+
for k in cols:
|
|
210
|
+
col_data = columns[k]
|
|
211
|
+
if any(isinstance(v, list | tuple) for v in col_data):
|
|
212
|
+
col = Column(data=col_data, name=k, unit=units.get(k), dtype=object)
|
|
213
|
+
else:
|
|
214
|
+
col = Column(data=col_data, name=k, unit=units.get(k))
|
|
215
|
+
table_cols.append(col)
|
|
216
|
+
return table_cols
|
|
205
217
|
|
|
206
|
-
def compute_lower_energy_limit(self, loss_fraction):
|
|
207
|
-
"""
|
|
208
|
-
Compute the lower energy limit in TeV based on the event loss fraction.
|
|
209
|
-
|
|
210
|
-
Parameters
|
|
211
|
-
----------
|
|
212
|
-
loss_fraction : float
|
|
213
|
-
Fraction of events to be lost.
|
|
214
|
-
|
|
215
|
-
Returns
|
|
216
|
-
-------
|
|
217
|
-
astropy.units.Quantity
|
|
218
|
-
Lower energy limit.
|
|
219
|
-
"""
|
|
220
|
-
return (
|
|
221
|
-
self._compute_limits(
|
|
222
|
-
self.histograms.get("energy"), self.energy_bins, loss_fraction, limit_type="lower"
|
|
223
|
-
)
|
|
224
|
-
* u.TeV
|
|
225
|
-
)
|
|
226
218
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return np.linspace(
|
|
231
|
-
self.file_info.get("core_scatter_min", 0.0 * u.m).to("m").value,
|
|
232
|
-
self.file_info.get("core_scatter_max", 1.0e5 * u.m).to("m").value,
|
|
233
|
-
100,
|
|
234
|
-
)
|
|
219
|
+
def _compute_limits(hist, bin_edges, loss_fraction, limit_type="lower"):
|
|
220
|
+
"""
|
|
221
|
+
Compute the limits based on the loss fraction.
|
|
235
222
|
|
|
236
|
-
|
|
237
|
-
"""
|
|
238
|
-
Compute the upper radial distance based on the event loss fraction.
|
|
239
|
-
|
|
240
|
-
Parameters
|
|
241
|
-
----------
|
|
242
|
-
loss_fraction : float
|
|
243
|
-
Fraction of events to be lost.
|
|
244
|
-
|
|
245
|
-
Returns
|
|
246
|
-
-------
|
|
247
|
-
astropy.units.Quantity
|
|
248
|
-
Upper radial distance in m.
|
|
249
|
-
"""
|
|
250
|
-
return (
|
|
251
|
-
self._compute_limits(
|
|
252
|
-
self.histograms.get("core_distance"),
|
|
253
|
-
self.core_distance_bins,
|
|
254
|
-
loss_fraction,
|
|
255
|
-
limit_type="upper",
|
|
256
|
-
)
|
|
257
|
-
* u.m
|
|
258
|
-
)
|
|
223
|
+
Add or subtract one bin to be on the safe side of the limit.
|
|
259
224
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
hist : np.ndarray
|
|
228
|
+
1D histogram array.
|
|
229
|
+
bin_edges : np.ndarray
|
|
230
|
+
Array of bin edges.
|
|
231
|
+
loss_fraction : float
|
|
232
|
+
Fraction of events to be lost.
|
|
233
|
+
limit_type : str, optional
|
|
234
|
+
Type of limit ('lower' or 'upper'). Default is 'lower'.
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
float
|
|
239
|
+
Bin edge value corresponding to the threshold.
|
|
240
|
+
"""
|
|
241
|
+
total_events = np.sum(hist)
|
|
242
|
+
threshold = (1 - loss_fraction) * total_events
|
|
243
|
+
if limit_type == "upper":
|
|
244
|
+
cum = np.cumsum(hist)
|
|
245
|
+
idx = np.searchsorted(cum, threshold) + 1
|
|
246
|
+
return bin_edges[min(idx, len(bin_edges) - 1)]
|
|
247
|
+
if limit_type == "lower":
|
|
248
|
+
cum = np.cumsum(hist[::-1])
|
|
249
|
+
idx = np.searchsorted(cum, threshold) + 1
|
|
250
|
+
return bin_edges[max(len(bin_edges) - 1 - idx, 0)]
|
|
251
|
+
raise ValueError("limit_type must be 'lower' or 'upper'")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def compute_lower_energy_limit(histograms, loss_fraction):
|
|
255
|
+
"""
|
|
256
|
+
Compute the lower energy limit in TeV based on the event loss fraction.
|
|
268
257
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return (
|
|
288
|
-
self._compute_limits(
|
|
289
|
-
self.histograms.get("angular_distance"),
|
|
290
|
-
self.view_cone_bins,
|
|
291
|
-
loss_fraction,
|
|
292
|
-
limit_type="upper",
|
|
293
|
-
)
|
|
294
|
-
* u.deg
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
histograms : SimtelIOEventHistograms
|
|
261
|
+
Histograms.
|
|
262
|
+
loss_fraction : float
|
|
263
|
+
Fraction of events to be lost.
|
|
264
|
+
|
|
265
|
+
Returns
|
|
266
|
+
-------
|
|
267
|
+
astropy.units.Quantity
|
|
268
|
+
Lower energy limit.
|
|
269
|
+
"""
|
|
270
|
+
energy_min = (
|
|
271
|
+
_compute_limits(
|
|
272
|
+
histograms.histograms["energy"]["histogram"],
|
|
273
|
+
histograms.energy_bins,
|
|
274
|
+
loss_fraction,
|
|
275
|
+
limit_type="lower",
|
|
295
276
|
)
|
|
277
|
+
* u.TeV
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
return _is_close(
|
|
281
|
+
energy_min,
|
|
282
|
+
histograms.file_info["energy_min"].to("TeV")
|
|
283
|
+
if "energy_min" in histograms.file_info
|
|
284
|
+
else None,
|
|
285
|
+
"Lower energy limit is equal to the minimum energy of",
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _is_close(value, reference, warning_text):
|
|
290
|
+
"""Check if the value is close to the reference value and log a warning if so."""
|
|
291
|
+
if reference is not None and np.isclose(value.value, reference.value, rtol=1.0e-2):
|
|
292
|
+
_logger.warning(f"{warning_text} {value}.")
|
|
293
|
+
return value
|
|
296
294
|
|
|
297
|
-
def plot_data(self, output_path=None):
|
|
298
|
-
"""
|
|
299
|
-
Histogram plotting.
|
|
300
|
-
|
|
301
|
-
Parameters
|
|
302
|
-
----------
|
|
303
|
-
output_path: Path or str, optional
|
|
304
|
-
Directory to save plots. If None, plots will be displayed.
|
|
305
|
-
"""
|
|
306
|
-
self._logger.info(f"Plotting histograms written to {output_path}")
|
|
307
|
-
event_counts = "Event Count"
|
|
308
|
-
plots = {
|
|
309
|
-
"core_vs_energy": {
|
|
310
|
-
"data": self.histograms.get("core_vs_energy"),
|
|
311
|
-
"bins": [
|
|
312
|
-
self.histograms.get("core_vs_energy_bin_x_edges"),
|
|
313
|
-
self.histograms.get("core_vs_energy_bin_y_edges"),
|
|
314
|
-
],
|
|
315
|
-
"plot_type": "histogram2d",
|
|
316
|
-
"plot_params": {"norm": "log", "cmap": "viridis"},
|
|
317
|
-
"labels": {
|
|
318
|
-
"x": "Core Distance [m]",
|
|
319
|
-
"y": "Energy [TeV]",
|
|
320
|
-
"title": "Triggered events: core distance vs energy",
|
|
321
|
-
},
|
|
322
|
-
"lines": {
|
|
323
|
-
"x": self.limits["upper_radius_limit"].value,
|
|
324
|
-
"y": self.limits["lower_energy_limit"].value,
|
|
325
|
-
},
|
|
326
|
-
"scales": {"y": "log"},
|
|
327
|
-
"colorbar_label": event_counts,
|
|
328
|
-
"filename": "core_vs_energy_distribution",
|
|
329
|
-
},
|
|
330
|
-
"energy_distribution": {
|
|
331
|
-
"data": self.histograms.get("energy"),
|
|
332
|
-
"bins": self.histograms.get("energy_bin_edges"),
|
|
333
|
-
"plot_type": "histogram",
|
|
334
|
-
"plot_params": {"color": "g", "edgecolor": "g", "lw": 1},
|
|
335
|
-
"labels": {
|
|
336
|
-
"x": "Energy [TeV]",
|
|
337
|
-
"y": event_counts,
|
|
338
|
-
"title": "Triggered events: energy distribution",
|
|
339
|
-
},
|
|
340
|
-
"scales": {"x": "log", "y": "log"},
|
|
341
|
-
"lines": {"x": self.limits["lower_energy_limit"].value},
|
|
342
|
-
"filename": "energy_distribution",
|
|
343
|
-
},
|
|
344
|
-
"core_distance": {
|
|
345
|
-
"data": self.histograms.get("core_distance"),
|
|
346
|
-
"bins": self.histograms.get("core_distance_bin_edges"),
|
|
347
|
-
"plot_type": "histogram",
|
|
348
|
-
"plot_params": {"color": "g", "edgecolor": "g", "lw": 1},
|
|
349
|
-
"labels": {
|
|
350
|
-
"x": "Core Distance [m]",
|
|
351
|
-
"y": event_counts,
|
|
352
|
-
"title": "Triggered events: core distance distribution",
|
|
353
|
-
},
|
|
354
|
-
"lines": {"x": self.limits["upper_radius_limit"].value},
|
|
355
|
-
"filename": "core_distance_distribution",
|
|
356
|
-
},
|
|
357
|
-
"core_xy": {
|
|
358
|
-
"data": self.histograms.get("shower_cores"),
|
|
359
|
-
"bins": [
|
|
360
|
-
self.histograms.get("shower_cores_bin_x_edges"),
|
|
361
|
-
self.histograms.get("shower_cores_bin_y_edges"),
|
|
362
|
-
],
|
|
363
|
-
"plot_type": "histogram2d",
|
|
364
|
-
"plot_params": {"norm": "log", "cmap": "viridis", "aspect": "equal"},
|
|
365
|
-
"labels": {
|
|
366
|
-
"x": "Core X [m]",
|
|
367
|
-
"y": "Core Y [m]",
|
|
368
|
-
"title": "Triggered events: core x vs core y",
|
|
369
|
-
},
|
|
370
|
-
"colorbar_label": event_counts,
|
|
371
|
-
"lines": {
|
|
372
|
-
"r": self.limits["upper_radius_limit"].value,
|
|
373
|
-
},
|
|
374
|
-
"filename": "core_xy_distribution",
|
|
375
|
-
},
|
|
376
|
-
"angular_distance": {
|
|
377
|
-
"data": self.histograms.get("angular_distance"),
|
|
378
|
-
"bins": self.histograms.get("angular_distance_bin_edges"),
|
|
379
|
-
"plot_type": "histogram",
|
|
380
|
-
"plot_params": {"color": "g", "edgecolor": "g", "lw": 1},
|
|
381
|
-
"labels": {
|
|
382
|
-
"x": "Distance to pointing direction [deg]",
|
|
383
|
-
"y": event_counts,
|
|
384
|
-
"title": "Triggered events: angular distance distribution",
|
|
385
|
-
},
|
|
386
|
-
"lines": {"x": self.limits["viewcone_radius"].value},
|
|
387
|
-
"filename": "angular_distance_distribution",
|
|
388
|
-
},
|
|
389
|
-
}
|
|
390
295
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
):
|
|
414
|
-
"""Create and save a plot with the given parameters."""
|
|
415
|
-
plot_params = plot_params or {}
|
|
416
|
-
labels = labels or {}
|
|
417
|
-
scales = scales or {}
|
|
418
|
-
lines = lines or {}
|
|
419
|
-
|
|
420
|
-
fig, ax = plt.subplots(figsize=(8, 6))
|
|
421
|
-
|
|
422
|
-
if plot_type == "histogram":
|
|
423
|
-
plt.bar(bins[:-1], data, width=np.diff(bins), **plot_params)
|
|
424
|
-
elif plot_type == "histogram2d":
|
|
425
|
-
pcm = plt.pcolormesh(
|
|
426
|
-
bins[0], bins[1], data.T, norm=LogNorm(vmin=1, vmax=data.max()), cmap="viridis"
|
|
427
|
-
)
|
|
428
|
-
plt.colorbar(pcm, label=colorbar_label)
|
|
429
|
-
|
|
430
|
-
if "x" in lines:
|
|
431
|
-
plt.axvline(lines["x"], color="r", linestyle="--", linewidth=0.5)
|
|
432
|
-
if "y" in lines:
|
|
433
|
-
plt.axhline(lines["y"], color="r", linestyle="--", linewidth=0.5)
|
|
434
|
-
if "r" in lines:
|
|
435
|
-
circle = plt.Circle(
|
|
436
|
-
(0, 0), lines["r"], color="r", fill=False, linestyle="--", linewidth=0.5
|
|
437
|
-
)
|
|
438
|
-
plt.gca().add_artist(circle)
|
|
439
|
-
|
|
440
|
-
ax.set(
|
|
441
|
-
xlabel=labels.get("x", ""),
|
|
442
|
-
ylabel=labels.get("y", ""),
|
|
443
|
-
title=labels.get("title", ""),
|
|
444
|
-
xscale=scales.get("x", "linear"),
|
|
445
|
-
yscale=scales.get("y", "linear"),
|
|
296
|
+
def compute_upper_radius_limit(histograms, loss_fraction):
|
|
297
|
+
"""
|
|
298
|
+
Compute the upper radial distance based on the event loss fraction.
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
histograms : SimtelIOEventHistograms
|
|
303
|
+
Histograms.
|
|
304
|
+
loss_fraction : float
|
|
305
|
+
Fraction of events to be lost.
|
|
306
|
+
|
|
307
|
+
Returns
|
|
308
|
+
-------
|
|
309
|
+
astropy.units.Quantity
|
|
310
|
+
Upper radial distance in m.
|
|
311
|
+
"""
|
|
312
|
+
radius_limit = (
|
|
313
|
+
_compute_limits(
|
|
314
|
+
histograms.histograms["core_distance"]["histogram"],
|
|
315
|
+
histograms.core_distance_bins,
|
|
316
|
+
loss_fraction,
|
|
317
|
+
limit_type="upper",
|
|
446
318
|
)
|
|
319
|
+
* u.m
|
|
320
|
+
)
|
|
321
|
+
return _is_close(
|
|
322
|
+
radius_limit,
|
|
323
|
+
histograms.file_info["core_scatter_max"].to("m")
|
|
324
|
+
if "core_scatter_max" in histograms.file_info
|
|
325
|
+
else None,
|
|
326
|
+
"Upper radius limit is equal to the maximum core scatter distance of",
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def compute_viewcone(histograms, loss_fraction):
|
|
331
|
+
"""
|
|
332
|
+
Compute the viewcone based on the event loss fraction.
|
|
447
333
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
plt.close()
|
|
452
|
-
else:
|
|
453
|
-
plt.tight_layout()
|
|
454
|
-
plt.show()
|
|
334
|
+
The shower IDs of triggered events are used to create a mask for the
|
|
335
|
+
azimuth and altitude of the triggered events. A mapping is created
|
|
336
|
+
between the triggered events and the simulated events using the shower IDs.
|
|
455
337
|
|
|
456
|
-
|
|
338
|
+
Parameters
|
|
339
|
+
----------
|
|
340
|
+
histograms : SimtelIOEventHistograms
|
|
341
|
+
Histograms.
|
|
342
|
+
loss_fraction : float
|
|
343
|
+
Fraction of events to be lost.
|
|
344
|
+
|
|
345
|
+
Returns
|
|
346
|
+
-------
|
|
347
|
+
astropy.units.Quantity
|
|
348
|
+
Viewcone radius in degrees.
|
|
349
|
+
"""
|
|
350
|
+
viewcone_limit = (
|
|
351
|
+
_compute_limits(
|
|
352
|
+
histograms.histograms["angular_distance"]["histogram"],
|
|
353
|
+
histograms.view_cone_bins,
|
|
354
|
+
loss_fraction,
|
|
355
|
+
limit_type="upper",
|
|
356
|
+
)
|
|
357
|
+
* u.deg
|
|
358
|
+
)
|
|
359
|
+
return _is_close(
|
|
360
|
+
viewcone_limit,
|
|
361
|
+
histograms.file_info["viewcone_max"].to("deg")
|
|
362
|
+
if "viewcone_max" in histograms.file_info
|
|
363
|
+
else None,
|
|
364
|
+
"Upper viewcone limit is equal to the maximum viewcone distance of",
|
|
365
|
+
)
|