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
|
@@ -11,13 +11,11 @@ import logging
|
|
|
11
11
|
import uuid
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
|
-
import yaml
|
|
15
|
-
|
|
16
14
|
import simtools.utils.general as gen
|
|
17
15
|
import simtools.version
|
|
18
16
|
from simtools.constants import METADATA_JSON_SCHEMA
|
|
19
17
|
from simtools.data_model import metadata_model, schema
|
|
20
|
-
from simtools.
|
|
18
|
+
from simtools.io import ascii_handler, io_handler
|
|
21
19
|
from simtools.utils import names
|
|
22
20
|
|
|
23
21
|
__all__ = ["MetadataCollector"]
|
|
@@ -41,33 +39,36 @@ class MetadataCollector:
|
|
|
41
39
|
Command line parameters
|
|
42
40
|
metadata_file_name: str
|
|
43
41
|
Name of metadata file (only required when args_dict is None)
|
|
44
|
-
|
|
45
|
-
Name of
|
|
42
|
+
model_parameter_name: str
|
|
43
|
+
Name of model parameter
|
|
46
44
|
observatory: str
|
|
47
45
|
Name of observatory (default: "cta")
|
|
48
46
|
clean_meta: bool
|
|
49
47
|
Clean metadata from None values and empty lists (default: True)
|
|
48
|
+
schema_version: str
|
|
49
|
+
Version of the metadata schema to use (default: 'latest')
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
52
|
def __init__(
|
|
53
53
|
self,
|
|
54
|
-
args_dict,
|
|
54
|
+
args_dict=None,
|
|
55
55
|
metadata_file_name=None,
|
|
56
|
-
|
|
56
|
+
model_parameter_name=None,
|
|
57
57
|
observatory="cta",
|
|
58
58
|
clean_meta=True,
|
|
59
|
+
schema_version="latest",
|
|
59
60
|
):
|
|
60
61
|
"""Initialize metadata collector."""
|
|
61
62
|
self._logger = logging.getLogger(__name__)
|
|
62
63
|
self.observatory = observatory
|
|
63
64
|
self.io_handler = io_handler.IOHandler()
|
|
64
65
|
|
|
65
|
-
self.args_dict = args_dict
|
|
66
|
-
self.
|
|
66
|
+
self.args_dict = args_dict or {}
|
|
67
|
+
self.model_parameter_name = model_parameter_name
|
|
67
68
|
self.schema_file = None
|
|
68
69
|
self.schema_dict = None
|
|
69
|
-
self.top_level_meta =
|
|
70
|
-
|
|
70
|
+
self.top_level_meta = metadata_model.get_default_metadata_dict(
|
|
71
|
+
schema_version=schema_version
|
|
71
72
|
)
|
|
72
73
|
self.input_metadata = self._read_input_metadata_from_file(metadata_file_name)
|
|
73
74
|
self.collect_meta_data()
|
|
@@ -119,7 +120,7 @@ class MetadataCollector:
|
|
|
119
120
|
collector = MetadataCollector(args_dict)
|
|
120
121
|
collector.write(output_file, add_activity_name=add_activity_name)
|
|
121
122
|
|
|
122
|
-
def write(self, yml_file=None, keys_lower_case=
|
|
123
|
+
def write(self, yml_file=None, keys_lower_case=True, add_activity_name=False):
|
|
123
124
|
"""
|
|
124
125
|
Write toplevel metadata to file (yaml file format).
|
|
125
126
|
|
|
@@ -155,16 +156,13 @@ class MetadataCollector:
|
|
|
155
156
|
|
|
156
157
|
try:
|
|
157
158
|
yml_file = names.file_name_with_version(yml_file, suffix)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
gen.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
sort_keys=False,
|
|
166
|
-
explicit_start=True,
|
|
167
|
-
)
|
|
159
|
+
ascii_handler.write_data_to_file(
|
|
160
|
+
data=gen.change_dict_keys_case(
|
|
161
|
+
gen.remove_substring_recursively_from_dict(metadata, substring="\n"),
|
|
162
|
+
keys_lower_case,
|
|
163
|
+
),
|
|
164
|
+
output_file=yml_file,
|
|
165
|
+
)
|
|
168
166
|
self._logger.info(f"Writing metadata to {yml_file}")
|
|
169
167
|
return yml_file
|
|
170
168
|
except FileNotFoundError as exc:
|
|
@@ -198,10 +196,10 @@ class MetadataCollector:
|
|
|
198
196
|
except KeyError:
|
|
199
197
|
pass
|
|
200
198
|
|
|
201
|
-
# from
|
|
202
|
-
if self.
|
|
203
|
-
self._logger.debug(f"Schema file from data model name: {self.
|
|
204
|
-
return str(schema.get_model_parameter_schema_file(self.
|
|
199
|
+
# from model parameter name
|
|
200
|
+
if self.model_parameter_name:
|
|
201
|
+
self._logger.debug(f"Schema file from data model name: {self.model_parameter_name}")
|
|
202
|
+
return str(schema.get_model_parameter_schema_file(self.model_parameter_name))
|
|
205
203
|
|
|
206
204
|
# from first entry in input metadata (least preferred)
|
|
207
205
|
try:
|
|
@@ -225,7 +223,7 @@ class MetadataCollector:
|
|
|
225
223
|
|
|
226
224
|
"""
|
|
227
225
|
try:
|
|
228
|
-
return
|
|
226
|
+
return ascii_handler.collect_data_from_file(file_name=self.schema_file)
|
|
229
227
|
except TypeError:
|
|
230
228
|
self._logger.debug(f"No valid schema file provided ({self.schema_file}).")
|
|
231
229
|
return {}
|
|
@@ -334,7 +332,7 @@ class MetadataCollector:
|
|
|
334
332
|
|
|
335
333
|
Raises
|
|
336
334
|
------
|
|
337
|
-
|
|
335
|
+
ValueError:
|
|
338
336
|
if metadata cannot be read from file.
|
|
339
337
|
KeyError:
|
|
340
338
|
if metadata does not exist
|
|
@@ -365,7 +363,7 @@ class MetadataCollector:
|
|
|
365
363
|
)
|
|
366
364
|
continue
|
|
367
365
|
else:
|
|
368
|
-
raise
|
|
366
|
+
raise ValueError(f"Unknown metadata file format: {metadata_file}")
|
|
369
367
|
|
|
370
368
|
schema.validate_dict_using_schema(_input_metadata, schema_file=METADATA_JSON_SCHEMA)
|
|
371
369
|
metadata.append(gen.change_dict_keys_case(_input_metadata, lower_case=True))
|
|
@@ -391,16 +389,14 @@ class MetadataCollector:
|
|
|
391
389
|
def _read_input_metadata_from_yml_or_json(self, metadata_file_name):
|
|
392
390
|
"""Read input metadata from yml or json file."""
|
|
393
391
|
try:
|
|
394
|
-
_input_metadata =
|
|
392
|
+
_input_metadata = ascii_handler.collect_data_from_file(file_name=metadata_file_name)
|
|
395
393
|
_json_type_metadata = {"Metadata", "metadata", "METADATA"}.intersection(_input_metadata)
|
|
396
394
|
if len(_json_type_metadata) == 1:
|
|
397
395
|
_input_metadata = _input_metadata[_json_type_metadata.pop()]
|
|
398
396
|
if len(_json_type_metadata) > 1:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
self._logger.error("Failed reading metadata from %s", metadata_file_name)
|
|
403
|
-
raise exc
|
|
397
|
+
raise ValueError(f"More than one metadata entry found in {metadata_file_name}")
|
|
398
|
+
except FileNotFoundError as exc:
|
|
399
|
+
raise FileNotFoundError(f"Failed reading metadata from {metadata_file_name}") from exc
|
|
404
400
|
return _input_metadata
|
|
405
401
|
|
|
406
402
|
def _fill_product_meta(self, product_dict):
|
|
@@ -443,7 +439,7 @@ class MetadataCollector:
|
|
|
443
439
|
or self.args_dict.get("metadata_product_data_name")
|
|
444
440
|
or "undefined_model_name"
|
|
445
441
|
)
|
|
446
|
-
product_dict["data"]["model"]["version"] = self.schema_dict.get("
|
|
442
|
+
product_dict["data"]["model"]["version"] = self.schema_dict.get("schema_version", "0.0.0")
|
|
447
443
|
product_dict["data"]["model"]["type"] = self.schema_dict.get("meta_schema", None)
|
|
448
444
|
product_dict["data"]["model"]["url"] = self.schema_file or self.args_dict.get(
|
|
449
445
|
"metadata_product_data_url"
|
|
@@ -11,11 +11,14 @@ Follows CTAO top-level data model definition.
|
|
|
11
11
|
import logging
|
|
12
12
|
|
|
13
13
|
import simtools.data_model.schema
|
|
14
|
+
import simtools.utils.general as gen
|
|
14
15
|
|
|
15
16
|
_logger = logging.getLogger(__name__)
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def get_default_metadata_dict(
|
|
19
|
+
def get_default_metadata_dict(
|
|
20
|
+
schema_file=None, observatory="CTA", schema_version="latest", lower_case=True
|
|
21
|
+
):
|
|
19
22
|
"""
|
|
20
23
|
Return metadata schema with default values.
|
|
21
24
|
|
|
@@ -27,6 +30,10 @@ def get_default_metadata_dict(schema_file=None, observatory="CTA"):
|
|
|
27
30
|
Schema file (jsonschema format) used for validation
|
|
28
31
|
observatory: str
|
|
29
32
|
Observatory name
|
|
33
|
+
schema_version: str, optional
|
|
34
|
+
Version of the schema to use. If not provided, the latest version is used.
|
|
35
|
+
lower_case: bool, optional
|
|
36
|
+
If True, all keys in the returned dictionary will be converted to lower case.
|
|
30
37
|
|
|
31
38
|
Returns
|
|
32
39
|
-------
|
|
@@ -35,8 +42,11 @@ def get_default_metadata_dict(schema_file=None, observatory="CTA"):
|
|
|
35
42
|
|
|
36
43
|
|
|
37
44
|
"""
|
|
38
|
-
schema = simtools.data_model.schema.load_schema(schema_file)
|
|
39
|
-
return
|
|
45
|
+
schema = simtools.data_model.schema.load_schema(schema_file, schema_version=schema_version)
|
|
46
|
+
return gen.change_dict_keys_case(
|
|
47
|
+
data_dict=_fill_defaults(schema["definitions"], observatory.lower()),
|
|
48
|
+
lower_case=lower_case,
|
|
49
|
+
)
|
|
40
50
|
|
|
41
51
|
|
|
42
52
|
def _resolve_references(yaml_data, observatory="CTA"):
|
|
@@ -62,7 +72,7 @@ def _resolve_references(yaml_data, observatory="CTA"):
|
|
|
62
72
|
parts = ref_path.split("/")
|
|
63
73
|
ref_data = yaml_data
|
|
64
74
|
for part in parts:
|
|
65
|
-
if part in ("definitions", observatory):
|
|
75
|
+
if part in ("definitions", observatory.lower()):
|
|
66
76
|
continue
|
|
67
77
|
ref_data = ref_data.get(part, {})
|
|
68
78
|
return ref_data
|
|
@@ -123,7 +133,7 @@ def _fill_defaults_recursive(sub_schema, current_dict):
|
|
|
123
133
|
Current dictionary to fill with default values.
|
|
124
134
|
"""
|
|
125
135
|
if "properties" not in sub_schema:
|
|
126
|
-
|
|
136
|
+
raise KeyError("Missing 'properties' key in schema.")
|
|
127
137
|
|
|
128
138
|
for prop, prop_schema in sub_schema["properties"].items():
|
|
129
139
|
_process_property(prop, prop_schema, current_dict)
|
|
@@ -152,10 +162,3 @@ def _process_property(prop, prop_schema, current_dict):
|
|
|
152
162
|
current_dict[prop] = [{}]
|
|
153
163
|
if "items" in prop_schema and isinstance(prop_schema["items"], dict):
|
|
154
164
|
_fill_defaults_recursive(prop_schema["items"], current_dict[prop][0])
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def _raise_missing_properties_error():
|
|
158
|
-
"""Raise an error when the 'properties' key is missing in the schema."""
|
|
159
|
-
msg = "Missing 'properties' key in schema."
|
|
160
|
-
_logger.error(msg)
|
|
161
|
-
raise KeyError(msg)
|
|
@@ -1,40 +1,20 @@
|
|
|
1
1
|
"""Model data writer module."""
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
import logging
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
|
|
7
|
-
import astropy.units as u
|
|
8
|
-
import numpy as np
|
|
9
6
|
from astropy.io.registry.base import IORegistryError
|
|
10
7
|
|
|
11
8
|
import simtools.utils.general as gen
|
|
12
9
|
from simtools.data_model import schema, validate_data
|
|
13
10
|
from simtools.data_model.metadata_collector import MetadataCollector
|
|
14
11
|
from simtools.db import db_handler
|
|
15
|
-
from simtools.
|
|
12
|
+
from simtools.io import ascii_handler, io_handler
|
|
16
13
|
from simtools.utils import names, value_conversion
|
|
17
14
|
|
|
18
15
|
__all__ = ["ModelDataWriter"]
|
|
19
16
|
|
|
20
17
|
|
|
21
|
-
class JsonNumpyEncoder(json.JSONEncoder):
|
|
22
|
-
"""Convert numpy to python types as accepted by json.dump."""
|
|
23
|
-
|
|
24
|
-
def default(self, o):
|
|
25
|
-
if isinstance(o, np.floating):
|
|
26
|
-
return float(o)
|
|
27
|
-
if isinstance(o, np.integer):
|
|
28
|
-
return int(o)
|
|
29
|
-
if isinstance(o, np.ndarray):
|
|
30
|
-
return o.tolist()
|
|
31
|
-
if isinstance(o, u.core.CompositeUnit | u.core.IrreducibleUnit | u.core.Unit):
|
|
32
|
-
return str(o) if o != u.dimensionless_unscaled else None
|
|
33
|
-
if np.issubdtype(type(o), np.bool_):
|
|
34
|
-
return bool(o)
|
|
35
|
-
return super().default(o)
|
|
36
|
-
|
|
37
|
-
|
|
38
18
|
class ModelDataWriter:
|
|
39
19
|
"""
|
|
40
20
|
Writer for simulation model data and metadata.
|
|
@@ -254,7 +234,7 @@ class ModelDataWriter:
|
|
|
254
234
|
"""
|
|
255
235
|
self._logger.debug(f"Getting validated parameter dictionary for {instrument}")
|
|
256
236
|
schema_file = schema.get_model_parameter_schema_file(parameter_name)
|
|
257
|
-
self.schema_dict =
|
|
237
|
+
self.schema_dict = ascii_handler.collect_data_from_file(schema_file)
|
|
258
238
|
|
|
259
239
|
value, unit = value_conversion.split_value_and_unit(value)
|
|
260
240
|
|
|
@@ -381,7 +361,7 @@ class ModelDataWriter:
|
|
|
381
361
|
|
|
382
362
|
if metadata is not None:
|
|
383
363
|
product_data.meta.update(
|
|
384
|
-
gen.change_dict_keys_case(metadata.get_top_level_metadata(),
|
|
364
|
+
gen.change_dict_keys_case(metadata.get_top_level_metadata(), True)
|
|
385
365
|
)
|
|
386
366
|
|
|
387
367
|
self._logger.info(f"Writing data to {self.product_data_file}")
|
|
@@ -415,15 +395,13 @@ class ModelDataWriter:
|
|
|
415
395
|
if data writing was not successful.
|
|
416
396
|
"""
|
|
417
397
|
data_dict = ModelDataWriter.prepare_data_dict_for_writing(data_dict)
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
f"Error writing model data to {self.io_handler.get_output_file(file_name)}"
|
|
426
|
-
) from exc
|
|
398
|
+
self._logger.info(f"Writing data to {self.io_handler.get_output_file(file_name)}")
|
|
399
|
+
ascii_handler.write_data_to_file(
|
|
400
|
+
data=data_dict,
|
|
401
|
+
output_file=self.io_handler.get_output_file(file_name),
|
|
402
|
+
sort_keys=False,
|
|
403
|
+
numpy_types=True,
|
|
404
|
+
)
|
|
427
405
|
|
|
428
406
|
@staticmethod
|
|
429
407
|
def prepare_data_dict_for_writing(data_dict):
|
|
@@ -432,6 +410,7 @@ class ModelDataWriter:
|
|
|
432
410
|
|
|
433
411
|
Ensure sim_telarray style lists as strings 'type' and 'unit' entries.
|
|
434
412
|
Replace "None" with "null" for unit field.
|
|
413
|
+
Replace list of equal units with single unit string.
|
|
435
414
|
|
|
436
415
|
Parameters
|
|
437
416
|
----------
|
|
@@ -452,6 +431,8 @@ class ModelDataWriter:
|
|
|
452
431
|
unit.replace("None", "null") if isinstance(unit, str) else unit
|
|
453
432
|
for unit in data_dict["unit"]
|
|
454
433
|
]
|
|
434
|
+
if all(u == data_dict["unit"][0] for u in data_dict["unit"]):
|
|
435
|
+
data_dict["unit"] = data_dict["unit"][0]
|
|
455
436
|
except KeyError:
|
|
456
437
|
pass
|
|
457
438
|
return data_dict
|
simtools/data_model/schema.py
CHANGED
|
@@ -14,6 +14,7 @@ from simtools.constants import (
|
|
|
14
14
|
SCHEMA_PATH,
|
|
15
15
|
)
|
|
16
16
|
from simtools.data_model import format_checkers
|
|
17
|
+
from simtools.io import ascii_handler
|
|
17
18
|
from simtools.utils import names
|
|
18
19
|
|
|
19
20
|
_logger = logging.getLogger(__name__)
|
|
@@ -37,7 +38,7 @@ def get_model_parameter_schema_files(schema_directory=MODEL_PARAMETER_SCHEMA_PAT
|
|
|
37
38
|
parameters = []
|
|
38
39
|
for schema_file in schema_files:
|
|
39
40
|
# reading parameter 'name' only - first document in schema file should be ok
|
|
40
|
-
schema_dict =
|
|
41
|
+
schema_dict = ascii_handler.collect_data_from_file(file_name=schema_file, yaml_document=0)
|
|
41
42
|
parameters.append(schema_dict.get("name"))
|
|
42
43
|
return parameters, schema_files
|
|
43
44
|
|
|
@@ -80,12 +81,12 @@ def get_model_parameter_schema_version(schema_version=None):
|
|
|
80
81
|
Schema version.
|
|
81
82
|
|
|
82
83
|
"""
|
|
83
|
-
schemas =
|
|
84
|
+
schemas = ascii_handler.collect_data_from_file(MODEL_PARAMETER_METASCHEMA)
|
|
84
85
|
|
|
85
86
|
if schema_version is None and schemas:
|
|
86
|
-
return schemas[0].get("
|
|
87
|
+
return schemas[0].get("schema_version")
|
|
87
88
|
|
|
88
|
-
if any(schema.get("
|
|
89
|
+
if any(schema.get("schema_version") == schema_version for schema in schemas):
|
|
89
90
|
return schema_version
|
|
90
91
|
|
|
91
92
|
raise ValueError(f"Schema version {schema_version} not found in {MODEL_PARAMETER_METASCHEMA}.")
|
|
@@ -112,13 +113,7 @@ def validate_dict_using_schema(data, schema_file=None, json_schema=None):
|
|
|
112
113
|
_logger.warning(f"No schema provided for validation of {data}")
|
|
113
114
|
return None
|
|
114
115
|
if json_schema is None:
|
|
115
|
-
json_schema = load_schema(
|
|
116
|
-
schema_file,
|
|
117
|
-
data.get("schema_version")
|
|
118
|
-
or data.get(
|
|
119
|
-
"SCHEMA_VERSION", "0.1.0"
|
|
120
|
-
), # default version to ensure backward compatibility
|
|
121
|
-
)
|
|
116
|
+
json_schema = load_schema(schema_file, get_schema_version_from_data(data))
|
|
122
117
|
|
|
123
118
|
validator = jsonschema.Draft6Validator(
|
|
124
119
|
schema=json_schema,
|
|
@@ -145,11 +140,36 @@ def validate_dict_using_schema(data, schema_file=None, json_schema=None):
|
|
|
145
140
|
def _retrieve_yaml_schema_from_uri(uri):
|
|
146
141
|
"""Load schema from a file URI."""
|
|
147
142
|
path = SCHEMA_PATH / Path(uri.removeprefix("file:/"))
|
|
148
|
-
contents =
|
|
143
|
+
contents = ascii_handler.collect_data_from_file(file_name=path)
|
|
149
144
|
return Resource.from_contents(contents)
|
|
150
145
|
|
|
151
146
|
|
|
152
|
-
def
|
|
147
|
+
def get_schema_version_from_data(data, observatory="cta"):
|
|
148
|
+
"""
|
|
149
|
+
Get schema version from data dictionary.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
data: dict
|
|
154
|
+
data dictionary.
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
str
|
|
159
|
+
Schema version. If not found, returns 'latest'.
|
|
160
|
+
"""
|
|
161
|
+
schema_version = data.get("schema_version") or data.get("SCHEMA_VERSION")
|
|
162
|
+
if schema_version:
|
|
163
|
+
return schema_version
|
|
164
|
+
reference_version = data.get(observatory.upper(), {}).get("REFERENCE", {}).get(
|
|
165
|
+
"VERSION"
|
|
166
|
+
) or data.get(observatory.lower(), {}).get("reference", {}).get("version")
|
|
167
|
+
if reference_version:
|
|
168
|
+
return reference_version
|
|
169
|
+
return "latest"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def load_schema(schema_file=None, schema_version="latest"):
|
|
153
173
|
"""
|
|
154
174
|
Load parameter schema from file.
|
|
155
175
|
|
|
@@ -175,28 +195,58 @@ def load_schema(schema_file=None, schema_version=None):
|
|
|
175
195
|
|
|
176
196
|
for path in (schema_file, SCHEMA_PATH / schema_file):
|
|
177
197
|
try:
|
|
178
|
-
schema =
|
|
198
|
+
schema = ascii_handler.collect_data_from_file(file_name=path)
|
|
179
199
|
break
|
|
180
200
|
except FileNotFoundError:
|
|
181
201
|
continue
|
|
182
202
|
else:
|
|
183
203
|
raise FileNotFoundError(f"Schema file not found: {schema_file}")
|
|
184
204
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
raise ValueError(f"Schema version not given in {schema_file}.")
|
|
188
|
-
schema = next((doc for doc in schema if doc.get("version") == schema_version), None)
|
|
189
|
-
if schema is None:
|
|
190
|
-
raise ValueError(f"Schema version {schema_version} not found in {schema_file}.")
|
|
191
|
-
elif schema_version is not None and schema_version != schema.get("version"):
|
|
192
|
-
_logger.warning(f"Schema version {schema_version} does not match {schema.get('version')}")
|
|
193
|
-
|
|
194
|
-
_logger.debug(f"Loading schema from {schema_file}")
|
|
205
|
+
_logger.debug(f"Loading schema from {schema_file} for schema version {schema_version}")
|
|
206
|
+
schema = _get_schema_for_version(schema, schema_file, schema_version)
|
|
195
207
|
_add_array_elements("InstrumentTypeElement", schema)
|
|
196
208
|
|
|
197
209
|
return schema
|
|
198
210
|
|
|
199
211
|
|
|
212
|
+
def _get_schema_for_version(schema, schema_file, schema_version):
|
|
213
|
+
"""
|
|
214
|
+
Get schema for a specific version.
|
|
215
|
+
|
|
216
|
+
Allow for 'latest' version to return the most recent schema.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
schema: dict or list
|
|
221
|
+
Schema dictionary or list of dictionaries.
|
|
222
|
+
schema_file: str
|
|
223
|
+
Path to schema file.
|
|
224
|
+
schema_version: str or None
|
|
225
|
+
Schema version to retrieve. If 'latest', the most recent version is returned.
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
dict
|
|
230
|
+
Schema dictionary for the specified version.
|
|
231
|
+
"""
|
|
232
|
+
if schema_version is None:
|
|
233
|
+
raise ValueError(f"Schema version not given in {schema_file}.")
|
|
234
|
+
|
|
235
|
+
if isinstance(schema, list): # schema file with several schemas defined
|
|
236
|
+
if len(schema) == 0:
|
|
237
|
+
raise ValueError(f"No schemas found in {schema_file}.")
|
|
238
|
+
if schema_version == "latest":
|
|
239
|
+
schema_version = schema[0].get("schema_version")
|
|
240
|
+
schema = next((doc for doc in schema if doc.get("schema_version") == schema_version), None)
|
|
241
|
+
if schema is None:
|
|
242
|
+
raise ValueError(f"Schema version {schema_version} not found in {schema_file}.")
|
|
243
|
+
if schema_version not in (None, "latest") and schema_version != schema.get("schema_version"):
|
|
244
|
+
_logger.warning(
|
|
245
|
+
f"Schema version {schema_version} does not match {schema.get('schema_version')}"
|
|
246
|
+
)
|
|
247
|
+
return schema
|
|
248
|
+
|
|
249
|
+
|
|
200
250
|
def _get_array_element_list():
|
|
201
251
|
"""Build complete list of array elements including design types."""
|
|
202
252
|
elements = set(names.array_elements().keys())
|
|
@@ -12,6 +12,7 @@ from astropy.utils.diff import report_diff_values
|
|
|
12
12
|
|
|
13
13
|
import simtools.utils.general as gen
|
|
14
14
|
from simtools.data_model import schema
|
|
15
|
+
from simtools.io import ascii_handler
|
|
15
16
|
from simtools.utils import names, value_conversion
|
|
16
17
|
|
|
17
18
|
__all__ = ["DataValidator"]
|
|
@@ -100,7 +101,7 @@ class DataValidator:
|
|
|
100
101
|
"""
|
|
101
102
|
try:
|
|
102
103
|
if Path(self.data_file_name).suffix in (".yml", ".yaml", ".json"):
|
|
103
|
-
self.data_dict =
|
|
104
|
+
self.data_dict = ascii_handler.collect_data_from_file(self.data_file_name)
|
|
104
105
|
self._logger.info(f"Validating data from: {self.data_file_name}")
|
|
105
106
|
else:
|
|
106
107
|
self.data_table = Table.read(self.data_file_name, guess=True, delimiter=r"\s")
|
|
@@ -563,7 +564,7 @@ class DataValidator:
|
|
|
563
564
|
If unit conversions fails
|
|
564
565
|
|
|
565
566
|
"""
|
|
566
|
-
self.
|
|
567
|
+
self._rate_limited_logger(col_name, f"Checking data column '{col_name}'")
|
|
567
568
|
|
|
568
569
|
reference_unit = self._get_reference_unit(col_name)
|
|
569
570
|
try:
|
|
@@ -574,9 +575,10 @@ class DataValidator:
|
|
|
574
575
|
if self._is_dimensionless(column_unit) and self._is_dimensionless(reference_unit):
|
|
575
576
|
return data, u.dimensionless_unscaled
|
|
576
577
|
|
|
577
|
-
self.
|
|
578
|
+
self._rate_limited_logger(
|
|
579
|
+
col_name,
|
|
578
580
|
f"Data column '{col_name}' with reference unit "
|
|
579
|
-
f"'{reference_unit}' and data unit '{column_unit}'"
|
|
581
|
+
f"'{reference_unit}' and data unit '{column_unit}'",
|
|
580
582
|
)
|
|
581
583
|
try:
|
|
582
584
|
if isinstance(data, u.Quantity | Column):
|
|
@@ -652,7 +654,9 @@ class DataValidator:
|
|
|
652
654
|
range columns
|
|
653
655
|
|
|
654
656
|
"""
|
|
655
|
-
self.
|
|
657
|
+
self._rate_limited_logger(
|
|
658
|
+
col_name, f"Checking data in column '{col_name}' for '{range_type}'"
|
|
659
|
+
)
|
|
656
660
|
|
|
657
661
|
if range_type not in ("allowed_range", "required_range"):
|
|
658
662
|
raise KeyError("Allowed range types are 'allowed_range', 'required_range'")
|
|
@@ -673,6 +677,26 @@ class DataValidator:
|
|
|
673
677
|
f"{_entry[range_type].get('max', np.inf)}])"
|
|
674
678
|
)
|
|
675
679
|
|
|
680
|
+
def _rate_limited_logger(self, col_name, message, max_logs=10):
|
|
681
|
+
"""
|
|
682
|
+
Log debug messages at a limited rate defined by a numerical column name.
|
|
683
|
+
|
|
684
|
+
Parameters
|
|
685
|
+
----------
|
|
686
|
+
col_name: str or int
|
|
687
|
+
Column name or index to limit the rate of logging.
|
|
688
|
+
message: str
|
|
689
|
+
Message to log.
|
|
690
|
+
max_logs: int
|
|
691
|
+
Maximum number of logging messages to be printed.
|
|
692
|
+
"""
|
|
693
|
+
try:
|
|
694
|
+
col_index = int(col_name)
|
|
695
|
+
if col_index < max_logs:
|
|
696
|
+
self._logger.debug(message)
|
|
697
|
+
except (ValueError, TypeError):
|
|
698
|
+
self._logger.debug(message)
|
|
699
|
+
|
|
676
700
|
@staticmethod
|
|
677
701
|
def _interval_check(data, axis_range, range_type):
|
|
678
702
|
"""
|
|
@@ -732,11 +756,11 @@ class DataValidator:
|
|
|
732
756
|
ValueError
|
|
733
757
|
if schema version is not found in schema file
|
|
734
758
|
"""
|
|
735
|
-
schema_data =
|
|
759
|
+
schema_data = ascii_handler.collect_data_from_file(file_name=schema_file)
|
|
736
760
|
entries = schema_data if isinstance(schema_data, list) else [schema_data]
|
|
737
761
|
|
|
738
762
|
for entry in entries:
|
|
739
|
-
if not schema_version or entry.get("
|
|
763
|
+
if not schema_version or entry.get("schema_version") == schema_version:
|
|
740
764
|
try:
|
|
741
765
|
return entry["data"]
|
|
742
766
|
except KeyError as exc:
|
|
@@ -774,8 +798,9 @@ class DataValidator:
|
|
|
774
798
|
If data column is not found.
|
|
775
799
|
|
|
776
800
|
"""
|
|
777
|
-
self.
|
|
778
|
-
|
|
801
|
+
self._rate_limited_logger(
|
|
802
|
+
column_name,
|
|
803
|
+
f"Getting reference data column {column_name} from schema {self._data_description}",
|
|
779
804
|
)
|
|
780
805
|
try:
|
|
781
806
|
return (
|