gammasimtools 0.8.1__py3-none-any.whl → 0.9.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.
Files changed (296) hide show
  1. {gammasimtools-0.8.1.dist-info → gammasimtools-0.9.0.dist-info}/METADATA +4 -3
  2. gammasimtools-0.9.0.dist-info/RECORD +350 -0
  3. {gammasimtools-0.8.1.dist-info → gammasimtools-0.9.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.8.1.dist-info → gammasimtools-0.9.0.dist-info}/entry_points.txt +2 -0
  5. simtools/_dev_version/__init__.py +9 -0
  6. simtools/_version.py +2 -2
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +1 -1
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +8 -9
  9. simtools/applications/convert_model_parameter_from_simtel.py +1 -1
  10. simtools/applications/db_add_model_parameters_from_repository_to_db.py +2 -10
  11. simtools/applications/db_add_value_from_json_to_db.py +1 -9
  12. simtools/applications/db_get_array_layouts_from_db.py +3 -1
  13. simtools/applications/db_get_parameter_from_db.py +1 -1
  14. simtools/applications/derive_mirror_rnda.py +10 -1
  15. simtools/applications/derive_psf_parameters.py +1 -1
  16. simtools/applications/generate_array_config.py +1 -5
  17. simtools/applications/generate_regular_arrays.py +9 -6
  18. simtools/applications/generate_simtel_array_histograms.py +1 -1
  19. simtools/applications/plot_array_layout.py +3 -1
  20. simtools/applications/plot_tabular_data.py +84 -0
  21. simtools/applications/production_scale_events.py +1 -2
  22. simtools/applications/simulate_light_emission.py +2 -2
  23. simtools/applications/simulate_prod.py +24 -59
  24. simtools/applications/simulate_prod_htcondor_generator.py +95 -0
  25. simtools/applications/submit_data_from_external.py +1 -1
  26. simtools/applications/validate_camera_efficiency.py +1 -1
  27. simtools/applications/validate_camera_fov.py +4 -8
  28. simtools/applications/validate_cumulative_psf.py +3 -7
  29. simtools/applications/validate_file_using_schema.py +31 -23
  30. simtools/applications/validate_optics.py +3 -4
  31. simtools/camera_efficiency.py +1 -4
  32. simtools/configuration/commandline_parser.py +9 -15
  33. simtools/configuration/configurator.py +6 -19
  34. simtools/constants.py +3 -3
  35. simtools/data_model/metadata_collector.py +19 -1
  36. simtools/data_model/metadata_model.py +18 -5
  37. simtools/data_model/model_data_writer.py +1 -1
  38. simtools/data_model/validate_data.py +67 -10
  39. simtools/db/db_handler.py +92 -315
  40. simtools/io_operations/legacy_data_handler.py +61 -0
  41. simtools/job_execution/htcondor_script_generator.py +133 -0
  42. simtools/job_execution/job_manager.py +77 -50
  43. simtools/model/array_model.py +30 -26
  44. simtools/model/calibration_model.py +10 -10
  45. simtools/model/camera.py +79 -63
  46. simtools/model/mirrors.py +8 -6
  47. simtools/model/model_parameter.py +42 -12
  48. simtools/model/model_utils.py +6 -6
  49. simtools/model/site_model.py +2 -2
  50. simtools/model/telescope_model.py +26 -22
  51. simtools/ray_tracing/mirror_panel_psf.py +47 -27
  52. simtools/runners/corsika_runner.py +14 -3
  53. simtools/runners/runner_services.py +3 -3
  54. simtools/runners/simtel_runner.py +27 -8
  55. simtools/schemas/integration_tests_config.metaschema.yml +15 -5
  56. simtools/schemas/model_parameter.metaschema.yml +90 -2
  57. simtools/schemas/model_parameters/adjust_gain.schema.yml +1 -1
  58. simtools/schemas/model_parameters/altitude.schema.yml +1 -1
  59. simtools/schemas/model_parameters/array_coordinates.schema.yml +1 -1
  60. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +1 -1
  61. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +1 -1
  62. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +1 -1
  63. simtools/schemas/model_parameters/array_layouts.schema.yml +1 -1
  64. simtools/schemas/model_parameters/array_triggers.schema.yml +1 -1
  65. simtools/schemas/model_parameters/asum_clipping.schema.yml +1 -1
  66. simtools/schemas/model_parameters/asum_offset.schema.yml +1 -1
  67. simtools/schemas/model_parameters/asum_shaping.schema.yml +1 -1
  68. simtools/schemas/model_parameters/asum_threshold.schema.yml +1 -1
  69. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +1 -1
  70. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +1 -1
  71. simtools/schemas/model_parameters/axes_offsets.schema.yml +1 -1
  72. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +1 -1
  73. simtools/schemas/model_parameters/camera_body_shape.schema.yml +1 -1
  74. simtools/schemas/model_parameters/camera_config_file.schema.yml +1 -1
  75. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +1 -1
  76. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +1 -1
  77. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +1 -1
  78. simtools/schemas/model_parameters/camera_depth.schema.yml +1 -1
  79. simtools/schemas/model_parameters/camera_filter.schema.yml +1 -1
  80. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +1 -1
  81. simtools/schemas/model_parameters/camera_pixels.schema.yml +1 -1
  82. simtools/schemas/model_parameters/camera_transmission.schema.yml +1 -1
  83. simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
  84. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +1 -1
  85. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +1 -1
  86. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +1 -1
  87. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +1 -1
  88. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +1 -1
  89. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +1 -1
  90. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +1 -1
  91. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +1 -1
  92. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +1 -1
  93. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +1 -1
  94. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +1 -1
  95. simtools/schemas/model_parameters/dark_events.schema.yml +1 -1
  96. simtools/schemas/model_parameters/default_trigger.schema.yml +1 -1
  97. simtools/schemas/model_parameters/design_model.schema.yml +1 -1
  98. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +1 -1
  99. simtools/schemas/model_parameters/disc_bins.schema.yml +1 -1
  100. simtools/schemas/model_parameters/disc_start.schema.yml +1 -1
  101. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +1 -1
  102. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +1 -1
  103. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +1 -1
  104. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +1 -1
  105. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +1 -1
  106. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +1 -1
  107. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +1 -1
  108. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +1 -1
  109. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +1 -1
  110. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +1 -1
  111. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +1 -1
  112. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -1
  113. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +1 -1
  114. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +1 -1
  115. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +1 -1
  116. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +1 -1
  117. simtools/schemas/model_parameters/dish_shape_length.schema.yml +1 -1
  118. simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -1
  119. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +1 -1
  120. simtools/schemas/model_parameters/dsum_offset.schema.yml +1 -1
  121. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +1 -1
  122. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +1 -1
  123. simtools/schemas/model_parameters/dsum_prescale.schema.yml +1 -1
  124. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +1 -1
  125. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +1 -1
  126. simtools/schemas/model_parameters/dsum_shaping.schema.yml +1 -1
  127. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +1 -1
  128. simtools/schemas/model_parameters/dsum_threshold.schema.yml +1 -1
  129. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +1 -1
  130. simtools/schemas/model_parameters/effective_focal_length.schema.yml +32 -2
  131. simtools/schemas/model_parameters/epsg_code.schema.yml +1 -1
  132. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +1 -1
  133. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +1 -1
  134. simtools/schemas/model_parameters/fadc_bins.schema.yml +1 -1
  135. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
  136. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +1 -1
  137. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +1 -1
  138. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +1 -1
  139. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +1 -1
  140. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
  141. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +1 -1
  142. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +1 -1
  143. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +1 -1
  144. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +1 -1
  145. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +1 -1
  146. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +1 -1
  147. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +1 -1
  148. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +1 -1
  149. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +1 -1
  150. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +1 -1
  151. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +1 -1
  152. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +1 -1
  153. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +1 -1
  154. simtools/schemas/model_parameters/fadc_mhz.schema.yml +1 -1
  155. simtools/schemas/model_parameters/fadc_noise.schema.yml +1 -1
  156. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +1 -1
  157. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +1 -1
  158. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +1 -1
  159. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +1 -1
  160. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +1 -1
  161. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +1 -1
  162. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +1 -1
  163. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +1 -1
  164. simtools/schemas/model_parameters/flatfielding.schema.yml +1 -1
  165. simtools/schemas/model_parameters/focal_length.schema.yml +1 -1
  166. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +1 -1
  167. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +1 -1
  168. simtools/schemas/model_parameters/focus_offset.schema.yml +1 -1
  169. simtools/schemas/model_parameters/gain_variation.schema.yml +1 -1
  170. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +1 -1
  171. simtools/schemas/model_parameters/geomag_rotation.schema.yml +1 -1
  172. simtools/schemas/model_parameters/geomag_vertical.schema.yml +1 -1
  173. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +1 -1
  174. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
  175. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
  176. simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
  177. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +1 -1
  178. simtools/schemas/model_parameters/laser_photons.schema.yml +1 -1
  179. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +1 -1
  180. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +1 -1
  181. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +1 -1
  182. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +1 -1
  183. simtools/schemas/model_parameters/laser_var_photons.schema.yml +1 -1
  184. simtools/schemas/model_parameters/laser_wavelength.schema.yml +1 -1
  185. simtools/schemas/model_parameters/led_events.schema.yml +1 -1
  186. simtools/schemas/model_parameters/led_photons.schema.yml +1 -1
  187. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +1 -1
  188. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +1 -1
  189. simtools/schemas/model_parameters/led_var_photons.schema.yml +1 -1
  190. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
  191. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
  192. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
  193. simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
  194. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +1 -1
  195. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +1 -1
  196. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +1 -1
  197. simtools/schemas/model_parameters/mirror_class.schema.yml +1 -1
  198. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +1 -1
  199. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +1 -1
  200. simtools/schemas/model_parameters/mirror_list.schema.yml +1 -1
  201. simtools/schemas/model_parameters/mirror_offset.schema.yml +1 -1
  202. simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +1 -1
  203. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +1 -1
  204. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +1 -1
  205. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +1 -1
  206. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +1 -1
  207. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +1 -1
  208. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +1 -1
  209. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +1 -1
  210. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +1 -1
  211. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +1 -1
  212. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +1 -1
  213. simtools/schemas/model_parameters/nsb_skymap.schema.yml +1 -1
  214. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +1 -1
  215. simtools/schemas/model_parameters/num_gains.schema.yml +1 -1
  216. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +1 -1
  217. simtools/schemas/model_parameters/optics_properties.schema.yml +1 -1
  218. simtools/schemas/model_parameters/parabolic_dish.schema.yml +1 -1
  219. simtools/schemas/model_parameters/pedestal_events.schema.yml +1 -1
  220. simtools/schemas/model_parameters/photon_delay.schema.yml +1 -1
  221. simtools/schemas/model_parameters/photons_per_run.schema.yml +1 -1
  222. simtools/schemas/model_parameters/pixel_cells.schema.yml +1 -1
  223. simtools/schemas/model_parameters/pixels_parallel.schema.yml +1 -1
  224. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +1 -1
  225. simtools/schemas/model_parameters/pm_average_gain.schema.yml +1 -1
  226. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +1 -1
  227. simtools/schemas/model_parameters/pm_gain_index.schema.yml +1 -1
  228. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +1 -1
  229. simtools/schemas/model_parameters/pm_transit_time.schema.yml +1 -1
  230. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +1 -1
  231. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +1 -1
  232. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +1 -1
  233. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +1 -1
  234. simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +1 -1
  235. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +1 -1
  236. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +1 -1
  237. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +1 -1
  238. simtools/schemas/model_parameters/qe_variation.schema.yml +1 -1
  239. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +1 -1
  240. simtools/schemas/model_parameters/random_focal_length.schema.yml +1 -1
  241. simtools/schemas/model_parameters/random_generator.schema.yml +1 -1
  242. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +1 -1
  243. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +1 -1
  244. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +1 -1
  245. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +1 -1
  246. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +1 -1
  247. simtools/schemas/model_parameters/sampled_output.schema.yml +1 -1
  248. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +1 -1
  249. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +1 -1
  250. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +1 -1
  251. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
  252. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +1 -1
  253. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +1 -1
  254. simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +1 -1
  255. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +1 -1
  256. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +1 -1
  257. simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +1 -1
  258. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +1 -1
  259. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +1 -1
  260. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +1 -1
  261. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
  262. simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
  263. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +1 -1
  264. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +1 -1
  265. simtools/schemas/model_parameters/telescope_random_error.schema.yml +1 -1
  266. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +1 -1
  267. simtools/schemas/model_parameters/telescope_transmission.schema.yml +1 -1
  268. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +1 -1
  269. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +1 -1
  270. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +1 -1
  271. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +1 -1
  272. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +1 -1
  273. simtools/schemas/model_parameters/transit_time_error.schema.yml +1 -1
  274. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +1 -1
  275. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +1 -1
  276. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +1 -1
  277. simtools/schemas/model_parameters/trigger_pixels.schema.yml +1 -1
  278. simtools/simtel/simtel_table_reader.py +410 -0
  279. simtools/simtel/simulator_camera_efficiency.py +6 -4
  280. simtools/simtel/simulator_light_emission.py +2 -2
  281. simtools/simtel/simulator_ray_tracing.py +1 -2
  282. simtools/simulator.py +80 -33
  283. simtools/testing/configuration.py +12 -8
  284. simtools/testing/helpers.py +5 -5
  285. simtools/testing/validate_output.py +28 -28
  286. simtools/utils/general.py +50 -3
  287. simtools/utils/names.py +3 -4
  288. simtools/utils/value_conversion.py +9 -1
  289. simtools/version.py +1 -1
  290. simtools/visualization/plot_tables.py +106 -0
  291. simtools/visualization/visualize.py +43 -5
  292. gammasimtools-0.8.1.dist-info/RECORD +0 -346
  293. simtools/_dev_version/scm_version.py +0 -10
  294. simtools/db/db_from_repo_handler.py +0 -106
  295. {gammasimtools-0.8.1.dist-info → gammasimtools-0.9.0.dist-info}/LICENSE +0 -0
  296. {gammasimtools-0.8.1.dist-info → gammasimtools-0.9.0.dist-info}/top_level.txt +0 -0
