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
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.
|
|
@@ -340,26 +207,27 @@ def get_log_level_from_user(log_level):
|
|
|
340
207
|
return possible_levels[log_level_lower]
|
|
341
208
|
|
|
342
209
|
|
|
343
|
-
def
|
|
210
|
+
def ensure_iterable(value):
|
|
344
211
|
"""
|
|
345
|
-
|
|
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.
|
|
346
217
|
|
|
347
218
|
Parameters
|
|
348
219
|
----------
|
|
349
|
-
value
|
|
220
|
+
value: any
|
|
221
|
+
Input value to be converted to a iterable.
|
|
350
222
|
|
|
351
223
|
Returns
|
|
352
224
|
-------
|
|
353
|
-
|
|
354
|
-
|
|
225
|
+
list or tuple
|
|
226
|
+
Converted value as list or tuple.
|
|
355
227
|
"""
|
|
356
|
-
if
|
|
357
|
-
return [
|
|
358
|
-
|
|
359
|
-
try:
|
|
360
|
-
return list(value)
|
|
361
|
-
except TypeError:
|
|
362
|
-
return [value]
|
|
228
|
+
if not value:
|
|
229
|
+
return []
|
|
230
|
+
return value if isinstance(value, list | tuple) else [value]
|
|
363
231
|
|
|
364
232
|
|
|
365
233
|
def program_is_executable(program):
|
|
@@ -396,17 +264,17 @@ def _search_directory(directory, filename, rec=False):
|
|
|
396
264
|
_logger.debug(f"Directory {directory} does not exist")
|
|
397
265
|
return None
|
|
398
266
|
|
|
399
|
-
|
|
400
|
-
if
|
|
267
|
+
_file = Path(directory).joinpath(filename)
|
|
268
|
+
if _file.exists():
|
|
401
269
|
_logger.debug(f"File {filename} found in {directory}")
|
|
402
|
-
return
|
|
270
|
+
return _file
|
|
403
271
|
|
|
404
272
|
if rec:
|
|
405
273
|
for subdir in Path(directory).iterdir():
|
|
406
274
|
if subdir.is_dir():
|
|
407
|
-
|
|
408
|
-
if
|
|
409
|
-
return
|
|
275
|
+
_file = _search_directory(subdir, filename, True)
|
|
276
|
+
if _file:
|
|
277
|
+
return _file
|
|
410
278
|
return None
|
|
411
279
|
|
|
412
280
|
|
|
@@ -434,15 +302,15 @@ def find_file(name, loc):
|
|
|
434
302
|
all_locations = [loc] if not isinstance(loc, list) else loc
|
|
435
303
|
|
|
436
304
|
# Searching file locally
|
|
437
|
-
|
|
438
|
-
if
|
|
439
|
-
return
|
|
305
|
+
_file = _search_directory(".", name)
|
|
306
|
+
if _file:
|
|
307
|
+
return _file
|
|
440
308
|
|
|
441
309
|
# Searching file in given locations
|
|
442
310
|
for location in all_locations:
|
|
443
|
-
|
|
444
|
-
if
|
|
445
|
-
return
|
|
311
|
+
_file = _search_directory(location, name, True)
|
|
312
|
+
if _file:
|
|
313
|
+
return _file
|
|
446
314
|
|
|
447
315
|
msg = f"File {name} could not be found in {all_locations}"
|
|
448
316
|
_logger.error(msg)
|
|
@@ -477,6 +345,29 @@ def resolve_file_patterns(file_names):
|
|
|
477
345
|
return _files
|
|
478
346
|
|
|
479
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
|
+
|
|
480
371
|
def get_log_excerpt(log_file, n_last_lines=30):
|
|
481
372
|
"""
|
|
482
373
|
Get an excerpt from a log file, namely the n_last_lines of the file.
|
|
@@ -615,29 +506,6 @@ def remove_substring_recursively_from_dict(data_dict, substring="\n"):
|
|
|
615
506
|
return data_dict
|
|
616
507
|
|
|
617
508
|
|
|
618
|
-
def sort_arrays(*args):
|
|
619
|
-
"""Sort arrays.
|
|
620
|
-
|
|
621
|
-
Parameters
|
|
622
|
-
----------
|
|
623
|
-
*args
|
|
624
|
-
Arguments to be sorted.
|
|
625
|
-
|
|
626
|
-
Returns
|
|
627
|
-
-------
|
|
628
|
-
list
|
|
629
|
-
Sorted args.
|
|
630
|
-
"""
|
|
631
|
-
if len(args) == 0:
|
|
632
|
-
return args
|
|
633
|
-
order_array = copy.copy(args[0])
|
|
634
|
-
new_args = []
|
|
635
|
-
for arg in args:
|
|
636
|
-
_, value = zip(*sorted(zip(order_array, arg)))
|
|
637
|
-
new_args.append(list(value))
|
|
638
|
-
return new_args
|
|
639
|
-
|
|
640
|
-
|
|
641
509
|
def user_confirm():
|
|
642
510
|
"""
|
|
643
511
|
Ask the user to enter y or n (case-insensitive) on the command line.
|
|
@@ -814,123 +682,125 @@ def convert_string_to_list(data_string, is_float=True, force_comma_separation=Fa
|
|
|
814
682
|
return data_string
|
|
815
683
|
|
|
816
684
|
|
|
817
|
-
def
|
|
685
|
+
def get_structure_array_from_table(table, column_names):
|
|
818
686
|
"""
|
|
819
|
-
|
|
687
|
+
Get a structured array from an astropy table for a selected list of columns.
|
|
820
688
|
|
|
821
689
|
Parameters
|
|
822
690
|
----------
|
|
823
|
-
|
|
824
|
-
|
|
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.
|
|
825
695
|
|
|
826
696
|
Returns
|
|
827
697
|
-------
|
|
828
|
-
|
|
829
|
-
|
|
698
|
+
numpy.ndarray
|
|
699
|
+
Structured array containing the table data.
|
|
830
700
|
"""
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
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
|
+
)
|
|
836
705
|
|
|
837
706
|
|
|
838
|
-
def
|
|
707
|
+
def convert_keys_in_dict_to_lowercase(data):
|
|
839
708
|
"""
|
|
840
|
-
|
|
709
|
+
Recursively convert all dictionary keys to lowercase.
|
|
841
710
|
|
|
842
711
|
Parameters
|
|
843
712
|
----------
|
|
844
|
-
|
|
845
|
-
|
|
713
|
+
data: dict
|
|
714
|
+
Dictionary to be converted.
|
|
846
715
|
|
|
847
716
|
Returns
|
|
848
717
|
-------
|
|
849
|
-
|
|
850
|
-
|
|
718
|
+
dict
|
|
719
|
+
Dictionary with all keys converted to lowercase.
|
|
851
720
|
"""
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
return
|
|
856
|
-
|
|
857
|
-
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
|
|
858
726
|
|
|
859
727
|
|
|
860
|
-
def
|
|
728
|
+
def remove_key_from_dict(data, key_to_remove):
|
|
861
729
|
"""
|
|
862
|
-
|
|
730
|
+
Remove a specific key from a dictionary recursively.
|
|
863
731
|
|
|
864
732
|
Parameters
|
|
865
733
|
----------
|
|
866
|
-
|
|
867
|
-
|
|
734
|
+
data: dict
|
|
735
|
+
Dictionary to be processed.
|
|
736
|
+
key_to_remove: str
|
|
737
|
+
Key to be removed from the dictionary.
|
|
868
738
|
|
|
869
739
|
Returns
|
|
870
740
|
-------
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
Raises
|
|
875
|
-
------
|
|
876
|
-
UnicodeDecodeError
|
|
877
|
-
If the file cannot be decoded using UTF-8 or Latin-1.
|
|
741
|
+
dict
|
|
742
|
+
Dictionary with the specified key removed.
|
|
878
743
|
"""
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
except UnicodeDecodeError as exc:
|
|
888
|
-
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
|
+
|
|
889
752
|
|
|
890
|
-
|
|
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))
|
|
891
763
|
|
|
892
764
|
|
|
893
|
-
def
|
|
765
|
+
def find_differences_in_json_objects(obj1, obj2, path=""):
|
|
894
766
|
"""
|
|
895
|
-
|
|
767
|
+
Recursively find differences between two JSON-like objects.
|
|
896
768
|
|
|
897
769
|
Parameters
|
|
898
770
|
----------
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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.
|
|
903
777
|
|
|
904
778
|
Returns
|
|
905
779
|
-------
|
|
906
|
-
|
|
907
|
-
|
|
780
|
+
list
|
|
781
|
+
List of differences found between the two objects, with paths indicating where the
|
|
782
|
+
differences occur.
|
|
908
783
|
"""
|
|
909
|
-
|
|
910
|
-
list(zip(*[np.array(table[col]) for col in column_names if col in table.colnames])),
|
|
911
|
-
dtype=[(col, np.array(table[col]).dtype) for col in column_names if col in table.colnames],
|
|
912
|
-
)
|
|
784
|
+
diffs = []
|
|
913
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
|
|
914
789
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
Recursively convert all dictionary keys to lowercase.
|
|
790
|
+
if isinstance(obj1, dict):
|
|
791
|
+
_find_differences_dict(obj1, obj2, path, diffs)
|
|
918
792
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
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))
|
|
923
799
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
"""
|
|
929
|
-
if isinstance(data, dict):
|
|
930
|
-
return {k.lower(): convert_keys_in_dict_to_lowercase(v) for k, v in data.items()}
|
|
931
|
-
if isinstance(data, list):
|
|
932
|
-
return [convert_keys_in_dict_to_lowercase(i) for i in data]
|
|
933
|
-
return data
|
|
800
|
+
elif obj1 != obj2:
|
|
801
|
+
diffs.append(f"{path}: value changed from {obj1} to {obj2}")
|
|
802
|
+
|
|
803
|
+
return diffs
|
|
934
804
|
|
|
935
805
|
|
|
936
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
|
@@ -829,6 +829,6 @@ def file_name_with_version(file_name, suffix):
|
|
|
829
829
|
if file_name is None or suffix is None:
|
|
830
830
|
return None
|
|
831
831
|
file_name = str(file_name)
|
|
832
|
-
if
|
|
832
|
+
if re.search(r"\d{1,8}\.\d{1,8}\.\d{1,8}\Z", file_name):
|
|
833
833
|
return Path(file_name + suffix)
|
|
834
834
|
return Path(file_name).with_suffix(suffix)
|