gammasimtools 0.20.0__py3-none-any.whl → 0.22.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.20.0.dist-info → gammasimtools-0.22.0.dist-info}/METADATA +2 -3
- {gammasimtools-0.20.0.dist-info → gammasimtools-0.22.0.dist-info}/RECORD +313 -296
- {gammasimtools-0.20.0.dist-info → gammasimtools-0.22.0.dist-info}/entry_points.txt +3 -2
- simtools/_version.py +2 -2
- simtools/applications/calculate_incident_angles.py +1 -4
- simtools/applications/convert_all_model_parameters_from_simtel.py +1 -2
- simtools/applications/convert_model_parameter_from_simtel.py +0 -1
- simtools/applications/db_generate_compound_indexes.py +4 -17
- simtools/applications/db_upload_model_repository.py +122 -0
- simtools/applications/derive_psf_parameters.py +71 -42
- 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 +8 -185
- simtools/applications/maintain_simulation_model_add_production.py +81 -0
- simtools/applications/merge_tables.py +1 -1
- simtools/applications/plot_array_layout.py +1 -2
- simtools/applications/plot_simtel_events.py +2 -228
- simtools/applications/print_version.py +8 -7
- simtools/applications/production_derive_statistics.py +1 -2
- simtools/applications/production_generate_grid.py +1 -1
- simtools/applications/simulate_flasher.py +74 -72
- simtools/applications/simulate_illuminator.py +52 -186
- simtools/applications/{simulate_calibration_events.py → simulate_pedestals.py} +9 -55
- simtools/applications/submit_model_parameter_from_external.py +0 -1
- simtools/applications/validate_camera_efficiency.py +0 -1
- simtools/applications/validate_camera_fov.py +1 -2
- simtools/applications/validate_cumulative_psf.py +2 -3
- simtools/applications/validate_file_using_schema.py +20 -12
- simtools/applications/validate_optics.py +2 -2
- simtools/camera/camera_efficiency.py +8 -11
- simtools/configuration/commandline_parser.py +1 -7
- simtools/configuration/configurator.py +0 -2
- simtools/corsika/corsika_config.py +9 -11
- simtools/corsika/corsika_histograms.py +82 -1
- simtools/data_model/model_data_writer.py +87 -25
- simtools/data_model/schema.py +61 -2
- simtools/data_model/validate_data.py +1 -1
- simtools/db/db_handler.py +103 -48
- simtools/db/db_model_upload.py +247 -16
- simtools/io/io_handler.py +31 -83
- simtools/job_execution/job_manager.py +45 -0
- simtools/layout/array_layout_utils.py +1 -5
- simtools/model/array_model.py +93 -42
- simtools/model/model_parameter.py +20 -9
- simtools/model/model_repository.py +197 -109
- simtools/model/model_utils.py +21 -6
- simtools/model/telescope_model.py +20 -0
- simtools/production_configuration/derive_corsika_limits.py +1 -1
- simtools/ray_tracing/incident_angles.py +7 -7
- simtools/ray_tracing/mirror_panel_psf.py +1 -1
- simtools/ray_tracing/psf_parameter_optimisation.py +1106 -565
- simtools/ray_tracing/ray_tracing.py +1 -3
- simtools/reporting/docs_read_parameters.py +171 -101
- simtools/resources/array_elements.yml +26 -0
- simtools/runners/corsika_simtel_runner.py +11 -17
- simtools/runners/runner_services.py +5 -6
- simtools/runners/simtools_runner.py +0 -2
- simtools/schemas/application_workflow.metaschema.yml +1 -1
- simtools/schemas/common_definitions.schema.yml +39 -0
- simtools/schemas/model_parameter.metaschema.yml +19 -13
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +6 -12
- simtools/schemas/model_parameters/adjust_gain.schema.yml +0 -5
- simtools/schemas/model_parameters/altitude.schema.yml +0 -5
- simtools/schemas/model_parameters/array_coordinates.schema.yml +0 -5
- simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +0 -5
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +0 -7
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +0 -7
- simtools/schemas/model_parameters/array_layouts.schema.yml +0 -5
- simtools/schemas/model_parameters/array_triggers.schema.yml +0 -5
- simtools/schemas/model_parameters/array_window.schema.yml +0 -7
- simtools/schemas/model_parameters/asum_clipping.schema.yml +0 -3
- simtools/schemas/model_parameters/asum_offset.schema.yml +0 -7
- simtools/schemas/model_parameters/asum_shaping.schema.yml +0 -7
- simtools/schemas/model_parameters/asum_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/atmospheric_profile.schema.yml +0 -5
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +0 -5
- simtools/schemas/model_parameters/axes_offsets.schema.yml +0 -7
- simtools/schemas/model_parameters/calibration_devices.schema.yml +30 -0
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_config_file.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_degraded_map.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_depth.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_filter.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +0 -3
- simtools/schemas/model_parameters/camera_pixels.schema.yml +0 -7
- simtools/schemas/model_parameters/camera_transmission.schema.yml +0 -7
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +0 -7
- simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +0 -7
- simtools/schemas/model_parameters/corsika_observation_level.schema.yml +0 -5
- simtools/schemas/model_parameters/dark_events.schema.yml +4 -3
- simtools/schemas/model_parameters/default_trigger.schema.yml +0 -7
- simtools/schemas/model_parameters/design_model.schema.yml +0 -7
- simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +0 -7
- simtools/schemas/model_parameters/disc_bins.schema.yml +0 -7
- simtools/schemas/model_parameters/disc_start.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -9
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +0 -5
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -5
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_offset.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +0 -3
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +2 -12
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +0 -3
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +0 -7
- simtools/schemas/model_parameters/epsg_code.schema.yml +0 -5
- simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -9
- simtools/schemas/model_parameters/fadc_bins.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +0 -2
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -9
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +0 -2
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +0 -2
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_long_event_threshold.schema.yml +0 -3
- simtools/schemas/model_parameters/fadc_long_sum_bins.schema.yml +0 -3
- simtools/schemas/model_parameters/fadc_long_sum_offset.schema.yml +0 -3
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_max_sum.schema.yml +0 -2
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_noise.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +0 -7
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +0 -7
- simtools/schemas/model_parameters/fake_mirror_list.schema.yml +0 -3
- simtools/schemas/model_parameters/flasher_angular_distribution.schema.yml +32 -0
- simtools/schemas/model_parameters/flasher_angular_distribution_width.schema.yml +32 -0
- simtools/schemas/model_parameters/flasher_bunch_size.schema.yml +28 -0
- simtools/schemas/model_parameters/flasher_external_trigger.schema.yml +32 -0
- simtools/schemas/model_parameters/flasher_photons.schema.yml +34 -0
- simtools/schemas/model_parameters/flasher_position.schema.yml +43 -0
- simtools/schemas/model_parameters/flasher_pulse_exp_decay.schema.yml +29 -0
- simtools/schemas/model_parameters/flasher_pulse_offset.schema.yml +35 -0
- simtools/schemas/model_parameters/flasher_pulse_shape.schema.yml +30 -0
- simtools/schemas/model_parameters/flasher_pulse_width.schema.yml +32 -0
- simtools/schemas/model_parameters/flasher_type.schema.yml +28 -0
- simtools/schemas/model_parameters/flasher_var_photons.schema.yml +31 -0
- simtools/schemas/model_parameters/flasher_wavelength.schema.yml +33 -0
- simtools/schemas/model_parameters/flatfielding.schema.yml +0 -7
- simtools/schemas/model_parameters/focal_length.schema.yml +0 -7
- simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +0 -3
- simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +0 -3
- simtools/schemas/model_parameters/focus_offset.schema.yml +0 -7
- simtools/schemas/model_parameters/gain_variation.schema.yml +0 -7
- simtools/schemas/model_parameters/geomag_horizontal.schema.yml +2 -7
- simtools/schemas/model_parameters/geomag_rotation.schema.yml +2 -7
- simtools/schemas/model_parameters/geomag_vertical.schema.yml +2 -7
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +0 -5
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +0 -7
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +0 -7
- simtools/schemas/model_parameters/laser_events.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_external_trigger.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_photons.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_var_photons.schema.yml +4 -3
- simtools/schemas/model_parameters/laser_wavelength.schema.yml +4 -3
- simtools/schemas/model_parameters/led_events.schema.yml +4 -3
- simtools/schemas/model_parameters/led_photons.schema.yml +4 -3
- simtools/schemas/model_parameters/led_pulse_offset.schema.yml +4 -3
- simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +4 -3
- simtools/schemas/model_parameters/led_var_photons.schema.yml +4 -3
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +0 -7
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +0 -7
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +0 -7
- simtools/schemas/model_parameters/min_photons.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +0 -5
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_class.schema.yml +2 -9
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +0 -5
- simtools/schemas/model_parameters/mirror_list.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_offset.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +0 -7
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +0 -7
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +0 -7
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +0 -7
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +0 -7
- simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +0 -3
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +0 -7
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +0 -7
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +0 -5
- simtools/schemas/model_parameters/nsb_reference_value.schema.yml +0 -5
- simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +0 -5
- simtools/schemas/model_parameters/nsb_sky_map.schema.yml +0 -5
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +0 -5
- simtools/schemas/model_parameters/num_gains.schema.yml +0 -7
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +0 -7
- simtools/schemas/model_parameters/optics_properties.schema.yml +0 -7
- simtools/schemas/model_parameters/parabolic_dish.schema.yml +0 -3
- simtools/schemas/model_parameters/pedestal_events.schema.yml +4 -7
- simtools/schemas/model_parameters/photon_delay.schema.yml +0 -7
- simtools/schemas/model_parameters/photons_per_run.schema.yml +4 -4
- simtools/schemas/model_parameters/pixel_cells.schema.yml +0 -3
- simtools/schemas/model_parameters/pixels_parallel.schema.yml +0 -3
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +0 -7
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +0 -5
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +0 -5
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +0 -5
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +0 -7
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +4 -9
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +0 -5
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +0 -7
- simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +0 -3
- simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +0 -3
- simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +0 -3
- simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +0 -3
- simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +0 -3
- simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +0 -3
- simtools/schemas/model_parameters/qe_variation.schema.yml +0 -7
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +0 -7
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -7
- simtools/schemas/model_parameters/random_generator.schema.yml +0 -7
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +0 -7
- simtools/schemas/model_parameters/reference_point_altitude.schema.yml +0 -5
- simtools/schemas/model_parameters/reference_point_latitude.schema.yml +0 -5
- simtools/schemas/model_parameters/reference_point_longitude.schema.yml +0 -5
- simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +0 -5
- simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +0 -5
- simtools/schemas/model_parameters/sampled_output.schema.yml +0 -7
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +0 -7
- simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +0 -3
- simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +0 -3
- simtools/schemas/model_parameters/stars.schema.yml +0 -5
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +0 -7
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +0 -7
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +0 -7
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +0 -7
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +0 -7
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +0 -7
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +0 -7
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +0 -7
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +0 -7
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +0 -7
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +0 -7
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +0 -7
- simtools/schemas/model_parameters/transit_time_error.schema.yml +0 -7
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +0 -7
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +0 -7
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +0 -7
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +0 -7
- simtools/schemas/production_tables.schema.yml +8 -8
- simtools/schemas/simulation_models_info.schema.yml +78 -0
- simtools/simtel/simtel_config_writer.py +88 -14
- simtools/simtel/simulator_array.py +44 -74
- simtools/simtel/simulator_light_emission.py +336 -629
- simtools/simtel/simulator_ray_tracing.py +2 -2
- simtools/simulator.py +46 -18
- simtools/testing/configuration.py +4 -2
- simtools/testing/sim_telarray_metadata.py +4 -4
- simtools/utils/geometry.py +34 -0
- simtools/version.py +111 -0
- simtools/{corsika/corsika_histograms_visualize.py → visualization/plot_corsika_histograms.py} +109 -0
- simtools/visualization/plot_psf.py +775 -0
- simtools/visualization/plot_simtel_events.py +284 -87
- simtools/applications/maintain_simulation_model_add_production_table.py +0 -71
- simtools/model/flasher_model.py +0 -106
- {gammasimtools-0.20.0.dist-info → gammasimtools-0.22.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.20.0.dist-info → gammasimtools-0.22.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.20.0.dist-info → gammasimtools-0.22.0.dist-info}/top_level.txt +0 -0
|
@@ -132,11 +132,10 @@ def main(): # noqa: D103
|
|
|
132
132
|
logger = logging.getLogger()
|
|
133
133
|
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
134
134
|
|
|
135
|
-
# Output directory to save files related directly to this app
|
|
136
135
|
_io_handler = io_handler.IOHandler()
|
|
137
|
-
output_dir = _io_handler.get_output_directory(
|
|
136
|
+
output_dir = _io_handler.get_output_directory()
|
|
138
137
|
|
|
139
|
-
tel_model, site_model = initialize_simulation_models(
|
|
138
|
+
tel_model, site_model, _ = initialize_simulation_models(
|
|
140
139
|
label=label,
|
|
141
140
|
db_config=db_config,
|
|
142
141
|
site=args_dict["site"],
|
|
@@ -61,12 +61,15 @@ def _parse(label, description):
|
|
|
61
61
|
|
|
62
62
|
"""
|
|
63
63
|
config = configurator.Configurator(label=label, description=description)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
config.parser.add_argument(
|
|
65
|
+
"--file_name",
|
|
66
|
+
help="File to be validated (full path or name pattern, e.g., '*.json')",
|
|
67
|
+
default="*.json",
|
|
68
|
+
)
|
|
69
|
+
config.parser.add_argument(
|
|
67
70
|
"--file_directory",
|
|
68
71
|
help=(
|
|
69
|
-
"Directory with
|
|
72
|
+
"Directory with files to be validated. "
|
|
70
73
|
"If no schema file is provided, the assumption is that model "
|
|
71
74
|
"parameters are validated and the schema files are taken from "
|
|
72
75
|
f"{MODEL_PARAMETER_SCHEMA_PATH}."
|
|
@@ -84,6 +87,11 @@ def _parse(label, description):
|
|
|
84
87
|
help="Require exact data type for validation",
|
|
85
88
|
action="store_true",
|
|
86
89
|
)
|
|
90
|
+
config.parser.add_argument(
|
|
91
|
+
"--ignore_software_version",
|
|
92
|
+
help="Ignore software version check.",
|
|
93
|
+
action="store_true",
|
|
94
|
+
)
|
|
87
95
|
return config.initialize(paths=False)
|
|
88
96
|
|
|
89
97
|
|
|
@@ -115,11 +123,11 @@ def _get_schema_file_name(args_dict, data_dict=None):
|
|
|
115
123
|
return schema_file
|
|
116
124
|
|
|
117
125
|
|
|
118
|
-
def
|
|
119
|
-
"""Return list of
|
|
126
|
+
def _get_file_list(file_directory=None, file_name="*.json"):
|
|
127
|
+
"""Return list of files in a directory."""
|
|
120
128
|
file_list = []
|
|
121
129
|
if file_directory is not None:
|
|
122
|
-
file_list = list(Path(file_directory).rglob(
|
|
130
|
+
file_list = list(Path(file_directory).rglob(file_name))
|
|
123
131
|
if not file_list:
|
|
124
132
|
raise FileNotFoundError(f"No files found in {file_directory}")
|
|
125
133
|
elif file_name is not None:
|
|
@@ -137,9 +145,7 @@ def validate_dict_using_schema(args_dict, logger):
|
|
|
137
145
|
the metadata section of the data dictionary.
|
|
138
146
|
|
|
139
147
|
"""
|
|
140
|
-
for file_name in
|
|
141
|
-
args_dict.get("file_directory"), args_dict.get("file_name")
|
|
142
|
-
):
|
|
148
|
+
for file_name in _get_file_list(args_dict.get("file_directory"), args_dict.get("file_name")):
|
|
143
149
|
try:
|
|
144
150
|
data = ascii_handler.collect_data_from_file(file_name=file_name)
|
|
145
151
|
except FileNotFoundError as exc:
|
|
@@ -148,7 +154,9 @@ def validate_dict_using_schema(args_dict, logger):
|
|
|
148
154
|
try:
|
|
149
155
|
for data_dict in data:
|
|
150
156
|
schema.validate_dict_using_schema(
|
|
151
|
-
data_dict,
|
|
157
|
+
data_dict,
|
|
158
|
+
_get_schema_file_name(args_dict, data_dict),
|
|
159
|
+
ignore_software_version=args_dict.get("ignore_software_version", False),
|
|
152
160
|
)
|
|
153
161
|
except Exception as exc:
|
|
154
162
|
raise ValueError(f"Validation of file {file_name} failed") from exc
|
|
@@ -159,7 +167,7 @@ def validate_data_files(args_dict, logger):
|
|
|
159
167
|
"""Validate data files."""
|
|
160
168
|
if args_dict.get("file_directory") is not None:
|
|
161
169
|
tmp_args_dict = {}
|
|
162
|
-
for file_name in
|
|
170
|
+
for file_name in _get_file_list(args_dict.get("file_directory")):
|
|
163
171
|
tmp_args_dict["file_name"] = file_name
|
|
164
172
|
parameter_name = re.sub(r"-\d+\.\d+\.\d+", "", file_name.stem)
|
|
165
173
|
schema_file = schema.get_model_parameter_schema_file(f"{parameter_name}")
|
|
@@ -126,9 +126,9 @@ def main(): # noqa: D103
|
|
|
126
126
|
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
127
127
|
|
|
128
128
|
_io_handler = io_handler.IOHandler()
|
|
129
|
-
output_dir = _io_handler.get_output_directory(
|
|
129
|
+
output_dir = _io_handler.get_output_directory()
|
|
130
130
|
|
|
131
|
-
tel_model, site_model = initialize_simulation_models(
|
|
131
|
+
tel_model, site_model, _ = initialize_simulation_models(
|
|
132
132
|
label=label,
|
|
133
133
|
db_config=db_config,
|
|
134
134
|
site=args_dict["site"],
|
|
@@ -40,14 +40,14 @@ class CameraEfficiency:
|
|
|
40
40
|
self.label = label
|
|
41
41
|
|
|
42
42
|
self.io_handler = io_handler.IOHandler()
|
|
43
|
-
self.telescope_model, self.site_model = initialize_simulation_models(
|
|
44
|
-
self.label,
|
|
45
|
-
db_config,
|
|
46
|
-
config_data["
|
|
47
|
-
config_data["
|
|
48
|
-
config_data["
|
|
43
|
+
self.telescope_model, self.site_model, _ = initialize_simulation_models(
|
|
44
|
+
label=self.label,
|
|
45
|
+
db_config=db_config,
|
|
46
|
+
model_version=config_data["model_version"],
|
|
47
|
+
site=config_data["site"],
|
|
48
|
+
telescope_name=config_data["telescope"],
|
|
49
49
|
)
|
|
50
|
-
self.output_dir = self.io_handler.get_output_directory(
|
|
50
|
+
self.output_dir = self.io_handler.get_output_directory()
|
|
51
51
|
|
|
52
52
|
self._results = None
|
|
53
53
|
self._has_results = False
|
|
@@ -101,10 +101,7 @@ class CameraEfficiency:
|
|
|
101
101
|
label=self.label,
|
|
102
102
|
)
|
|
103
103
|
|
|
104
|
-
_file[label] = self.io_handler.get_output_directory(
|
|
105
|
-
label=self.label,
|
|
106
|
-
sub_dir="camera_efficiency",
|
|
107
|
-
).joinpath(file_name)
|
|
104
|
+
_file[label] = self.io_handler.get_output_directory().joinpath(file_name)
|
|
108
105
|
return _file
|
|
109
106
|
|
|
110
107
|
def simulate(self):
|
|
@@ -21,7 +21,7 @@ class CommandLineParser(argparse.ArgumentParser):
|
|
|
21
21
|
|
|
22
22
|
Wrapper around standard python argparse.ArgumentParser.
|
|
23
23
|
|
|
24
|
-
Command line arguments should be given in snake_case, e.g.
|
|
24
|
+
Command line arguments should be given in snake_case, e.g. 'input_meta'.
|
|
25
25
|
|
|
26
26
|
Parameters
|
|
27
27
|
----------
|
|
@@ -102,12 +102,6 @@ class CommandLineParser(argparse.ArgumentParser):
|
|
|
102
102
|
default="./simtools-output/",
|
|
103
103
|
required=False,
|
|
104
104
|
)
|
|
105
|
-
_job_group.add_argument(
|
|
106
|
-
"--use_plain_output_path",
|
|
107
|
-
help="use plain output path (without the tool name and dates)",
|
|
108
|
-
action="store_true",
|
|
109
|
-
required=False,
|
|
110
|
-
)
|
|
111
105
|
_job_group.add_argument(
|
|
112
106
|
"--model_path",
|
|
113
107
|
help="path pointing towards simulation model file directory",
|
|
@@ -340,8 +340,6 @@ class Configurator:
|
|
|
340
340
|
_io_handler = io_handler.IOHandler()
|
|
341
341
|
_io_handler.set_paths(
|
|
342
342
|
output_path=self.config.get("output_path", None),
|
|
343
|
-
use_plain_output_path=self.config.get("use_plain_output_path", False),
|
|
344
|
-
data_path=self.config.get("data_path", None),
|
|
345
343
|
model_path=self.config.get("model_path", None),
|
|
346
344
|
)
|
|
347
345
|
|
|
@@ -114,8 +114,8 @@ class CorsikaConfig:
|
|
|
114
114
|
return {}
|
|
115
115
|
|
|
116
116
|
self.is_file_updated = False
|
|
117
|
-
self.azimuth_angle = int(args_dict
|
|
118
|
-
self.zenith_angle = args_dict
|
|
117
|
+
self.azimuth_angle = int(args_dict.get("azimuth_angle", 0.0 * u.deg).to("deg").value)
|
|
118
|
+
self.zenith_angle = int(args_dict.get("zenith_angle", 0.0 * u.deg).to("deg").value)
|
|
119
119
|
|
|
120
120
|
self._logger.debug(
|
|
121
121
|
f"Setting CORSIKA parameters from database ({args_dict['model_version']})"
|
|
@@ -563,8 +563,9 @@ class CorsikaConfig:
|
|
|
563
563
|
if self.is_file_updated:
|
|
564
564
|
self._logger.debug(f"CORSIKA input file already updated: {self.config_file_path}")
|
|
565
565
|
return self.config_file_path
|
|
566
|
-
_output_generic_file_name = self.set_output_file_and_directory(use_multipipe=use_multipipe)
|
|
567
566
|
self._logger.info(f"Exporting CORSIKA input file to {self.config_file_path}")
|
|
567
|
+
_output_generic_file_name = self.set_output_file_and_directory(use_multipipe=use_multipipe)
|
|
568
|
+
self._logger.info(f"Output generic file name: {_output_generic_file_name}")
|
|
568
569
|
|
|
569
570
|
with open(self.config_file_path, "w", encoding="utf-8") as file:
|
|
570
571
|
file.write("\n* [ RUN PARAMETERS ]\n")
|
|
@@ -712,13 +713,10 @@ class CorsikaConfig:
|
|
|
712
713
|
str
|
|
713
714
|
Output file name.
|
|
714
715
|
"""
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
file_directory.mkdir(parents=True, exist_ok=True)
|
|
720
|
-
self.config_file_path = file_directory.joinpath(config_file_name)
|
|
721
|
-
|
|
716
|
+
self.config_file_path = self.io_handler.get_output_file(
|
|
717
|
+
file_name=self.get_corsika_config_file_name(file_type="config"),
|
|
718
|
+
sub_dir="corsika_sim_telarray" if use_multipipe else "corsika",
|
|
719
|
+
)
|
|
722
720
|
return self.get_corsika_config_file_name(file_type="output_generic")
|
|
723
721
|
|
|
724
722
|
def _write_seeds(self, file, use_test_seeds=False):
|
|
@@ -748,7 +746,7 @@ class CorsikaConfig:
|
|
|
748
746
|
Piece of text to be added to the CORSIKA input file.
|
|
749
747
|
"""
|
|
750
748
|
corsika_input_list = ""
|
|
751
|
-
for telescope_name, telescope in self.array_model.
|
|
749
|
+
for telescope_name, telescope in self.array_model.telescope_models.items():
|
|
752
750
|
positions = telescope.get_parameter_value_with_unit("array_element_position_ground")
|
|
753
751
|
corsika_input_list += "TELESCOPE"
|
|
754
752
|
for pos in positions:
|
|
@@ -22,6 +22,7 @@ from simtools.io.ascii_handler import collect_data_from_file
|
|
|
22
22
|
from simtools.io.hdf5_handler import fill_hdf5_table
|
|
23
23
|
from simtools.utils.geometry import convert_2d_to_radial_distr, rotate
|
|
24
24
|
from simtools.utils.names import sanitize_name
|
|
25
|
+
from simtools.visualization import plot_corsika_histograms as visualize
|
|
25
26
|
|
|
26
27
|
X_AXIS_STRING = "x axis"
|
|
27
28
|
Y_AXIS_STRING = "y axis"
|
|
@@ -66,7 +67,7 @@ class CorsikaHistograms:
|
|
|
66
67
|
raise FileNotFoundError
|
|
67
68
|
|
|
68
69
|
self.io_handler = io_handler.IOHandler()
|
|
69
|
-
_default_output_path = self.io_handler.get_output_directory(
|
|
70
|
+
_default_output_path = self.io_handler.get_output_directory("corsika")
|
|
70
71
|
|
|
71
72
|
if output_path is None:
|
|
72
73
|
self.output_path = _default_output_path
|
|
@@ -111,6 +112,86 @@ class CorsikaHistograms:
|
|
|
111
112
|
self.read_event_information()
|
|
112
113
|
self._initialize_header()
|
|
113
114
|
|
|
115
|
+
def parse_telescope_indices(self, indices_arg):
|
|
116
|
+
"""Return telescope indices as ndarray[int] or None.
|
|
117
|
+
|
|
118
|
+
Accepts None, a sequence of strings/ints. Raises ValueError on invalid input.
|
|
119
|
+
"""
|
|
120
|
+
if indices_arg is None:
|
|
121
|
+
return None
|
|
122
|
+
try:
|
|
123
|
+
return np.array(indices_arg).astype(int)
|
|
124
|
+
except ValueError as exc:
|
|
125
|
+
msg = (
|
|
126
|
+
f"{indices_arg} not a valid input. Please use integer numbers for telescope_indices"
|
|
127
|
+
)
|
|
128
|
+
self._logger.error(msg)
|
|
129
|
+
raise ValueError(msg) from exc
|
|
130
|
+
|
|
131
|
+
def should_overwrite(
|
|
132
|
+
self, write_hdf5: bool, event1d: list | None, event2d: list | None
|
|
133
|
+
) -> bool:
|
|
134
|
+
"""Return True if output HDF5 exists and any writing flag is requested."""
|
|
135
|
+
exists = Path(self.hdf5_file_name).exists()
|
|
136
|
+
if exists and (write_hdf5 or bool(event1d) or bool(event2d)):
|
|
137
|
+
self._logger.warning(
|
|
138
|
+
f"Output hdf5 file {self.hdf5_file_name} already exists. Overwriting it."
|
|
139
|
+
)
|
|
140
|
+
return True
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
def run_export_pipeline(
|
|
144
|
+
self,
|
|
145
|
+
*,
|
|
146
|
+
individual_telescopes: bool,
|
|
147
|
+
hist_config,
|
|
148
|
+
indices_arg,
|
|
149
|
+
write_pdf: bool,
|
|
150
|
+
write_hdf5: bool,
|
|
151
|
+
event1d: list | None,
|
|
152
|
+
event2d: list | None,
|
|
153
|
+
test: bool = False,
|
|
154
|
+
) -> dict:
|
|
155
|
+
"""Run the full histogram export pipeline and return output artifact paths.
|
|
156
|
+
|
|
157
|
+
Returns a dict with optional keys: pdf_photons, pdf_event1d, pdf_event2d.
|
|
158
|
+
"""
|
|
159
|
+
outputs: dict[str, Path | None] = {
|
|
160
|
+
"pdf_photons": None,
|
|
161
|
+
"pdf_event_1d": None,
|
|
162
|
+
"pdf_event_2d": None,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
indices = self.parse_telescope_indices(indices_arg)
|
|
166
|
+
overwrite = self.should_overwrite(write_hdf5, event1d, event2d)
|
|
167
|
+
|
|
168
|
+
self.set_histograms(
|
|
169
|
+
telescope_indices=indices,
|
|
170
|
+
individual_telescopes=individual_telescopes,
|
|
171
|
+
hist_config=hist_config,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if write_pdf:
|
|
175
|
+
pdf_path = visualize.export_all_photon_figures_pdf(self, test=test)
|
|
176
|
+
outputs["pdf_photons"] = pdf_path
|
|
177
|
+
if write_hdf5:
|
|
178
|
+
self.export_histograms(overwrite=overwrite)
|
|
179
|
+
|
|
180
|
+
if event1d is not None:
|
|
181
|
+
outputs["pdf_event_1d"] = visualize.derive_event_1d_histograms(
|
|
182
|
+
self, event1d, pdf=write_pdf, hdf5=write_hdf5, overwrite=not write_hdf5
|
|
183
|
+
)
|
|
184
|
+
if event2d is not None:
|
|
185
|
+
outputs["pdf_event_2d"] = visualize.derive_event_2d_histograms(
|
|
186
|
+
self,
|
|
187
|
+
event2d,
|
|
188
|
+
pdf=write_pdf,
|
|
189
|
+
hdf5=write_hdf5,
|
|
190
|
+
overwrite=not (write_hdf5 or bool(event1d)),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return outputs
|
|
194
|
+
|
|
114
195
|
@property
|
|
115
196
|
def hdf5_file_name(self):
|
|
116
197
|
"""
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
import packaging.version
|
|
6
7
|
from astropy.io.registry.base import IORegistryError
|
|
7
8
|
|
|
8
9
|
import simtools.utils.general as gen
|
|
@@ -29,8 +30,6 @@ class ModelDataWriter:
|
|
|
29
30
|
Dictionary with configuration parameters.
|
|
30
31
|
output_path: str or Path
|
|
31
32
|
Path to output file.
|
|
32
|
-
use_plain_output_path: bool
|
|
33
|
-
Use plain output path.
|
|
34
33
|
args_dict: dict
|
|
35
34
|
Dictionary with configuration parameters.
|
|
36
35
|
|
|
@@ -41,7 +40,6 @@ class ModelDataWriter:
|
|
|
41
40
|
product_data_file=None,
|
|
42
41
|
product_data_format=None,
|
|
43
42
|
output_path=None,
|
|
44
|
-
use_plain_output_path=True,
|
|
45
43
|
args_dict=None,
|
|
46
44
|
):
|
|
47
45
|
"""Initialize model data writer."""
|
|
@@ -50,11 +48,8 @@ class ModelDataWriter:
|
|
|
50
48
|
self.schema_dict = {}
|
|
51
49
|
if args_dict is not None:
|
|
52
50
|
output_path = args_dict.get("output_path", output_path)
|
|
53
|
-
use_plain_output_path = args_dict.get("use_plain_output_path", use_plain_output_path)
|
|
54
51
|
if output_path is not None:
|
|
55
|
-
self.io_handler.set_paths(
|
|
56
|
-
output_path=output_path, use_plain_output_path=use_plain_output_path
|
|
57
|
-
)
|
|
52
|
+
self.io_handler.set_paths(output_path=output_path)
|
|
58
53
|
try:
|
|
59
54
|
self.product_data_file = self.io_handler.get_output_file(file_name=product_data_file)
|
|
60
55
|
except TypeError:
|
|
@@ -104,9 +99,10 @@ class ModelDataWriter:
|
|
|
104
99
|
parameter_version,
|
|
105
100
|
output_file,
|
|
106
101
|
output_path=None,
|
|
107
|
-
use_plain_output_path=False,
|
|
108
102
|
metadata_input_dict=None,
|
|
109
103
|
db_config=None,
|
|
104
|
+
unit=None,
|
|
105
|
+
meta_parameter=False,
|
|
110
106
|
):
|
|
111
107
|
"""
|
|
112
108
|
Generate DB-style model parameter dict and write it to json file.
|
|
@@ -125,12 +121,12 @@ class ModelDataWriter:
|
|
|
125
121
|
Name of output file.
|
|
126
122
|
output_path: str or Path
|
|
127
123
|
Path to output file.
|
|
128
|
-
use_plain_output_path: bool
|
|
129
|
-
Use plain output path.
|
|
130
124
|
metadata_input_dict: dict
|
|
131
125
|
Input to metadata collector.
|
|
132
126
|
db_config: dict
|
|
133
127
|
Database configuration. If not None, check if parameter with the same version exists.
|
|
128
|
+
unit: str
|
|
129
|
+
Unit of the parameter value (if applicable and value is not of type astropy Quantity).
|
|
134
130
|
|
|
135
131
|
Returns
|
|
136
132
|
-------
|
|
@@ -142,7 +138,6 @@ class ModelDataWriter:
|
|
|
142
138
|
product_data_format="json",
|
|
143
139
|
args_dict=None,
|
|
144
140
|
output_path=output_path,
|
|
145
|
-
use_plain_output_path=use_plain_output_path,
|
|
146
141
|
)
|
|
147
142
|
if db_config is not None:
|
|
148
143
|
writer.check_db_for_existing_parameter(
|
|
@@ -160,7 +155,13 @@ class ModelDataWriter:
|
|
|
160
155
|
)
|
|
161
156
|
|
|
162
157
|
_json_dict = writer.get_validated_parameter_dict(
|
|
163
|
-
parameter_name,
|
|
158
|
+
parameter_name,
|
|
159
|
+
value,
|
|
160
|
+
instrument,
|
|
161
|
+
parameter_version,
|
|
162
|
+
unique_id,
|
|
163
|
+
unit=unit,
|
|
164
|
+
meta_parameter=meta_parameter,
|
|
164
165
|
)
|
|
165
166
|
writer.write_dict_to_model_parameter_json(output_file, _json_dict)
|
|
166
167
|
return _json_dict
|
|
@@ -210,6 +211,8 @@ class ModelDataWriter:
|
|
|
210
211
|
parameter_version,
|
|
211
212
|
unique_id=None,
|
|
212
213
|
schema_version=None,
|
|
214
|
+
unit=None,
|
|
215
|
+
meta_parameter=False,
|
|
213
216
|
):
|
|
214
217
|
"""
|
|
215
218
|
Get validated parameter dictionary.
|
|
@@ -226,6 +229,12 @@ class ModelDataWriter:
|
|
|
226
229
|
Version of the parameter.
|
|
227
230
|
schema_version: str
|
|
228
231
|
Version of the schema.
|
|
232
|
+
unique_id: str
|
|
233
|
+
Unique ID of the parameter set (from metadata).
|
|
234
|
+
unit: str
|
|
235
|
+
Unit of the parameter value (if applicable and value is not an astropy Quantity).
|
|
236
|
+
meta_parameter: bool
|
|
237
|
+
Setting for meta parameter flag.
|
|
229
238
|
|
|
230
239
|
Returns
|
|
231
240
|
-------
|
|
@@ -233,10 +242,10 @@ class ModelDataWriter:
|
|
|
233
242
|
Validated parameter dictionary.
|
|
234
243
|
"""
|
|
235
244
|
self._logger.debug(f"Getting validated parameter dictionary for {instrument}")
|
|
236
|
-
schema_file =
|
|
237
|
-
self.schema_dict = ascii_handler.collect_data_from_file(schema_file)
|
|
245
|
+
self.schema_dict, schema_file = self._read_schema_dict(parameter_name, schema_version)
|
|
238
246
|
|
|
239
|
-
|
|
247
|
+
if unit is None:
|
|
248
|
+
value, unit = value_conversion.split_value_and_unit(value)
|
|
240
249
|
|
|
241
250
|
data_dict = {
|
|
242
251
|
"schema_version": schema.get_model_parameter_schema_version(schema_version),
|
|
@@ -249,10 +258,8 @@ class ModelDataWriter:
|
|
|
249
258
|
"unit": unit,
|
|
250
259
|
"type": self._get_parameter_type(),
|
|
251
260
|
"file": self._parameter_is_a_file(),
|
|
252
|
-
"meta_parameter":
|
|
253
|
-
"model_parameter_schema_version": self.schema_dict.get(
|
|
254
|
-
"model_parameter_schema_version", "0.1.0"
|
|
255
|
-
),
|
|
261
|
+
"meta_parameter": meta_parameter,
|
|
262
|
+
"model_parameter_schema_version": self.schema_dict.get("schema_version", "0.1.0"),
|
|
256
263
|
}
|
|
257
264
|
return self.validate_and_transform(
|
|
258
265
|
product_data_dict=data_dict,
|
|
@@ -260,19 +267,74 @@ class ModelDataWriter:
|
|
|
260
267
|
is_model_parameter=True,
|
|
261
268
|
)
|
|
262
269
|
|
|
270
|
+
def _read_schema_dict(self, parameter_name, schema_version):
|
|
271
|
+
"""
|
|
272
|
+
Read schema dict for given parameter name and version.
|
|
273
|
+
|
|
274
|
+
Use newest schema version if schema_version is None.
|
|
275
|
+
|
|
276
|
+
Parameters
|
|
277
|
+
----------
|
|
278
|
+
parameter_name: str
|
|
279
|
+
Name of the parameter.
|
|
280
|
+
schema_version: str
|
|
281
|
+
Schema version.
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
dict
|
|
286
|
+
Schema dictionary.
|
|
287
|
+
"""
|
|
288
|
+
schema_file = schema.get_model_parameter_schema_file(parameter_name)
|
|
289
|
+
schemas = ascii_handler.collect_data_from_file(schema_file)
|
|
290
|
+
if isinstance(schemas, list):
|
|
291
|
+
if schema_version is None:
|
|
292
|
+
return self._find_highest_schema_version(schemas), schema_file
|
|
293
|
+
for entry in schemas:
|
|
294
|
+
if entry.get("schema_version") == schema_version:
|
|
295
|
+
return entry, schema_file
|
|
296
|
+
else:
|
|
297
|
+
return schemas, schema_file
|
|
298
|
+
|
|
299
|
+
raise ValueError(f"Schema version {schema_version} not found for {parameter_name}")
|
|
300
|
+
|
|
301
|
+
def _find_highest_schema_version(self, schema_list):
|
|
302
|
+
"""
|
|
303
|
+
Find entry with highest schema_version in a list of schema dicts.
|
|
304
|
+
|
|
305
|
+
Parameters
|
|
306
|
+
----------
|
|
307
|
+
schema_list: list
|
|
308
|
+
List of schema dictionaries.
|
|
309
|
+
|
|
310
|
+
Returns
|
|
311
|
+
-------
|
|
312
|
+
dict
|
|
313
|
+
Schema dictionary with highest schema_version.
|
|
314
|
+
"""
|
|
315
|
+
try:
|
|
316
|
+
valid_entries = [entry for entry in schema_list if "schema_version" in entry]
|
|
317
|
+
except TypeError as exc:
|
|
318
|
+
raise TypeError("No valid schema versions found in the list.") from exc
|
|
319
|
+
return max(valid_entries, key=lambda e: packaging.version.Version(e["schema_version"]))
|
|
320
|
+
|
|
263
321
|
def _get_parameter_type(self):
|
|
264
322
|
"""
|
|
265
323
|
Return parameter type from schema.
|
|
266
324
|
|
|
325
|
+
Reduce list of types to single type if all types are the same.
|
|
326
|
+
|
|
267
327
|
Returns
|
|
268
328
|
-------
|
|
269
|
-
str
|
|
329
|
+
str or list[str]
|
|
270
330
|
Parameter type
|
|
271
331
|
"""
|
|
272
|
-
_parameter_type = []
|
|
273
|
-
|
|
274
|
-
_parameter_type
|
|
275
|
-
|
|
332
|
+
_parameter_type = [data["type"] for data in self.schema_dict["data"]]
|
|
333
|
+
return (
|
|
334
|
+
_parameter_type[0]
|
|
335
|
+
if all(t == _parameter_type[0] for t in _parameter_type)
|
|
336
|
+
else _parameter_type
|
|
337
|
+
)
|
|
276
338
|
|
|
277
339
|
def _parameter_is_a_file(self):
|
|
278
340
|
"""
|
|
@@ -399,7 +461,7 @@ class ModelDataWriter:
|
|
|
399
461
|
ascii_handler.write_data_to_file(
|
|
400
462
|
data=data_dict,
|
|
401
463
|
output_file=self.io_handler.get_output_file(file_name),
|
|
402
|
-
sort_keys=
|
|
464
|
+
sort_keys=True,
|
|
403
465
|
numpy_types=True,
|
|
404
466
|
)
|
|
405
467
|
|
simtools/data_model/schema.py
CHANGED
|
@@ -4,9 +4,12 @@ import logging
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
import jsonschema
|
|
7
|
+
from packaging.specifiers import SpecifierSet
|
|
8
|
+
from packaging.version import Version
|
|
7
9
|
from referencing import Registry, Resource
|
|
8
10
|
|
|
9
11
|
import simtools.utils.general as gen
|
|
12
|
+
from simtools import version
|
|
10
13
|
from simtools.constants import (
|
|
11
14
|
METADATA_JSON_SCHEMA,
|
|
12
15
|
MODEL_PARAMETER_METASCHEMA,
|
|
@@ -66,7 +69,7 @@ def get_model_parameter_schema_file(parameter):
|
|
|
66
69
|
|
|
67
70
|
def get_model_parameter_schema_version(schema_version=None):
|
|
68
71
|
"""
|
|
69
|
-
Validate
|
|
72
|
+
Validate and return schema versions.
|
|
70
73
|
|
|
71
74
|
If no schema_version is given, the most recent version is provided.
|
|
72
75
|
|
|
@@ -92,7 +95,9 @@ def get_model_parameter_schema_version(schema_version=None):
|
|
|
92
95
|
raise ValueError(f"Schema version {schema_version} not found in {MODEL_PARAMETER_METASCHEMA}.")
|
|
93
96
|
|
|
94
97
|
|
|
95
|
-
def validate_dict_using_schema(
|
|
98
|
+
def validate_dict_using_schema(
|
|
99
|
+
data, schema_file=None, json_schema=None, ignore_software_version=False
|
|
100
|
+
):
|
|
96
101
|
"""
|
|
97
102
|
Validate a data dictionary against a schema.
|
|
98
103
|
|
|
@@ -102,6 +107,10 @@ def validate_dict_using_schema(data, schema_file=None, json_schema=None):
|
|
|
102
107
|
dictionary to be validated
|
|
103
108
|
schema_file (dict)
|
|
104
109
|
schema used for validation
|
|
110
|
+
json_schema (dict)
|
|
111
|
+
schema used for validation
|
|
112
|
+
ignore_software_version: bool
|
|
113
|
+
If True, ignore software version check.
|
|
105
114
|
|
|
106
115
|
Raises
|
|
107
116
|
------
|
|
@@ -115,6 +124,8 @@ def validate_dict_using_schema(data, schema_file=None, json_schema=None):
|
|
|
115
124
|
if json_schema is None:
|
|
116
125
|
json_schema = load_schema(schema_file, get_schema_version_from_data(data))
|
|
117
126
|
|
|
127
|
+
_validate_deprecation_and_version(data, ignore_software_version)
|
|
128
|
+
|
|
118
129
|
validator = jsonschema.Draft6Validator(
|
|
119
130
|
schema=json_schema,
|
|
120
131
|
format_checker=format_checkers.format_checker,
|
|
@@ -294,3 +305,51 @@ def _add_array_elements(key, schema):
|
|
|
294
305
|
|
|
295
306
|
recursive_search(schema, key)
|
|
296
307
|
return schema
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def _validate_deprecation_and_version(
|
|
311
|
+
data, software_name="simtools", ignore_software_version=False
|
|
312
|
+
):
|
|
313
|
+
"""
|
|
314
|
+
Check if data contains deprecated parameters or version mismatches.
|
|
315
|
+
|
|
316
|
+
Parameters
|
|
317
|
+
----------
|
|
318
|
+
data: dict
|
|
319
|
+
Data dictionary to check.
|
|
320
|
+
software_name: str
|
|
321
|
+
Name of the software to check version against.
|
|
322
|
+
ignore_software_version: bool
|
|
323
|
+
If True, ignore software version check.
|
|
324
|
+
"""
|
|
325
|
+
if not isinstance(data, dict):
|
|
326
|
+
return
|
|
327
|
+
|
|
328
|
+
if data.get("deprecated", False):
|
|
329
|
+
note = data.get("deprecation_note", "(no deprecation note provided)")
|
|
330
|
+
_logger.warning(f"Data is deprecated. Note: {note}")
|
|
331
|
+
|
|
332
|
+
def check_version(sw):
|
|
333
|
+
constraint = sw.get("version")
|
|
334
|
+
if constraint is None:
|
|
335
|
+
return
|
|
336
|
+
constraint = constraint.strip()
|
|
337
|
+
spec = SpecifierSet(constraint, prereleases=True)
|
|
338
|
+
if Version(version.__version__) in spec:
|
|
339
|
+
_logger.debug(
|
|
340
|
+
f"Version {version.__version__} of {software_name} matches constraint {constraint}."
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
msg = (
|
|
344
|
+
f"Version {version.__version__} of {software_name} "
|
|
345
|
+
f"does not match constraint {constraint}."
|
|
346
|
+
)
|
|
347
|
+
if ignore_software_version:
|
|
348
|
+
_logger.warning(f"{msg}, but version check is ignored.")
|
|
349
|
+
return
|
|
350
|
+
raise ValueError(msg)
|
|
351
|
+
|
|
352
|
+
for sw in data.get("simulation_software", []):
|
|
353
|
+
if sw.get("name") == software_name:
|
|
354
|
+
check_version(sw)
|
|
355
|
+
break
|
|
@@ -232,7 +232,7 @@ class DataValidator:
|
|
|
232
232
|
else:
|
|
233
233
|
self._check_data_type(np.array(value).dtype, index, value)
|
|
234
234
|
|
|
235
|
-
if self.
|
|
235
|
+
if self._get_data_description(index).get("type", None) not in ("string", "dict", "file"):
|
|
236
236
|
self._check_for_not_a_number(value, index)
|
|
237
237
|
value, unit = self._check_and_convert_units(value, unit, index)
|
|
238
238
|
for range_type in ("allowed_range", "required_range"):
|