@@ -1,25 +1,25 @@
1
1
  """Helper functions for integration testing."""
2
2
 
3
3
  import os
4
-
5
- import pytest
4
+ from pathlib import Path
6
5
 
7
6
 
8
7
  def skip_camera_efficiency(config):
9
8
  """Skip camera efficiency tests if the old version of testeff is used."""
10
9
  if "camera-efficiency" in config["APPLICATION"]:
11
10
  if not _new_testeff_version():
12
- pytest.skip(
11
+ return (
13
12
  "Any applications calling the old version of testeff are skipped "
14
13
  "due to a limitation of the old testeff not allowing to specify "
15
14
  "the include directory. Please update your sim_telarray tarball."
16
15
  )
17
16
  full_test_name = f"{config['APPLICATION']}_{config['TEST_NAME']}"
18
17
  if "simtools-validate-camera-efficiency_SSTS" == full_test_name:
19
- pytest.skip(
18
+ return (
20
19
  "The test simtools-validate-camera-efficiency_SSTS is skipped "
21
20
  "since the fake SST mirrors are not yet implemented (#1155)"
22
21
  )
22
+ return None
23
23
 
24
24
 
25
25
  def _new_testeff_version():
@@ -28,7 +28,7 @@ def _new_testeff_version():
28
28
 
29
29
  This test checks if the new version is used.
30
30
  """
31
- testeff_path = os.path.join(os.getenv("SIMTOOLS_SIMTEL_PATH"), "sim_telarray/testeff.c")
31
+ testeff_path = Path(os.getenv("SIMTOOLS_SIMTEL_PATH")) / "sim_telarray/testeff.c"
32
32
  try:
33
33
  with open(testeff_path, encoding="utf-8") as file:
34
34
  file_content = file.read()
@@ -55,8 +55,13 @@ def validate_application_output(config):
55
55
  if "REFERENCE_OUTPUT_FILE" in integration_test:
56
56
  _validate_reference_output_file(config, integration_test)
57
57
 
58
+ if "TEST_OUTPUT_FILES" in integration_test:
59
+ _validate_output_path_and_file(config, integration_test["TEST_OUTPUT_FILES"])
58
60
  if "OUTPUT_FILE" in integration_test:
59
- _validate_output_path_and_file(config, integration_test)
61
+ _validate_output_path_and_file(
62
+ config,
63
+ [{"PATH_DESCRIPTOR": "OUTPUT_PATH", "FILE": integration_test["OUTPUT_FILE"]}],
64
+ )
60
65
 
61
66
  if "FILE_TYPE" in integration_test:
62
67
  assert assertions.assert_file_type(
@@ -79,31 +84,25 @@ def _validate_reference_output_file(config, integration_test):
79
84
  )
80
85
 
81
86
 
82
- def _validate_output_path_and_file(config, integration_test):
83
- """Check if output path and file exist."""
84
- _logger.info(f"PATH {config['CONFIGURATION']['OUTPUT_PATH']}")
85
- _logger.info(f"File {integration_test['OUTPUT_FILE']}")
86
-
87
- data_path = config["CONFIGURATION"].get(
88
- "DATA_DIRECTORY", config["CONFIGURATION"]["OUTPUT_PATH"]
89
- )
90
- output_file_path = Path(data_path) / integration_test["OUTPUT_FILE"]
91
-
92
- _logger.info(f"Checking path: {output_file_path}")
93
- assert output_file_path.exists()
94
-
95
- expected_output = [
96
- d["EXPECTED_OUTPUT"] for d in config["INTEGRATION_TESTS"] if "EXPECTED_OUTPUT" in d
97
- ]
98
- if expected_output and "log_hist" not in integration_test["OUTPUT_FILE"]:
99
- # Get the expected output from the configuration file
100
- expected_output = expected_output[0]
101
- _logger.info(
102
- f"Checking the output of {integration_test['OUTPUT_FILE']} "
103
- "complies with the expected output: "
104
- f"{expected_output}"
105
- )
106
- assert assertions.check_output_from_sim_telarray(output_file_path, expected_output)
87
+ def _validate_output_path_and_file(config, integration_file_tests):
88
+ """Check if output paths and files exist."""
89
+ for file_test in integration_file_tests:
90
+ try:
91
+ output_path = config["CONFIGURATION"][file_test["PATH_DESCRIPTOR"]]
92
+ except KeyError as exc:
93
+ raise KeyError(
94
+ f"Path {file_test['PATH_DESCRIPTOR']} not found in integration test configuration."
95
+ ) from exc
96
+
97
+ output_file_path = Path(output_path) / file_test["FILE"]
98
+ _logger.info(f"Checking path: {output_file_path}")
99
+ assert output_file_path.exists()
100
+
101
+ if "EXPECTED_OUTPUT" in file_test:
102
+ assert assertions.check_output_from_sim_telarray(
103
+ output_file_path,
104
+ file_test["EXPECTED_OUTPUT"],
105
+ )
107
106
 
108
107
 
109
108
  def compare_files(file1, file2, tolerance=1.0e-5, test_columns=None):
@@ -124,7 +123,7 @@ def compare_files(file1, file2, tolerance=1.0e-5, test_columns=None):
124
123
  Returns
125
124
  -------
126
125
  bool
127
- True if the files are equal, False otherwise.
126
+ True if the files are equal.
128
127
 
129
128
  """
130
129
  _file1_suffix = Path(file1).suffix
@@ -158,7 +157,7 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
158
157
  Returns
159
158
  -------
160
159
  bool
161
- True if the files are equal, False otherwise.
160
+ True if the files are equal.
162
161
 
163
162
  """
164
163
  data1 = gen.collect_data_from_file(file1)
@@ -235,6 +234,7 @@ def compare_ecsv_files(file1, file2, tolerance=1.0e-5, test_columns=None):
235
234
 
236
235
  if np.issubdtype(table1_masked[col_name].dtype, np.floating):
237
236
  if not np.allclose(table1_masked[col_name], table2_masked[col_name], rtol=tolerance):
237
+ _logger.warning(f"Column {col_name} outside of relative tolerance {tolerance}")
238
238
  return False
239
239
 
240
240
  return True
simtools/utils/general.py CHANGED
@@ -164,6 +164,9 @@ def collect_data_from_file(file_name):
164
164
  return yaml.safe_load(file)
165
165
  except yaml.constructor.ConstructorError:
166
166
  return _load_yaml_using_astropy(file)
167
+ except yaml.composer.ComposerError:
168
+ file.seek(0)
169
+ return list(yaml.safe_load_all(file))
167
170
 
168
171
 
169
172
  def collect_kwargs(label, in_kwargs):
@@ -333,9 +336,10 @@ def program_is_executable(program):
333
336
  Follows https://stackoverflow.com/questions/377017/
334
337
 
335
338
  """
339
+ program = Path(program)
336
340
 
337
341
  def is_exe(fpath):
338
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
342
+ return fpath.is_file() and os.access(fpath, os.X_OK)
339
343
 
340
344
  fpath, _ = os.path.split(program)
341
345
  if fpath:
@@ -344,7 +348,7 @@ def program_is_executable(program):
344
348
  else:
345
349
  try:
346
350
  for path in os.environ["PATH"].split(os.pathsep):
347
- exe_file = os.path.join(path, program)
351
+ exe_file = Path(path) / program
348
352
  if is_exe(exe_file):
349
353
  return exe_file
350
354
  except KeyError:
@@ -442,7 +446,7 @@ def get_file_age(file_path):
442
446
  if not Path(file_path).is_file():
443
447
  raise FileNotFoundError(f"'{file_path}' does not exist or is not a file.")
444
448
 
445
- file_stats = os.stat(file_path)
449
+ file_stats = Path(file_path).stat()
446
450
  modification_time = file_stats.st_mtime
447
451
  current_time = time.time()
448
452
 
@@ -785,3 +789,46 @@ def read_file_encoded_in_utf_or_latin(file_name):
785
789
  raise UnicodeDecodeError("Unable to decode file using UTF-8 or Latin-1.") from exc
786
790
 
787
791
  return lines
792
+
793
+
794
+ def get_structure_array_from_table(table, column_names):
795
+ """
796
+ Get a structured array from an astropy table for a selected list of columns.
797
+
798
+ Parameters
799
+ ----------
800
+ table: astropy.table.Table
801
+ Table to be converted.
802
+ column_names: list
803
+ List of column names to be included in the structured array.
804
+
805
+ Returns
806
+ -------
807
+ numpy.ndarray
808
+ Structured array containing the table data.
809
+ """
810
+ return np.array(
811
+ list(zip(*[np.array(table[col]) for col in column_names])),
812
+ dtype=[(col, np.array(table[col]).dtype) for col in column_names],
813
+ )
814
+
815
+
816
+ def convert_keys_in_dict_to_lowercase(data):
817
+ """
818
+ Recursively convert all dictionary keys to lowercase.
819
+
820
+ Parameters
821
+ ----------
822
+ data: dict
823
+ Dictionary to be converted.
824
+
825
+ Returns
826
+ -------
827
+ dict
828
+ Dictionary with all keys converted to lowercase.
829
+ """
830
+ if isinstance(data, dict):
831
+ return {k.lower(): convert_keys_in_dict_to_lowercase(v) for k, v in data.items()}
832
+ if isinstance(data, list):
833
+ return [convert_keys_in_dict_to_lowercase(i) for i in data]
834
+ return data
simtools/utils/names.py CHANGED
@@ -1,9 +1,9 @@
1
1
  """Validation of names."""
2
2
 
3
- import glob
4
3
  import logging
5
4
  import re
6
5
  from functools import cache
6
+ from importlib.resources import files
7
7
  from pathlib import Path
8
8
 
9
9
  import yaml
@@ -34,8 +34,7 @@ def array_elements():
34
34
  dict
35
35
  Array elements.
36
36
  """
37
- base_path = Path(__file__).parent
38
- with open(base_path / "../schemas/array_elements.yml", encoding="utf-8") as file:
37
+ with open(files("simtools") / "schemas/array_elements.yml", encoding="utf-8") as file:
39
38
  return yaml.safe_load(file)["data"]
40
39
 
41
40
 
@@ -60,7 +59,7 @@ def site_names():
60
59
  @cache
61
60
  def load_model_parameters(class_key_list):
62
61
  model_parameters = {}
63
- schema_files = glob.glob(str(Path(__file__).parent / "../schemas/model_parameters") + "/*.yml")
62
+ schema_files = list(Path(files("simtools") / "schemas/model_parameters").rglob("*.yml"))
64
63
  for schema_file in schema_files:
65
64
  with open(schema_file, encoding="utf-8") as f:
66
65
  data = yaml.safe_load(f)
@@ -84,7 +84,7 @@ def get_value_unit_type(value, unit_str=None):
84
84
  pass
85
85
  base_unit = unit_str
86
86
 
87
- return base_value, base_unit, base_type
87
+ return base_value, _unit_as_string(base_unit), base_type
88
88
 
89
89
 
90
90
  def split_value_and_unit(value):
@@ -174,3 +174,11 @@ def get_value_as_quantity(value, unit):
174
174
  _logger.error(f"Cannot convert {value.unit} to {unit}.")
175
175
  raise
176
176
  return value * unit
177
+
178
+
179
+ def _unit_as_string(unit):
180
+ """Return the string representation of a unit. Collapse if it is a list of identical items."""
181
+ if not isinstance(unit, list):
182
+ unit = [unit]
183
+ unit = [str(element) if element is not None else None for element in unit]
184
+ return unit[0] if len(set(unit)) == 1 else unit
simtools/version.py CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  try:
8
8
  try:
9
- from ._dev.scm_version import version
9
+ from ._dev_version import version
10
10
  except ImportError:
11
11
  from ._version import version
12
12
  except Exception:
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/python3
2
+ """Plot tabular data."""
3
+
4
+ import numpy as np
5
+
6
+ import simtools.utils.general as gen
7
+ from simtools.io_operations import legacy_data_handler
8
+ from simtools.model.site_model import SiteModel
9
+ from simtools.model.telescope_model import TelescopeModel
10
+ from simtools.visualization import visualize
11
+
12
+
13
+ def plot(config, output_file, db_config=None):
14
+ """
15
+ Plot tabular data from data or from model parameter files.
16
+
17
+ Parameters
18
+ ----------
19
+ config: dict
20
+ Configuration dictionary for plotting.
21
+ output_file: str
22
+ Output file.
23
+ """
24
+ data = read_table_data(config, db_config)
25
+
26
+ fig = visualize.plot_1d(
27
+ data,
28
+ **config,
29
+ )
30
+ visualize.save_figure(fig, output_file)
31
+
32
+
33
+ def read_table_data(config, db_config):
34
+ """
35
+ Read table data from file or parameter database.
36
+
37
+ Parameters
38
+ ----------
39
+ config: dict
40
+ Configuration dictionary for plotting.
41
+
42
+ Returns
43
+ -------
44
+ Dict
45
+ Dict with table data (astropy tables).
46
+ """
47
+ data = {}
48
+
49
+ for _config in config["tables"]:
50
+ if "parameter" in _config:
51
+ table = _read_table_from_model_database(_config, db_config)
52
+ elif "file_name" in _config:
53
+ table = legacy_data_handler.read_legacy_data_as_table(
54
+ _config["file_name"], _config["type"]
55
+ )
56
+ else:
57
+ raise ValueError("No table data defined in configuration.")
58
+ if _config.get("normalize_y"):
59
+ table[_config["column_y"]] = (
60
+ table[_config["column_y"]] / table[_config["column_y"]].max()
61
+ )
62
+ if _config.get("select_values"):
63
+ table = _select_values_from_table(
64
+ table,
65
+ _config["select_values"]["column_name"],
66
+ _config["select_values"]["value"],
67
+ )
68
+ data[_config["label"]] = gen.get_structure_array_from_table(
69
+ table, [_config["column_x"], _config["column_y"]]
70
+ )
71
+ return data
72
+
73
+
74
+ def _read_table_from_model_database(table_config, db_config):
75
+ """
76
+ Read table data from model parameter database.
77
+
78
+ Parameters
79
+ ----------
80
+ table_config: dict
81
+ Configuration dictionary for table data.
82
+
83
+ Returns
84
+ -------
85
+ Table
86
+ Astropy table.
87
+ """
88
+ if "telescope" in table_config:
89
+ model = TelescopeModel(
90
+ site=table_config["site"],
91
+ telescope_name=table_config["telescope"],
92
+ model_version=table_config["model_version"],
93
+ mongo_db_config=db_config,
94
+ )
95
+ else:
96
+ model = SiteModel(
97
+ site=table_config["site"],
98
+ model_version=table_config["model_version"],
99
+ mongo_db_config=db_config,
100
+ )
101
+ return model.get_model_file_as_table(table_config["parameter"])
102
+
103
+
104
+ def _select_values_from_table(table, column_name, value):
105
+ """Return a table with only the rows where column_name == value."""
106
+ return table[np.isclose(table[column_name], value)]
@@ -5,6 +5,7 @@ import copy
5
5
  import logging
6
6
  import re
7
7
  from collections import OrderedDict
8
+ from pathlib import Path
8
9
 
9
10
  import astropy.units as u
10
11
  import matplotlib.patches as mpatches
@@ -27,6 +28,7 @@ __all__ = [
27
28
  "plot_array",
28
29
  "plot_hist_2d",
29
30
  "plot_table",
31
+ "save_figure",
30
32
  "set_style",
31
33
  ]
32
34
 
@@ -366,6 +368,12 @@ def handle_kwargs(kwargs):
366
368
  "empty_markers": False,
367
369
  "plot_ratio": False,
368
370
  "plot_difference": False,
371
+ "xscale": "linear",
372
+ "yscale": "linear",
373
+ "xlim": (None, None),
374
+ "ylim": (None, None),
375
+ "xtitle": None,
376
+ "ytitle": None,
369
377
  }
370
378
  for key, default in kwargs_defaults.items():
371
379
  kwargs[key] = kwargs.pop(key, default)
@@ -414,11 +422,17 @@ def plot_main_data(data_dict, kwargs, plot_args):
414
422
  """Plot the main data."""
415
423
  for label, data_now in data_dict.items():
416
424
  assert len(data_now.dtype.names) == 2, "Input array must have two columns with titles."
417
- x_title, y_title = data_now.dtype.names[0], data_now.dtype.names[1]
418
- x_title_unit = _add_unit(x_title, data_now[x_title])
419
- y_title_unit = _add_unit(y_title, data_now[y_title])
420
- plt.plot(data_now[x_title], data_now[y_title], label=label, **plot_args)
421
-
425
+ x_column_name, y_column_name = data_now.dtype.names[0], data_now.dtype.names[1]
426
+ x_title = kwargs["xtitle"] if kwargs.get("xtitle") else x_column_name
427
+ y_title = kwargs["ytitle"] if kwargs.get("ytitle") else y_column_name
428
+ x_title_unit = _add_unit(x_title, data_now[x_column_name])
429
+ y_title_unit = _add_unit(y_title, data_now[y_column_name])
430
+ plt.plot(data_now[x_column_name], data_now[y_column_name], label=label, **plot_args)
431
+
432
+ plt.xscale(kwargs["xscale"])
433
+ plt.yscale(kwargs["yscale"])
434
+ plt.xlim(kwargs["xlim"])
435
+ plt.ylim(kwargs["ylim"])
422
436
  plt.ylabel(y_title_unit)
423
437
  if not (kwargs["plot_ratio"] or kwargs["plot_difference"]):
424
438
  plt.xlabel(x_title_unit)
@@ -878,3 +892,27 @@ def plot_simtel_ctapipe(filename, cleaning_args, distance, return_cleaned=False)
878
892
  ax.set_axis_off()
879
893
  fig.tight_layout()
880
894
  return fig
895
+
896
+
897
+ def save_figure(fig, output_file, figure_format=None, log_title=""):
898
+ """
899
+ Save figure to output file(s).
900
+
901
+ Parameters
902
+ ----------
903
+ fig: plt.figure
904
+ Figure to save.
905
+ output_file: Path, str
906
+ Path to save the figure (without suffix).
907
+ figure_format: list
908
+ List of formats to save the figure.
909
+ title: str
910
+ Title of the figure to be added to the log message.
911
+ """
912
+ figure_format = figure_format or ["pdf", "png"]
913
+ for fmt in figure_format:
914
+ _file = Path(output_file).with_suffix(f".{fmt}")
915
+ fig.savefig(_file, format=fmt, bbox_inches="tight")
916
+ logging.info(f"Saved plot {log_title} to {_file}")
917
+
918
+ fig.clf()