gammasimtools 0.17.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.17.0.dist-info → gammasimtools-0.19.0.dist-info}/METADATA +27 -69
- gammasimtools-0.19.0.dist-info/RECORD +393 -0
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.19.0.dist-info}/entry_points.txt +10 -2
- {gammasimtools-0.17.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_simulation_model_from_repository_to_db.py +10 -1
- 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 +18 -12
- 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 +97 -5
- 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 +16 -18
- simtools/applications/plot_array_layout.py +3 -3
- simtools/applications/plot_simtel_events.py +379 -0
- simtools/applications/plot_tabular_data.py +21 -3
- simtools/applications/plot_tabular_data_for_model_parameter.py +104 -0
- simtools/applications/print_version.py +8 -9
- simtools/applications/production_derive_corsika_limits.py +64 -27
- 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 +31 -1
- simtools/configuration/configurator.py +4 -4
- simtools/constants.py +2 -0
- 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 +88 -24
- simtools/data_model/validate_data.py +34 -9
- simtools/db/db_handler.py +48 -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/{io_operations/io_table_handler.py → io/table_handler.py} +1 -1
- simtools/job_execution/htcondor_script_generator.py +15 -4
- simtools/layout/array_layout.py +1 -1
- simtools/layout/array_layout_utils.py +19 -8
- simtools/model/array_model.py +28 -5
- 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/resources/array-element-ids.json +126 -0
- 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 +7 -3
- 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 +42 -1
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +44 -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 +11 -1
- simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +11 -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 +32 -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 +13 -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 +11 -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 +11 -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 +13 -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 +20 -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 +11 -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 +51 -59
- 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 +16 -43
- simtools/simtel/simtel_io_event_writer.py +46 -10
- simtools/simtel/simtel_io_histogram.py +3 -1
- simtools/simtel/simtel_io_histograms.py +7 -3
- simtools/simtel/simtel_io_metadata.py +99 -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 -257
- simtools/utils/geometry.py +36 -0
- simtools/utils/names.py +72 -3
- simtools/visualization/legend_handlers.py +180 -264
- simtools/visualization/plot_array_layout.py +20 -8
- simtools/visualization/plot_pixels.py +1 -2
- simtools/visualization/plot_tables.py +202 -27
- simtools/visualization/simtel_event_plots.py +816 -0
- simtools/visualization/visualize.py +4 -101
- gammasimtools-0.17.0.dist-info/RECORD +0 -374
- simtools/production_configuration/derive_corsika_limits_grid.py +0 -189
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.19.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.17.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/{schemas → resources}/array_elements.yml +0 -0
simtools/utils/general.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"""General functions useful across different parts of the code."""
|
|
2
2
|
|
|
3
|
-
import copy
|
|
4
3
|
import datetime
|
|
5
4
|
import glob
|
|
6
|
-
import json
|
|
7
5
|
import logging
|
|
8
6
|
import os
|
|
9
|
-
import
|
|
7
|
+
import tarfile
|
|
10
8
|
import time
|
|
11
9
|
import urllib.error
|
|
12
10
|
import urllib.request
|
|
@@ -14,54 +12,21 @@ from pathlib import Path
|
|
|
14
12
|
from urllib.parse import urlparse
|
|
15
13
|
|
|
16
14
|
import numpy as np
|
|
17
|
-
import yaml
|
|
18
15
|
|
|
19
16
|
__all__ = [
|
|
20
|
-
"InvalidConfigDataError",
|
|
21
17
|
"change_dict_keys_case",
|
|
22
18
|
"clear_default_sim_telarray_cfg_directories",
|
|
23
|
-
"collect_data_from_file",
|
|
24
19
|
"collect_final_lines",
|
|
25
20
|
"collect_kwargs",
|
|
26
21
|
"get_log_excerpt",
|
|
27
22
|
"get_log_level_from_user",
|
|
28
23
|
"remove_substring_recursively_from_dict",
|
|
29
24
|
"set_default_kwargs",
|
|
30
|
-
"sort_arrays",
|
|
31
25
|
]
|
|
32
26
|
|
|
33
27
|
_logger = logging.getLogger(__name__)
|
|
34
28
|
|
|
35
29
|
|
|
36
|
-
class InvalidConfigDataError(Exception):
|
|
37
|
-
"""Exception for invalid configuration data."""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def join_url_or_path(url_or_path, *args):
|
|
41
|
-
"""
|
|
42
|
-
Join URL or path with additional subdirectories and file.
|
|
43
|
-
|
|
44
|
-
This is the equivalent to Path.join(), with extended functionality
|
|
45
|
-
working also for URLs.
|
|
46
|
-
|
|
47
|
-
Parameters
|
|
48
|
-
----------
|
|
49
|
-
url_or_path: str or Path
|
|
50
|
-
URL or path to be extended.
|
|
51
|
-
args: list
|
|
52
|
-
Additional arguments to be added to the URL or path.
|
|
53
|
-
|
|
54
|
-
Returns
|
|
55
|
-
-------
|
|
56
|
-
str or Path
|
|
57
|
-
Extended URL or path.
|
|
58
|
-
|
|
59
|
-
"""
|
|
60
|
-
if "://" in str(url_or_path):
|
|
61
|
-
return "/".join([url_or_path.rstrip("/"), *args])
|
|
62
|
-
return Path(url_or_path).joinpath(*args)
|
|
63
|
-
|
|
64
|
-
|
|
65
30
|
def is_url(url):
|
|
66
31
|
"""
|
|
67
32
|
Check if a string is a valid URL.
|
|
@@ -106,104 +71,6 @@ def url_exists(url):
|
|
|
106
71
|
return False
|
|
107
72
|
|
|
108
73
|
|
|
109
|
-
def collect_data_from_http(url):
|
|
110
|
-
"""
|
|
111
|
-
Download yaml or json file from url and return it contents as dict.
|
|
112
|
-
|
|
113
|
-
File is downloaded as a temporary file and deleted afterwards.
|
|
114
|
-
|
|
115
|
-
Parameters
|
|
116
|
-
----------
|
|
117
|
-
url: str
|
|
118
|
-
URL of the yaml/json file.
|
|
119
|
-
|
|
120
|
-
Returns
|
|
121
|
-
-------
|
|
122
|
-
dict
|
|
123
|
-
Dictionary containing the file content.
|
|
124
|
-
|
|
125
|
-
Raises
|
|
126
|
-
------
|
|
127
|
-
TypeError
|
|
128
|
-
If url is not a valid URL.
|
|
129
|
-
FileNotFoundError
|
|
130
|
-
If downloading the yaml file fails.
|
|
131
|
-
|
|
132
|
-
"""
|
|
133
|
-
try:
|
|
134
|
-
with tempfile.NamedTemporaryFile(mode="w+t") as tmp_file:
|
|
135
|
-
urllib.request.urlretrieve(url, tmp_file.name)
|
|
136
|
-
data = _collect_data_from_different_file_types(
|
|
137
|
-
tmp_file, url, Path(url).suffix.lower(), None
|
|
138
|
-
)
|
|
139
|
-
except TypeError as exc:
|
|
140
|
-
raise TypeError(f"Invalid url {url}") from exc
|
|
141
|
-
except urllib.error.HTTPError as exc:
|
|
142
|
-
raise FileNotFoundError(f"Failed to download file from {url}") from exc
|
|
143
|
-
|
|
144
|
-
_logger.debug(f"Downloaded file from {url}")
|
|
145
|
-
return data
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def collect_data_from_file(file_name, yaml_document=None):
|
|
149
|
-
"""
|
|
150
|
-
Collect data from file based on its extension.
|
|
151
|
-
|
|
152
|
-
Parameters
|
|
153
|
-
----------
|
|
154
|
-
file_name: str
|
|
155
|
-
Name of the yaml/json/ascii file.
|
|
156
|
-
yaml_document: None, int
|
|
157
|
-
Return list of yaml documents or a single document (for yaml files with several documents).
|
|
158
|
-
|
|
159
|
-
Returns
|
|
160
|
-
-------
|
|
161
|
-
data: dict or list
|
|
162
|
-
Data as dict or list.
|
|
163
|
-
"""
|
|
164
|
-
if is_url(file_name):
|
|
165
|
-
return collect_data_from_http(file_name)
|
|
166
|
-
|
|
167
|
-
suffix = Path(file_name).suffix.lower()
|
|
168
|
-
try:
|
|
169
|
-
with open(file_name, encoding="utf-8") as file:
|
|
170
|
-
return _collect_data_from_different_file_types(file, file_name, suffix, yaml_document)
|
|
171
|
-
# broad exception to catch all possible errors in reading the file
|
|
172
|
-
except Exception as exc: # pylint: disable=broad-except
|
|
173
|
-
raise type(exc)(f"Failed to read file {file_name}: {exc}") from exc
|
|
174
|
-
return None
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def _collect_data_from_different_file_types(file, file_name, suffix, yaml_document):
|
|
178
|
-
"""Collect data from different file types."""
|
|
179
|
-
if suffix == ".json":
|
|
180
|
-
return json.load(file)
|
|
181
|
-
if suffix in (".list", ".txt"):
|
|
182
|
-
return [line.strip() for line in file.readlines()]
|
|
183
|
-
if suffix in [".yml", ".yaml"]:
|
|
184
|
-
return _collect_data_from_yaml_file(file, file_name, yaml_document)
|
|
185
|
-
raise TypeError(f"File type {suffix} not supported.")
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def _collect_data_from_yaml_file(file, file_name, yaml_document):
|
|
189
|
-
"""Collect data from a yaml file (allow for multi-document yaml files)."""
|
|
190
|
-
try:
|
|
191
|
-
return yaml.safe_load(file)
|
|
192
|
-
except yaml.constructor.ConstructorError:
|
|
193
|
-
return _load_yaml_using_astropy(file)
|
|
194
|
-
except yaml.composer.ComposerError:
|
|
195
|
-
pass
|
|
196
|
-
file.seek(0)
|
|
197
|
-
if yaml_document is None:
|
|
198
|
-
return list(yaml.safe_load_all(file))
|
|
199
|
-
try:
|
|
200
|
-
return list(yaml.safe_load_all(file))[yaml_document]
|
|
201
|
-
except IndexError as exc:
|
|
202
|
-
raise InvalidConfigDataError(
|
|
203
|
-
f"YAML file {file_name} does not contain {yaml_document} documents."
|
|
204
|
-
) from exc
|
|
205
|
-
|
|
206
|
-
|
|
207
74
|
def collect_kwargs(label, in_kwargs):
|
|
208
75
|
"""
|
|
209
76
|
Collect kwargs of the type label_* and return them as a dict.
|
|
@@ -324,10 +191,8 @@ def get_log_level_from_user(log_level):
|
|
|
324
191
|
possible_levels = {
|
|
325
192
|
"info": logging.INFO,
|
|
326
193
|
"debug": logging.DEBUG,
|
|
327
|
-
"warn": logging.WARNING,
|
|
328
194
|
"warning": logging.WARNING,
|
|
329
195
|
"error": logging.ERROR,
|
|
330
|
-
"critical": logging.CRITICAL,
|
|
331
196
|
}
|
|
332
197
|
try:
|
|
333
198
|
log_level_lower = log_level.lower()
|
|
@@ -342,26 +207,27 @@ def get_log_level_from_user(log_level):
|
|
|
342
207
|
return possible_levels[log_level_lower]
|
|
343
208
|
|
|
344
209
|
|
|
345
|
-
def
|
|
210
|
+
def ensure_iterable(value):
|
|
346
211
|
"""
|
|
347
|
-
|
|
212
|
+
Return input value as iterable.
|
|
213
|
+
|
|
214
|
+
- Single values will return as a list with a single element.
|
|
215
|
+
- None values will return as empty list.
|
|
216
|
+
- Values of list or tuple type are not changed.
|
|
348
217
|
|
|
349
218
|
Parameters
|
|
350
219
|
----------
|
|
351
|
-
value
|
|
220
|
+
value: any
|
|
221
|
+
Input value to be converted to a iterable.
|
|
352
222
|
|
|
353
223
|
Returns
|
|
354
224
|
-------
|
|
355
|
-
|
|
356
|
-
|
|
225
|
+
list or tuple
|
|
226
|
+
Converted value as list or tuple.
|
|
357
227
|
"""
|
|
358
|
-
if
|
|
359
|
-
return [
|
|
360
|
-
|
|
361
|
-
try:
|
|
362
|
-
return list(value)
|
|
363
|
-
except TypeError:
|
|
364
|
-
return [value]
|
|
228
|
+
if not value:
|
|
229
|
+
return []
|
|
230
|
+
return value if isinstance(value, list | tuple) else [value]
|
|
365
231
|
|
|
366
232
|
|
|
367
233
|
def program_is_executable(program):
|
|
@@ -398,17 +264,17 @@ def _search_directory(directory, filename, rec=False):
|
|
|
398
264
|
_logger.debug(f"Directory {directory} does not exist")
|
|
399
265
|
return None
|
|
400
266
|
|
|
401
|
-
|
|
402
|
-
if
|
|
267
|
+
_file = Path(directory).joinpath(filename)
|
|
268
|
+
if _file.exists():
|
|
403
269
|
_logger.debug(f"File {filename} found in {directory}")
|
|
404
|
-
return
|
|
270
|
+
return _file
|
|
405
271
|
|
|
406
272
|
if rec:
|
|
407
273
|
for subdir in Path(directory).iterdir():
|
|
408
274
|
if subdir.is_dir():
|
|
409
|
-
|
|
410
|
-
if
|
|
411
|
-
return
|
|
275
|
+
_file = _search_directory(subdir, filename, True)
|
|
276
|
+
if _file:
|
|
277
|
+
return _file
|
|
412
278
|
return None
|
|
413
279
|
|
|
414
280
|
|
|
@@ -436,15 +302,15 @@ def find_file(name, loc):
|
|
|
436
302
|
all_locations = [loc] if not isinstance(loc, list) else loc
|
|
437
303
|
|
|
438
304
|
# Searching file locally
|
|
439
|
-
|
|
440
|
-
if
|
|
441
|
-
return
|
|
305
|
+
_file = _search_directory(".", name)
|
|
306
|
+
if _file:
|
|
307
|
+
return _file
|
|
442
308
|
|
|
443
309
|
# Searching file in given locations
|
|
444
310
|
for location in all_locations:
|
|
445
|
-
|
|
446
|
-
if
|
|
447
|
-
return
|
|
311
|
+
_file = _search_directory(location, name, True)
|
|
312
|
+
if _file:
|
|
313
|
+
return _file
|
|
448
314
|
|
|
449
315
|
msg = f"File {name} could not be found in {all_locations}"
|
|
450
316
|
_logger.error(msg)
|
|
@@ -479,6 +345,29 @@ def resolve_file_patterns(file_names):
|
|
|
479
345
|
return _files
|
|
480
346
|
|
|
481
347
|
|
|
348
|
+
def pack_tar_file(tar_file_name, file_list):
|
|
349
|
+
"""
|
|
350
|
+
Pack files into a tar.gz archive.
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
tar_file_name: str
|
|
355
|
+
Name of the output tar.gz file.
|
|
356
|
+
file_list: list
|
|
357
|
+
List of files to include in the archive.
|
|
358
|
+
"""
|
|
359
|
+
file_list = [Path(f) for f in file_list]
|
|
360
|
+
base = Path(os.path.commonpath([f.resolve() for f in file_list]))
|
|
361
|
+
base_resolved = base.resolve()
|
|
362
|
+
for f in file_list:
|
|
363
|
+
if not f.is_file() or not f.resolve().is_relative_to(base_resolved):
|
|
364
|
+
raise ValueError(f"Unsafe file path: {f}")
|
|
365
|
+
|
|
366
|
+
with tarfile.open(tar_file_name, "w:gz") as tar:
|
|
367
|
+
for file in file_list:
|
|
368
|
+
tar.add(file, arcname=file.name)
|
|
369
|
+
|
|
370
|
+
|
|
482
371
|
def get_log_excerpt(log_file, n_last_lines=30):
|
|
483
372
|
"""
|
|
484
373
|
Get an excerpt from a log file, namely the n_last_lines of the file.
|
|
@@ -617,29 +506,6 @@ def remove_substring_recursively_from_dict(data_dict, substring="\n"):
|
|
|
617
506
|
return data_dict
|
|
618
507
|
|
|
619
508
|
|
|
620
|
-
def sort_arrays(*args):
|
|
621
|
-
"""Sort arrays.
|
|
622
|
-
|
|
623
|
-
Parameters
|
|
624
|
-
----------
|
|
625
|
-
*args
|
|
626
|
-
Arguments to be sorted.
|
|
627
|
-
|
|
628
|
-
Returns
|
|
629
|
-
-------
|
|
630
|
-
list
|
|
631
|
-
Sorted args.
|
|
632
|
-
"""
|
|
633
|
-
if len(args) == 0:
|
|
634
|
-
return args
|
|
635
|
-
order_array = copy.copy(args[0])
|
|
636
|
-
new_args = []
|
|
637
|
-
for arg in args:
|
|
638
|
-
_, value = zip(*sorted(zip(order_array, arg)))
|
|
639
|
-
new_args.append(list(value))
|
|
640
|
-
return new_args
|
|
641
|
-
|
|
642
|
-
|
|
643
509
|
def user_confirm():
|
|
644
510
|
"""
|
|
645
511
|
Ask the user to enter y or n (case-insensitive) on the command line.
|
|
@@ -816,123 +682,125 @@ def convert_string_to_list(data_string, is_float=True, force_comma_separation=Fa
|
|
|
816
682
|
return data_string
|
|
817
683
|
|
|
818
684
|
|
|
819
|
-
def
|
|
685
|
+
def get_structure_array_from_table(table, column_names):
|
|
820
686
|
"""
|
|
821
|
-
|
|
687
|
+
Get a structured array from an astropy table for a selected list of columns.
|
|
822
688
|
|
|
823
689
|
Parameters
|
|
824
690
|
----------
|
|
825
|
-
|
|
826
|
-
|
|
691
|
+
table: astropy.table.Table
|
|
692
|
+
Table to be converted.
|
|
693
|
+
column_names: list
|
|
694
|
+
List of column names to be included in the structured array.
|
|
827
695
|
|
|
828
696
|
Returns
|
|
829
697
|
-------
|
|
830
|
-
|
|
831
|
-
|
|
698
|
+
numpy.ndarray
|
|
699
|
+
Structured array containing the table data.
|
|
832
700
|
"""
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
return astropy_yaml.load(file)
|
|
701
|
+
return np.array(
|
|
702
|
+
list(zip(*[np.array(table[col]) for col in column_names if col in table.colnames])),
|
|
703
|
+
dtype=[(col, np.array(table[col]).dtype) for col in column_names if col in table.colnames],
|
|
704
|
+
)
|
|
838
705
|
|
|
839
706
|
|
|
840
|
-
def
|
|
707
|
+
def convert_keys_in_dict_to_lowercase(data):
|
|
841
708
|
"""
|
|
842
|
-
|
|
709
|
+
Recursively convert all dictionary keys to lowercase.
|
|
843
710
|
|
|
844
711
|
Parameters
|
|
845
712
|
----------
|
|
846
|
-
|
|
847
|
-
|
|
713
|
+
data: dict
|
|
714
|
+
Dictionary to be converted.
|
|
848
715
|
|
|
849
716
|
Returns
|
|
850
717
|
-------
|
|
851
|
-
|
|
852
|
-
|
|
718
|
+
dict
|
|
719
|
+
Dictionary with all keys converted to lowercase.
|
|
853
720
|
"""
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
return
|
|
858
|
-
|
|
859
|
-
return False
|
|
721
|
+
if isinstance(data, dict):
|
|
722
|
+
return {k.lower(): convert_keys_in_dict_to_lowercase(v) for k, v in data.items()}
|
|
723
|
+
if isinstance(data, list):
|
|
724
|
+
return [convert_keys_in_dict_to_lowercase(i) for i in data]
|
|
725
|
+
return data
|
|
860
726
|
|
|
861
727
|
|
|
862
|
-
def
|
|
728
|
+
def remove_key_from_dict(data, key_to_remove):
|
|
863
729
|
"""
|
|
864
|
-
|
|
730
|
+
Remove a specific key from a dictionary recursively.
|
|
865
731
|
|
|
866
732
|
Parameters
|
|
867
733
|
----------
|
|
868
|
-
|
|
869
|
-
|
|
734
|
+
data: dict
|
|
735
|
+
Dictionary to be processed.
|
|
736
|
+
key_to_remove: str
|
|
737
|
+
Key to be removed from the dictionary.
|
|
870
738
|
|
|
871
739
|
Returns
|
|
872
740
|
-------
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
Raises
|
|
877
|
-
------
|
|
878
|
-
UnicodeDecodeError
|
|
879
|
-
If the file cannot be decoded using UTF-8 or Latin-1.
|
|
741
|
+
dict
|
|
742
|
+
Dictionary with the specified key removed.
|
|
880
743
|
"""
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
except UnicodeDecodeError as exc:
|
|
890
|
-
raise UnicodeDecodeError("Unable to decode file using UTF-8 or Latin-1.") from exc
|
|
744
|
+
if isinstance(data, dict):
|
|
745
|
+
return {
|
|
746
|
+
k: remove_key_from_dict(v, key_to_remove) for k, v in data.items() if k != key_to_remove
|
|
747
|
+
}
|
|
748
|
+
if isinstance(data, list):
|
|
749
|
+
return [remove_key_from_dict(i, key_to_remove) for i in data]
|
|
750
|
+
return data
|
|
751
|
+
|
|
891
752
|
|
|
892
|
-
|
|
753
|
+
def _find_differences_dict(obj1, obj2, path, diffs):
|
|
754
|
+
"""Recursively find differences between two dictionaries."""
|
|
755
|
+
for key in sorted(set(obj1) | set(obj2)):
|
|
756
|
+
subpath = f"{path}['{key}']" if path else f"['{key}']"
|
|
757
|
+
if key not in obj1:
|
|
758
|
+
diffs.append(f"{subpath}: added in second object")
|
|
759
|
+
elif key not in obj2:
|
|
760
|
+
diffs.append(f"{subpath}: removed in second object")
|
|
761
|
+
else:
|
|
762
|
+
diffs.extend(find_differences_in_json_objects(obj1[key], obj2[key], subpath))
|
|
893
763
|
|
|
894
764
|
|
|
895
|
-
def
|
|
765
|
+
def find_differences_in_json_objects(obj1, obj2, path=""):
|
|
896
766
|
"""
|
|
897
|
-
|
|
767
|
+
Recursively find differences between two JSON-like objects.
|
|
898
768
|
|
|
899
769
|
Parameters
|
|
900
770
|
----------
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
771
|
+
obj1: dict, list, or any
|
|
772
|
+
First object to compare.
|
|
773
|
+
obj2: dict, list, or any
|
|
774
|
+
Second object to compare.
|
|
775
|
+
path: str
|
|
776
|
+
Path to the current object in the JSON structure, used for reporting differences.
|
|
905
777
|
|
|
906
778
|
Returns
|
|
907
779
|
-------
|
|
908
|
-
|
|
909
|
-
|
|
780
|
+
list
|
|
781
|
+
List of differences found between the two objects, with paths indicating where the
|
|
782
|
+
differences occur.
|
|
910
783
|
"""
|
|
911
|
-
|
|
912
|
-
list(zip(*[np.array(table[col]) for col in column_names if col in table.colnames])),
|
|
913
|
-
dtype=[(col, np.array(table[col]).dtype) for col in column_names if col in table.colnames],
|
|
914
|
-
)
|
|
784
|
+
diffs = []
|
|
915
785
|
|
|
786
|
+
if not isinstance(obj1, type(obj2)):
|
|
787
|
+
diffs.append(f"{path}: type changed from {type(obj1).__name__} to {type(obj2).__name__}")
|
|
788
|
+
return diffs
|
|
916
789
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
Recursively convert all dictionary keys to lowercase.
|
|
790
|
+
if isinstance(obj1, dict):
|
|
791
|
+
_find_differences_dict(obj1, obj2, path, diffs)
|
|
920
792
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
793
|
+
elif isinstance(obj1, list):
|
|
794
|
+
if len(obj1) != len(obj2):
|
|
795
|
+
diffs.append(f"{path}: list length changed from {len(obj1)} to {len(obj2)}")
|
|
796
|
+
for i, (a, b) in enumerate(zip(obj1, obj2)):
|
|
797
|
+
subpath = f"{path}[{i}]" if path else f"[{i}]"
|
|
798
|
+
diffs.extend(find_differences_in_json_objects(a, b, subpath))
|
|
925
799
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
"""
|
|
931
|
-
if isinstance(data, dict):
|
|
932
|
-
return {k.lower(): convert_keys_in_dict_to_lowercase(v) for k, v in data.items()}
|
|
933
|
-
if isinstance(data, list):
|
|
934
|
-
return [convert_keys_in_dict_to_lowercase(i) for i in data]
|
|
935
|
-
return data
|
|
800
|
+
elif obj1 != obj2:
|
|
801
|
+
diffs.append(f"{path}: value changed from {obj1} to {obj2}")
|
|
802
|
+
|
|
803
|
+
return diffs
|
|
936
804
|
|
|
937
805
|
|
|
938
806
|
def clear_default_sim_telarray_cfg_directories(command):
|
simtools/utils/geometry.py
CHANGED
|
@@ -180,3 +180,39 @@ def calculate_circular_mean(angles):
|
|
|
180
180
|
sin_sum = np.sum(np.sin(angles))
|
|
181
181
|
cos_sum = np.sum(np.cos(angles))
|
|
182
182
|
return np.arctan2(sin_sum, cos_sum)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def transform_ground_to_shower_coordinates(x_ground, y_ground, z_ground, azimuth, altitude):
|
|
186
|
+
"""
|
|
187
|
+
Transform ground to shower coordinates.
|
|
188
|
+
|
|
189
|
+
Assume ground to be of type 'North-West-Up' (NWU) coordinates.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
x_ground: numpy.array
|
|
194
|
+
Ground x coordinate.
|
|
195
|
+
y_ground: numpy.array
|
|
196
|
+
Ground y coordinate.
|
|
197
|
+
z_ground: numpy.array
|
|
198
|
+
Ground z coordinate.
|
|
199
|
+
azimuth: numpy.array
|
|
200
|
+
Azimuth angle of the shower (in radians).
|
|
201
|
+
altitude: numpy.array
|
|
202
|
+
Altitude angle of the shower (in radians).
|
|
203
|
+
|
|
204
|
+
Returns
|
|
205
|
+
-------
|
|
206
|
+
tuple
|
|
207
|
+
Transformed shower coordinates (x', y', z').
|
|
208
|
+
"""
|
|
209
|
+
x, y, z, az, alt = np.broadcast_arrays(x_ground, y_ground, z_ground, azimuth, altitude)
|
|
210
|
+
|
|
211
|
+
ca, sa = np.cos(az), np.sin(az)
|
|
212
|
+
cz, sz = np.sin(alt), np.cos(alt)
|
|
213
|
+
|
|
214
|
+
x_s = ca * cz * x - sa * y + ca * sz * z
|
|
215
|
+
y_s = sa * cz * x + ca * y + sa * sz * z
|
|
216
|
+
z_s = -sz * x + cz * z
|
|
217
|
+
|
|
218
|
+
return x_s, y_s, z_s
|
simtools/utils/names.py
CHANGED
|
@@ -12,6 +12,7 @@ Naming in simtools:
|
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
+
import json
|
|
15
16
|
import logging
|
|
16
17
|
import re
|
|
17
18
|
from functools import cache
|
|
@@ -22,7 +23,7 @@ import yaml
|
|
|
22
23
|
from simtools.constants import (
|
|
23
24
|
MODEL_PARAMETER_DESCRIPTION_METASCHEMA,
|
|
24
25
|
MODEL_PARAMETER_SCHEMA_PATH,
|
|
25
|
-
|
|
26
|
+
RESOURCE_PATH,
|
|
26
27
|
)
|
|
27
28
|
|
|
28
29
|
_logger = logging.getLogger(__name__)
|
|
@@ -59,10 +60,30 @@ def array_elements():
|
|
|
59
60
|
dict
|
|
60
61
|
Array elements.
|
|
61
62
|
"""
|
|
62
|
-
|
|
63
|
+
# for efficiency reason, no functions from simtools.utils.general are used here
|
|
64
|
+
with open(Path(RESOURCE_PATH) / "array_elements.yml", encoding="utf-8") as file:
|
|
63
65
|
return yaml.safe_load(file)["data"]
|
|
64
66
|
|
|
65
67
|
|
|
68
|
+
@cache
|
|
69
|
+
def array_element_common_identifiers():
|
|
70
|
+
"""
|
|
71
|
+
Get array element IDs from CTAO common identifier.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
dict, dict
|
|
76
|
+
Dictionary mapping array element names to their IDs and vice versa.
|
|
77
|
+
"""
|
|
78
|
+
# for efficiency reason, no functions from simtools.utils.general are used here
|
|
79
|
+
id_to_name = {}
|
|
80
|
+
with open(Path(RESOURCE_PATH) / "array-element-ids.json", encoding="utf-8") as file:
|
|
81
|
+
data = json.load(file)
|
|
82
|
+
id_to_name = {e["id"]: e["name"] for e in data["array_elements"]}
|
|
83
|
+
name_to_id = {e["name"]: e["id"] for e in data["array_elements"]}
|
|
84
|
+
return id_to_name, name_to_id
|
|
85
|
+
|
|
86
|
+
|
|
66
87
|
@cache
|
|
67
88
|
def simulation_software():
|
|
68
89
|
"""
|
|
@@ -415,6 +436,54 @@ def get_array_element_id_from_name(array_element_name):
|
|
|
415
436
|
raise ValueError(f"Invalid name {array_element_name}") from exc
|
|
416
437
|
|
|
417
438
|
|
|
439
|
+
def get_common_identifier_from_array_element_name(array_element_name, default_return=None):
|
|
440
|
+
"""
|
|
441
|
+
Get numerical common identifier from array element name as used by CTAO.
|
|
442
|
+
|
|
443
|
+
Common identifiers are numerical IDs used by the CTAO ACADA and DPPS systems.
|
|
444
|
+
|
|
445
|
+
Parameters
|
|
446
|
+
----------
|
|
447
|
+
array_element_name: str
|
|
448
|
+
Array element name (e.g. LSTN-01)
|
|
449
|
+
|
|
450
|
+
Returns
|
|
451
|
+
-------
|
|
452
|
+
int
|
|
453
|
+
Common identifier.
|
|
454
|
+
"""
|
|
455
|
+
_, name_to_id = array_element_common_identifiers()
|
|
456
|
+
try:
|
|
457
|
+
return name_to_id[array_element_name]
|
|
458
|
+
except KeyError as exc:
|
|
459
|
+
if default_return is not None:
|
|
460
|
+
return default_return
|
|
461
|
+
raise ValueError(f"Unknown array element name {array_element_name}") from exc
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def get_array_element_name_from_common_identifier(common_identifier):
|
|
465
|
+
"""
|
|
466
|
+
Get array element name from common identifier as used by CTAO.
|
|
467
|
+
|
|
468
|
+
Common identifiers are numerical IDs used by the CTAO ACADA and DPPS systems.
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
common_identifier: int
|
|
473
|
+
Common identifier.
|
|
474
|
+
|
|
475
|
+
Returns
|
|
476
|
+
-------
|
|
477
|
+
str
|
|
478
|
+
Array element name.
|
|
479
|
+
"""
|
|
480
|
+
id_to_name, _ = array_element_common_identifiers()
|
|
481
|
+
try:
|
|
482
|
+
return id_to_name[common_identifier]
|
|
483
|
+
except KeyError as exc:
|
|
484
|
+
raise ValueError(f"Unknown common identifier {common_identifier}") from exc
|
|
485
|
+
|
|
486
|
+
|
|
418
487
|
def get_list_of_array_element_types(
|
|
419
488
|
array_element_class="telescopes", site=None, observatory="CTAO"
|
|
420
489
|
):
|
|
@@ -760,6 +829,6 @@ def file_name_with_version(file_name, suffix):
|
|
|
760
829
|
if file_name is None or suffix is None:
|
|
761
830
|
return None
|
|
762
831
|
file_name = str(file_name)
|
|
763
|
-
if
|
|
832
|
+
if re.search(r"\d{1,8}\.\d{1,8}\.\d{1,8}\Z", file_name):
|
|
764
833
|
return Path(file_name + suffix)
|
|
765
834
|
return Path(file_name).with_suffix(suffix)
|