gammasimtools 0.18.0__py3-none-any.whl → 0.19.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.19.0.dist-info}/METADATA +26 -69
- gammasimtools-0.19.0.dist-info/RECORD +393 -0
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.19.0.dist-info}/entry_points.txt +9 -2
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.19.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +16 -3
- simtools/applications/calculate_trigger_rate.py +1 -1
- 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_value_from_json_to_db.py +2 -1
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +8 -13
- simtools/applications/db_generate_compound_indexes.py +61 -0
- simtools/applications/db_get_file_from_db.py +1 -1
- 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/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_sim_telarray_histograms.py +1 -1
- 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 +379 -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 +2 -1
- 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 +29 -0
- 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 +34 -9
- simtools/db/db_handler.py +43 -37
- simtools/db/db_model_upload.py +3 -3
- simtools/dependencies.py +88 -25
- 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 +14 -7
- simtools/model/array_model.py +23 -4
- simtools/model/flasher_model.py +106 -0
- simtools/model/model_parameter.py +4 -4
- simtools/model/model_repository.py +197 -2
- simtools/model/telescope_model.py +3 -1
- simtools/production_configuration/derive_corsika_limits.py +361 -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/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 +2 -2
- 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 +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_sky_map.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +1 -1
- 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 +1 -1
- 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 +2 -2
- simtools/simtel/simtel_config_reader.py +2 -2
- simtools/simtel/simtel_config_writer.py +16 -4
- simtools/simtel/simtel_io_event_histograms.py +746 -0
- simtools/simtel/simtel_io_event_reader.py +15 -42
- simtools/simtel/simtel_io_event_writer.py +9 -9
- simtools/simtel/simtel_io_histogram.py +3 -1
- simtools/simtel/simtel_io_histograms.py +7 -3
- simtools/simtel/simtel_table_reader.py +92 -10
- 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/testing/configuration.py +24 -26
- simtools/testing/helpers.py +2 -2
- simtools/testing/log_inspector.py +50 -0
- simtools/testing/validate_output.py +87 -37
- simtools/utils/general.py +125 -255
- simtools/utils/geometry.py +36 -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_pixels.py +1 -1
- simtools/visualization/plot_tables.py +133 -37
- simtools/visualization/simtel_event_plots.py +816 -0
- simtools/visualization/visualize.py +4 -101
- gammasimtools-0.18.0.dist-info/RECORD +0 -376
- simtools/production_configuration/derive_corsika_limits_grid.py +0 -232
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.19.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.18.0.dist-info → gammasimtools-0.19.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,390 @@
|
|
|
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.model.site_model import SiteModel
|
|
13
|
+
from simtools.simtel.simtel_io_event_histograms import SimtelIOEventHistograms
|
|
11
14
|
|
|
15
|
+
_logger = logging.getLogger(__name__)
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
|
|
18
|
+
def generate_corsika_limits_grid(args_dict, db_config=None):
|
|
19
|
+
"""
|
|
20
|
+
Generate CORSIKA limits.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
args_dict : dict
|
|
25
|
+
Dictionary containing command line arguments.
|
|
26
|
+
db_config : dict, optional
|
|
27
|
+
Database configuration dictionary.
|
|
28
|
+
"""
|
|
29
|
+
if args_dict.get("array_layout_name"):
|
|
30
|
+
telescope_configs = _read_array_layouts_from_db(
|
|
31
|
+
args_dict["array_layout_name"],
|
|
32
|
+
args_dict.get("site"),
|
|
33
|
+
args_dict.get("model_version"),
|
|
34
|
+
db_config,
|
|
35
|
+
)
|
|
36
|
+
else:
|
|
37
|
+
telescope_configs = ascii_handler.collect_data_from_file(args_dict["telescope_ids"])[
|
|
38
|
+
"telescope_configs"
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
results = []
|
|
42
|
+
for array_name, telescope_ids in telescope_configs.items():
|
|
43
|
+
_logger.info(
|
|
44
|
+
f"Processing file: {args_dict['event_data_file']} with telescope config: {array_name}"
|
|
45
|
+
)
|
|
46
|
+
result = _process_file(
|
|
47
|
+
args_dict["event_data_file"],
|
|
48
|
+
array_name,
|
|
49
|
+
telescope_ids,
|
|
50
|
+
args_dict["loss_fraction"],
|
|
51
|
+
args_dict["plot_histograms"],
|
|
52
|
+
)
|
|
53
|
+
result["layout"] = array_name
|
|
54
|
+
results.append(result)
|
|
55
|
+
|
|
56
|
+
write_results(results, args_dict)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _process_file(file_path, array_name, telescope_ids, loss_fraction, plot_histograms):
|
|
14
60
|
"""
|
|
15
|
-
Compute limits for
|
|
61
|
+
Compute limits for a given event data file and telescope configuration.
|
|
16
62
|
|
|
17
|
-
|
|
63
|
+
Compute limits for energy, radial distance, and viewcone.
|
|
18
64
|
|
|
19
65
|
Parameters
|
|
20
66
|
----------
|
|
21
|
-
|
|
22
|
-
Path to the event
|
|
23
|
-
array_name : str
|
|
24
|
-
Name of the telescope array configuration
|
|
25
|
-
|
|
26
|
-
List of telescope IDs to filter the events
|
|
67
|
+
file_path : str
|
|
68
|
+
Path to the event data file.
|
|
69
|
+
array_name : str
|
|
70
|
+
Name of the telescope array configuration.
|
|
71
|
+
telescope_ids : list[int]
|
|
72
|
+
List of telescope IDs to filter the events.
|
|
73
|
+
loss_fraction : float
|
|
74
|
+
Fraction of events to be lost.
|
|
75
|
+
plot_histograms : bool
|
|
76
|
+
Whether to plot histograms.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
dict
|
|
81
|
+
Dictionary containing the computed limits and metadata.
|
|
27
82
|
"""
|
|
83
|
+
histograms = SimtelIOEventHistograms(
|
|
84
|
+
file_path, array_name=array_name, telescope_list=telescope_ids
|
|
85
|
+
)
|
|
86
|
+
histograms.fill()
|
|
87
|
+
|
|
88
|
+
limits = {
|
|
89
|
+
"lower_energy_limit": compute_lower_energy_limit(histograms, loss_fraction),
|
|
90
|
+
"upper_radius_limit": compute_upper_radius_limit(histograms, loss_fraction),
|
|
91
|
+
"viewcone_radius": compute_viewcone(histograms, loss_fraction),
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if plot_histograms:
|
|
95
|
+
histograms.plot_data(
|
|
96
|
+
output_path=io_handler.IOHandler().get_output_directory(),
|
|
97
|
+
limits=limits,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return limits
|
|
28
101
|
|
|
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
|
-
|
|
68
|
-
|
|
102
|
+
|
|
103
|
+
def write_results(results, args_dict):
|
|
104
|
+
"""
|
|
105
|
+
Write the computed limits as astropy table to file.
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
results : list[dict]
|
|
110
|
+
List of computed limits.
|
|
111
|
+
args_dict : dict
|
|
112
|
+
Dictionary containing command line arguments.
|
|
113
|
+
"""
|
|
114
|
+
table = _create_results_table(results, args_dict["loss_fraction"])
|
|
115
|
+
|
|
116
|
+
output_dir = io_handler.IOHandler().get_output_directory("corsika_limits")
|
|
117
|
+
output_file = output_dir / args_dict["output_file"]
|
|
118
|
+
|
|
119
|
+
table.write(output_file, format="ascii.ecsv", overwrite=True)
|
|
120
|
+
_logger.info(f"Results saved to {output_file}")
|
|
121
|
+
|
|
122
|
+
MetadataCollector.dump(args_dict, output_file)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _create_results_table(results, loss_fraction):
|
|
126
|
+
"""
|
|
127
|
+
Convert list of simulation results to an astropy Table with metadata.
|
|
128
|
+
|
|
129
|
+
Round values to appropriate precision and add metadata.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
results : list[dict]
|
|
134
|
+
Computed limits per file and telescope configuration.
|
|
135
|
+
loss_fraction : float
|
|
136
|
+
Fraction of lost events (added to metadata).
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
astropy.table.Table
|
|
141
|
+
Table with computed limits.
|
|
142
|
+
"""
|
|
143
|
+
cols = [
|
|
144
|
+
"primary_particle",
|
|
145
|
+
"array_name",
|
|
146
|
+
"telescope_ids",
|
|
147
|
+
"zenith",
|
|
148
|
+
"azimuth",
|
|
149
|
+
"nsb_level",
|
|
150
|
+
"lower_energy_limit",
|
|
151
|
+
"upper_radius_limit",
|
|
152
|
+
"viewcone_radius",
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
columns = {name: [] for name in cols}
|
|
156
|
+
units = {}
|
|
157
|
+
|
|
158
|
+
for res in results:
|
|
159
|
+
_process_result_row(res, cols, columns, units)
|
|
160
|
+
|
|
161
|
+
table_cols = _create_table_columns(cols, columns, units)
|
|
162
|
+
table = Table(table_cols)
|
|
163
|
+
|
|
164
|
+
table.meta.update(
|
|
165
|
+
{
|
|
166
|
+
"created": datetime.datetime.now().isoformat(),
|
|
167
|
+
"description": "Lookup table for CORSIKA limits computed from simulations.",
|
|
168
|
+
"loss_fraction": loss_fraction,
|
|
69
169
|
}
|
|
170
|
+
)
|
|
70
171
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
172
|
+
return table
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _process_result_row(res, cols, columns, units):
|
|
176
|
+
"""Process a single result row and add values to columns."""
|
|
177
|
+
for k in cols:
|
|
178
|
+
val = res.get(k, None)
|
|
179
|
+
if val is not None:
|
|
180
|
+
val = _round_value(k, val)
|
|
181
|
+
_logger.debug(f"Adding {k}: {val} to column data")
|
|
182
|
+
|
|
183
|
+
if hasattr(val, "unit"):
|
|
184
|
+
columns[k].append(val.value)
|
|
185
|
+
units[k] = val.unit
|
|
110
186
|
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
|
-
)
|
|
187
|
+
columns[k].append(val)
|
|
188
|
+
if k not in units:
|
|
189
|
+
units[k] = None
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _round_value(key, val):
|
|
193
|
+
"""Round value based on key type."""
|
|
194
|
+
if key == "lower_energy_limit":
|
|
195
|
+
return np.floor(val * 1e3) / 1e3
|
|
196
|
+
if key == "upper_radius_limit":
|
|
197
|
+
return np.ceil(val / 25) * 25
|
|
198
|
+
if key == "viewcone_radius":
|
|
199
|
+
return np.ceil(val / 0.25) * 0.25
|
|
200
|
+
return val
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _create_table_columns(cols, columns, units):
|
|
204
|
+
"""Create table columns with appropriate data types."""
|
|
205
|
+
table_cols = []
|
|
206
|
+
for k in cols:
|
|
207
|
+
col_data = columns[k]
|
|
208
|
+
if any(isinstance(v, list | tuple) for v in col_data):
|
|
209
|
+
col = Column(data=col_data, name=k, unit=units.get(k), dtype=object)
|
|
210
|
+
else:
|
|
211
|
+
col = Column(data=col_data, name=k, unit=units.get(k))
|
|
212
|
+
table_cols.append(col)
|
|
213
|
+
return table_cols
|
|
205
214
|
|
|
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
215
|
|
|
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
|
-
)
|
|
216
|
+
def _read_array_layouts_from_db(layouts, site, model_version, db_config):
|
|
217
|
+
"""
|
|
218
|
+
Read array layouts from the database.
|
|
235
219
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
)
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
layouts : list[str]
|
|
223
|
+
List of layout names to read. If "all", read all available layouts.
|
|
224
|
+
site : str
|
|
225
|
+
Site name for the array layouts.
|
|
226
|
+
model_version : str
|
|
227
|
+
Model version for the array layouts.
|
|
228
|
+
db_config : dict
|
|
229
|
+
Database configuration dictionary.
|
|
230
|
+
|
|
231
|
+
Returns
|
|
232
|
+
-------
|
|
233
|
+
dict
|
|
234
|
+
Dictionary mapping layout names to telescope IDs.
|
|
235
|
+
"""
|
|
236
|
+
site_model = SiteModel(site=site, model_version=model_version, mongo_db_config=db_config)
|
|
237
|
+
layout_names = site_model.get_list_of_array_layouts() if layouts == ["all"] else layouts
|
|
238
|
+
layout_dict = {}
|
|
239
|
+
for layout_name in layout_names:
|
|
240
|
+
layout_dict[layout_name] = site_model.get_array_elements_for_layout(layout_name)
|
|
241
|
+
return layout_dict
|
|
259
242
|
|
|
260
|
-
@property
|
|
261
|
-
def view_cone_bins(self):
|
|
262
|
-
"""Return bins for the viewcone histogram."""
|
|
263
|
-
return np.linspace(
|
|
264
|
-
self.file_info.get("viewcone_min", 0.0 * u.deg).to("deg").value,
|
|
265
|
-
self.file_info.get("viewcone_max", 20.0 * u.deg).to("deg").value,
|
|
266
|
-
100,
|
|
267
|
-
)
|
|
268
243
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
244
|
+
def _compute_limits(hist, bin_edges, loss_fraction, limit_type="lower"):
|
|
245
|
+
"""
|
|
246
|
+
Compute the limits based on the loss fraction.
|
|
247
|
+
|
|
248
|
+
Add or subtract one bin to be on the safe side of the limit.
|
|
249
|
+
|
|
250
|
+
Parameters
|
|
251
|
+
----------
|
|
252
|
+
hist : np.ndarray
|
|
253
|
+
1D histogram array.
|
|
254
|
+
bin_edges : np.ndarray
|
|
255
|
+
Array of bin edges.
|
|
256
|
+
loss_fraction : float
|
|
257
|
+
Fraction of events to be lost.
|
|
258
|
+
limit_type : str, optional
|
|
259
|
+
Type of limit ('lower' or 'upper'). Default is 'lower'.
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
float
|
|
264
|
+
Bin edge value corresponding to the threshold.
|
|
265
|
+
"""
|
|
266
|
+
total_events = np.sum(hist)
|
|
267
|
+
threshold = (1 - loss_fraction) * total_events
|
|
268
|
+
if limit_type == "upper":
|
|
269
|
+
cum = np.cumsum(hist)
|
|
270
|
+
idx = np.searchsorted(cum, threshold) + 1
|
|
271
|
+
return bin_edges[min(idx, len(bin_edges) - 1)]
|
|
272
|
+
if limit_type == "lower":
|
|
273
|
+
cum = np.cumsum(hist[::-1])
|
|
274
|
+
idx = np.searchsorted(cum, threshold) + 1
|
|
275
|
+
return bin_edges[max(len(bin_edges) - 1 - idx, 0)]
|
|
276
|
+
raise ValueError("limit_type must be 'lower' or 'upper'")
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def compute_lower_energy_limit(histograms, loss_fraction):
|
|
280
|
+
"""
|
|
281
|
+
Compute the lower energy limit in TeV based on the event loss fraction.
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
histograms : SimtelIOEventHistograms
|
|
286
|
+
Histograms.
|
|
287
|
+
loss_fraction : float
|
|
288
|
+
Fraction of events to be lost.
|
|
289
|
+
|
|
290
|
+
Returns
|
|
291
|
+
-------
|
|
292
|
+
astropy.units.Quantity
|
|
293
|
+
Lower energy limit.
|
|
294
|
+
"""
|
|
295
|
+
energy_min = (
|
|
296
|
+
_compute_limits(
|
|
297
|
+
histograms.histograms.get("energy"),
|
|
298
|
+
histograms.energy_bins,
|
|
299
|
+
loss_fraction,
|
|
300
|
+
limit_type="lower",
|
|
295
301
|
)
|
|
302
|
+
* u.TeV
|
|
303
|
+
)
|
|
296
304
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
-
}
|
|
305
|
+
return _is_close(
|
|
306
|
+
energy_min,
|
|
307
|
+
histograms.file_info["energy_min"].to("TeV")
|
|
308
|
+
if "energy_min" in histograms.file_info
|
|
309
|
+
else None,
|
|
310
|
+
"Lower energy limit is equal to the minimum energy of",
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def _is_close(value, reference, warning_text):
|
|
315
|
+
"""Check if the value is close to the reference value and log a warning if so."""
|
|
316
|
+
if reference is not None and np.isclose(value.value, reference.value, rtol=1.0e-2):
|
|
317
|
+
_logger.warning(f"{warning_text} {value}.")
|
|
318
|
+
return value
|
|
390
319
|
|
|
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"),
|
|
320
|
+
|
|
321
|
+
def compute_upper_radius_limit(histograms, loss_fraction):
|
|
322
|
+
"""
|
|
323
|
+
Compute the upper radial distance based on the event loss fraction.
|
|
324
|
+
|
|
325
|
+
Parameters
|
|
326
|
+
----------
|
|
327
|
+
histograms : SimtelIOEventHistograms
|
|
328
|
+
Histograms.
|
|
329
|
+
loss_fraction : float
|
|
330
|
+
Fraction of events to be lost.
|
|
331
|
+
|
|
332
|
+
Returns
|
|
333
|
+
-------
|
|
334
|
+
astropy.units.Quantity
|
|
335
|
+
Upper radial distance in m.
|
|
336
|
+
"""
|
|
337
|
+
radius_limit = (
|
|
338
|
+
_compute_limits(
|
|
339
|
+
histograms.histograms.get("core_distance"),
|
|
340
|
+
histograms.core_distance_bins,
|
|
341
|
+
loss_fraction,
|
|
342
|
+
limit_type="upper",
|
|
446
343
|
)
|
|
344
|
+
* u.m
|
|
345
|
+
)
|
|
346
|
+
return _is_close(
|
|
347
|
+
radius_limit,
|
|
348
|
+
histograms.file_info["core_scatter_max"].to("m")
|
|
349
|
+
if "core_scatter_max" in histograms.file_info
|
|
350
|
+
else None,
|
|
351
|
+
"Upper radius limit is equal to the maximum core scatter distance of",
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def compute_viewcone(histograms, loss_fraction):
|
|
356
|
+
"""
|
|
357
|
+
Compute the viewcone based on the event loss fraction.
|
|
447
358
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
plt.close()
|
|
452
|
-
else:
|
|
453
|
-
plt.tight_layout()
|
|
454
|
-
plt.show()
|
|
359
|
+
The shower IDs of triggered events are used to create a mask for the
|
|
360
|
+
azimuth and altitude of the triggered events. A mapping is created
|
|
361
|
+
between the triggered events and the simulated events using the shower IDs.
|
|
455
362
|
|
|
456
|
-
|
|
363
|
+
Parameters
|
|
364
|
+
----------
|
|
365
|
+
histograms : SimtelIOEventHistograms
|
|
366
|
+
Histograms.
|
|
367
|
+
loss_fraction : float
|
|
368
|
+
Fraction of events to be lost.
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
astropy.units.Quantity
|
|
373
|
+
Viewcone radius in degrees.
|
|
374
|
+
"""
|
|
375
|
+
viewcone_limit = (
|
|
376
|
+
_compute_limits(
|
|
377
|
+
histograms.histograms.get("angular_distance"),
|
|
378
|
+
histograms.view_cone_bins,
|
|
379
|
+
loss_fraction,
|
|
380
|
+
limit_type="upper",
|
|
381
|
+
)
|
|
382
|
+
* u.deg
|
|
383
|
+
)
|
|
384
|
+
return _is_close(
|
|
385
|
+
viewcone_limit,
|
|
386
|
+
histograms.file_info["viewcone_max"].to("deg")
|
|
387
|
+
if "viewcone_max" in histograms.file_info
|
|
388
|
+
else None,
|
|
389
|
+
"Upper viewcone limit is equal to the maximum viewcone distance of",
|
|
390
|
+
)
|