gammasimtools 0.12.0__py3-none-any.whl → 0.14.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 (276) hide show
  1. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info}/METADATA +3 -3
  2. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info}/RECORD +257 -263
  3. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info}/entry_points.txt +4 -1
  5. simtools/_version.py +2 -2
  6. simtools/applications/convert_all_model_parameters_from_simtel.py +77 -88
  7. simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -1
  8. simtools/applications/db_add_file_to_db.py +15 -0
  9. simtools/applications/db_add_value_from_json_to_db.py +18 -1
  10. simtools/applications/db_get_parameter_from_db.py +52 -22
  11. simtools/applications/derive_ctao_array_layouts.py +120 -0
  12. simtools/applications/derive_photon_electron_spectrum.py +30 -2
  13. simtools/applications/docs_produce_array_element_report.py +42 -26
  14. simtools/applications/docs_produce_model_parameter_reports.py +28 -21
  15. simtools/applications/generate_simtel_event_data.py +117 -0
  16. simtools/applications/plot_tabular_data.py +14 -2
  17. simtools/applications/print_version.py +81 -0
  18. simtools/applications/production_derive_corsika_limits.py +240 -0
  19. simtools/applications/production_scale_events.py +59 -36
  20. simtools/applications/run_application.py +47 -18
  21. simtools/applications/simulate_light_emission.py +115 -247
  22. simtools/applications/simulate_prod_htcondor_generator.py +2 -2
  23. simtools/applications/submit_data_from_external.py +1 -1
  24. simtools/applications/submit_model_parameter_from_external.py +2 -1
  25. simtools/camera/single_photon_electron_spectrum.py +169 -17
  26. simtools/constants.py +7 -0
  27. simtools/data_model/metadata_collector.py +159 -61
  28. simtools/data_model/model_data_writer.py +18 -61
  29. simtools/data_model/schema.py +2 -1
  30. simtools/data_model/validate_data.py +5 -3
  31. simtools/db/db_handler.py +123 -33
  32. simtools/dependencies.py +38 -3
  33. simtools/layout/array_layout.py +1 -0
  34. simtools/layout/ctao_array_layouts.py +172 -0
  35. simtools/model/array_model.py +3 -4
  36. simtools/model/model_parameter.py +30 -118
  37. simtools/production_configuration/derive_corsika_limits.py +328 -0
  38. simtools/production_configuration/event_scaler.py +2 -2
  39. simtools/ray_tracing/mirror_panel_psf.py +1 -1
  40. simtools/reporting/docs_auto_report_generator.py +217 -0
  41. simtools/reporting/docs_read_parameters.py +298 -143
  42. simtools/schemas/application_workflow.metaschema.yml +3 -0
  43. simtools/schemas/metadata.metaschema.yml +7 -6
  44. simtools/schemas/model_parameter.metaschema.yml +13 -4
  45. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +19 -5
  46. simtools/schemas/model_parameters/adjust_gain.schema.yml +1 -1
  47. simtools/schemas/model_parameters/altitude.schema.yml +1 -1
  48. simtools/schemas/model_parameters/array_coordinates.schema.yml +1 -1
  49. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +3 -3
  50. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +3 -3
  51. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +3 -3
  52. simtools/schemas/model_parameters/array_layouts.schema.yml +3 -0
  53. simtools/schemas/model_parameters/array_window.schema.yml +1 -1
  54. simtools/schemas/model_parameters/asum_clipping.schema.yml +1 -1
  55. simtools/schemas/model_parameters/asum_offset.schema.yml +1 -1
  56. simtools/schemas/model_parameters/asum_shaping.schema.yml +1 -1
  57. simtools/schemas/model_parameters/asum_threshold.schema.yml +1 -1
  58. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +1 -1
  59. simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
  60. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +1 -1
  61. simtools/schemas/model_parameters/camera_body_shape.schema.yml +1 -1
  62. simtools/schemas/model_parameters/camera_config_file.schema.yml +1 -1
  63. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +1 -1
  64. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +1 -1
  65. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +1 -1
  66. simtools/schemas/model_parameters/camera_depth.schema.yml +1 -1
  67. simtools/schemas/model_parameters/camera_filter.schema.yml +1 -1
  68. simtools/schemas/model_parameters/camera_pixels.schema.yml +1 -1
  69. simtools/schemas/model_parameters/camera_transmission.schema.yml +1 -1
  70. simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
  71. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +1 -1
  72. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +1 -1
  73. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +1 -1
  74. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +1 -1
  75. simtools/schemas/model_parameters/dark_events.schema.yml +1 -1
  76. simtools/schemas/model_parameters/disc_bins.schema.yml +1 -1
  77. simtools/schemas/model_parameters/disc_start.schema.yml +1 -1
  78. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +1 -1
  79. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +1 -1
  80. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +1 -1
  81. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +1 -1
  82. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +1 -1
  83. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +1 -1
  84. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +1 -1
  85. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +1 -1
  86. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +1 -1
  87. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +1 -1
  88. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -1
  89. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +1 -1
  90. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +1 -1
  91. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +1 -1
  92. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +1 -1
  93. simtools/schemas/model_parameters/dish_shape_length.schema.yml +1 -1
  94. simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -1
  95. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +1 -1
  96. simtools/schemas/model_parameters/dsum_offset.schema.yml +1 -1
  97. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +1 -1
  98. simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
  99. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +1 -1
  100. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +1 -1
  101. simtools/schemas/model_parameters/dsum_shaping.schema.yml +1 -1
  102. simtools/schemas/model_parameters/dsum_threshold.schema.yml +1 -1
  103. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +1 -1
  104. simtools/schemas/model_parameters/effective_focal_length.schema.yml +5 -5
  105. simtools/schemas/model_parameters/epsg_code.schema.yml +1 -1
  106. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +1 -1
  107. simtools/schemas/model_parameters/fadc_bins.schema.yml +1 -1
  108. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
  109. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +2 -2
  110. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +1 -1
  111. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +1 -1
  112. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +1 -1
  113. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
  114. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +2 -2
  115. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +1 -1
  116. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +1 -1
  117. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +1 -1
  118. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +4 -4
  119. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +1 -1
  120. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +1 -1
  121. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +1 -1
  122. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +1 -1
  123. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +1 -1
  124. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +1 -1
  125. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +1 -1
  126. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +4 -4
  127. simtools/schemas/model_parameters/fadc_mhz.schema.yml +1 -1
  128. simtools/schemas/model_parameters/fadc_noise.schema.yml +1 -1
  129. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +1 -1
  130. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +1 -1
  131. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +1 -1
  132. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +1 -1
  133. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +1 -1
  134. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +1 -1
  135. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +1 -1
  136. simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
  137. simtools/schemas/model_parameters/focal_length.schema.yml +1 -1
  138. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +20 -20
  139. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +1 -1
  140. simtools/schemas/model_parameters/focus_offset.schema.yml +4 -4
  141. simtools/schemas/model_parameters/gain_variation.schema.yml +1 -1
  142. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +1 -1
  143. simtools/schemas/model_parameters/geomag_rotation.schema.yml +1 -1
  144. simtools/schemas/model_parameters/geomag_vertical.schema.yml +1 -1
  145. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +1 -1
  146. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
  147. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
  148. simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
  149. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +1 -1
  150. simtools/schemas/model_parameters/laser_photons.schema.yml +1 -1
  151. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +1 -1
  152. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +1 -1
  153. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +1 -1
  154. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +1 -1
  155. simtools/schemas/model_parameters/laser_var_photons.schema.yml +1 -1
  156. simtools/schemas/model_parameters/laser_wavelength.schema.yml +1 -1
  157. simtools/schemas/model_parameters/led_events.schema.yml +1 -1
  158. simtools/schemas/model_parameters/led_photons.schema.yml +1 -1
  159. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +1 -1
  160. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +1 -1
  161. simtools/schemas/model_parameters/led_var_photons.schema.yml +1 -1
  162. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
  163. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
  164. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
  165. simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
  166. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +1 -1
  167. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +4 -4
  168. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +4 -4
  169. simtools/schemas/model_parameters/mirror_class.schema.yml +1 -1
  170. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +1 -1
  171. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +1 -1
  172. simtools/schemas/model_parameters/mirror_list.schema.yml +1 -1
  173. simtools/schemas/model_parameters/mirror_offset.schema.yml +1 -1
  174. simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +3 -3
  175. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +3 -3
  176. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +1 -1
  177. simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +45 -0
  178. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
  179. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +1 -1
  180. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +5 -5
  181. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +1 -1
  182. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +1 -1
  183. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +1 -1
  184. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +1 -1
  185. simtools/schemas/model_parameters/{nsb_skymap.schema.yml → nsb_sky_map.schema.yml} +1 -1
  186. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +2 -2
  187. simtools/schemas/model_parameters/num_gains.schema.yml +1 -1
  188. simtools/schemas/model_parameters/pedestal_events.schema.yml +1 -1
  189. simtools/schemas/model_parameters/photon_delay.schema.yml +1 -1
  190. simtools/schemas/model_parameters/photons_per_run.schema.yml +1 -1
  191. simtools/schemas/model_parameters/pixel_cells.schema.yml +1 -1
  192. simtools/schemas/model_parameters/pixels_parallel.schema.yml +1 -1
  193. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +1 -1
  194. simtools/schemas/model_parameters/pm_average_gain.schema.yml +1 -1
  195. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +1 -1
  196. simtools/schemas/model_parameters/pm_gain_index.schema.yml +1 -1
  197. simtools/schemas/model_parameters/pm_transit_time.schema.yml +4 -4
  198. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +1 -1
  199. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +8 -4
  200. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +1 -1
  201. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +1 -1
  202. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +20 -20
  203. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +1 -1
  204. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +1 -1
  205. simtools/schemas/model_parameters/qe_variation.schema.yml +1 -1
  206. simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
  207. simtools/schemas/model_parameters/random_mono_probability.schema.yml +38 -0
  208. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +1 -1
  209. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +4 -1
  210. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +4 -1
  211. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +1 -1
  212. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +1 -1
  213. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +5 -5
  214. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +1 -1
  215. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
  216. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +1 -1
  217. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +1 -1
  218. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +20 -20
  219. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +1 -1
  220. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +1 -1
  221. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +1 -1
  222. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +1 -1
  223. simtools/schemas/model_parameters/stars.schema.yml +36 -0
  224. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
  225. simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
  226. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +1 -1
  227. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +1 -1
  228. simtools/schemas/model_parameters/telescope_random_error.schema.yml +1 -1
  229. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +1 -1
  230. simtools/schemas/model_parameters/telescope_transmission.schema.yml +6 -6
  231. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +1 -1
  232. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +1 -1
  233. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +1 -1
  234. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +1 -1
  235. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +1 -1
  236. simtools/schemas/model_parameters/transit_time_error.schema.yml +1 -1
  237. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +1 -1
  238. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +1 -1
  239. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +4 -4
  240. simtools/schemas/model_parameters/trigger_pixels.schema.yml +1 -1
  241. simtools/schemas/plot_configuration.metaschema.yml +162 -0
  242. simtools/schemas/production_tables.schema.yml +1 -1
  243. simtools/simtel/simtel_config_reader.py +85 -34
  244. simtools/simtel/simtel_config_writer.py +70 -38
  245. simtools/simtel/simtel_io_event_reader.py +278 -0
  246. simtools/simtel/simtel_io_event_writer.py +317 -0
  247. simtools/simtel/simtel_table_reader.py +4 -0
  248. simtools/simtel/simulator_light_emission.py +181 -67
  249. simtools/simulator.py +2 -2
  250. simtools/testing/configuration.py +17 -0
  251. simtools/utils/general.py +83 -16
  252. simtools/utils/geometry.py +19 -0
  253. simtools/utils/names.py +14 -3
  254. simtools/visualization/plot_tables.py +25 -20
  255. simtools/visualization/visualize.py +73 -25
  256. simtools/_dev_version/__init__.py +0 -9
  257. simtools/applications/__init__.py +0 -0
  258. simtools/applications/production_derive_limits.py +0 -95
  259. simtools/configuration/__init__.py +0 -0
  260. simtools/corsika/__init__.py +0 -0
  261. simtools/data_model/__init__.py +0 -0
  262. simtools/db/__init__.py +0 -0
  263. simtools/io_operations/__init__.py +0 -0
  264. simtools/job_execution/__init__.py +0 -0
  265. simtools/layout/__init__.py +0 -0
  266. simtools/model/__init__.py +0 -0
  267. simtools/production_configuration/limits_calculation.py +0 -202
  268. simtools/ray_tracing/__init__.py +0 -0
  269. simtools/runners/__init__.py +0 -0
  270. simtools/simtel/__init__.py +0 -0
  271. simtools/simtel/simtel_io_events.py +0 -265
  272. simtools/testing/__init__.py +0 -0
  273. simtools/utils/__init__.py +0 -0
  274. simtools/visualization/__init__.py +0 -0
  275. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info/licenses}/LICENSE +0 -0
  276. {gammasimtools-0.12.0.dist-info → gammasimtools-0.14.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  """Integration test configuration."""
2
2
 
3
3
  import logging
4
+ import os
4
5
  from pathlib import Path
5
6
 
6
7
  import yaml
@@ -14,6 +15,10 @@ class VersionError(Exception):
14
15
  """Raise if model version requested is not supported."""
15
16
 
16
17
 
18
+ class ProductionDBError(Exception):
19
+ """Raise if production db is used."""
20
+
21
+
17
22
  def get_list_of_test_configurations(config_files):
18
23
  """
19
24
  Return list of test configuration dictionaries or test names.
@@ -100,6 +105,7 @@ def configure(config, tmp_test_directory, request):
100
105
 
101
106
  if "CONFIGURATION" in config:
102
107
  _skip_test_for_model_version(config, model_version_requested)
108
+ _skip_test_for_production_db(config)
103
109
 
104
110
  config_file, config_string, config_file_model_version = _prepare_test_options(
105
111
  config["CONFIGURATION"],
@@ -130,6 +136,17 @@ def _skip_test_for_model_version(config, model_version_requested):
130
136
  )
131
137
 
132
138
 
139
+ def _skip_test_for_production_db(config):
140
+ """Skip test if production db is used."""
141
+ simtools_db_server = os.environ.get("SIMTOOLS_DB_SERVER")
142
+ if (
143
+ simtools_db_server
144
+ and config.get("SKIP_FOR_PRODUCTION_DB")
145
+ and "db.zeuthen.desy.de" in simtools_db_server
146
+ ):
147
+ raise ProductionDBError("Production database used for this test")
148
+
149
+
133
150
  def _prepare_test_options(config, output_path, model_version=None):
134
151
  """
135
152
  Prepare test configuration.
simtools/utils/general.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import copy
4
4
  import datetime
5
+ import glob
5
6
  import json
6
7
  import logging
7
8
  import os
@@ -179,13 +180,17 @@ def collect_data_from_file(file_name, yaml_document=None):
179
180
  return collect_data_from_http(file_name)
180
181
 
181
182
  suffix = Path(file_name).suffix.lower()
182
- with open(file_name, encoding="utf-8") as file:
183
- if suffix == ".json":
184
- return json.load(file)
185
- if suffix == ".list":
186
- return [line.strip() for line in file.readlines()]
187
- if suffix in [".yml", ".yaml"]:
188
- return _collect_data_from_yaml_file(file, file_name, yaml_document)
183
+ try:
184
+ with open(file_name, encoding="utf-8") as file:
185
+ if suffix == ".json":
186
+ return json.load(file)
187
+ if suffix == ".list":
188
+ return [line.strip() for line in file.readlines()]
189
+ if suffix in [".yml", ".yaml"]:
190
+ return _collect_data_from_yaml_file(file, file_name, yaml_document)
191
+ # broad exception to catch all possible errors in reading the file
192
+ except Exception as exc: # pylint: disable=broad-except
193
+ raise type(exc)(f"Failed to read file {file_name}: {exc}") from exc
189
194
  return None
190
195
 
191
196
 
@@ -455,6 +460,34 @@ def find_file(name, loc):
455
460
  raise FileNotFoundError(msg)
456
461
 
457
462
 
463
+ def resolve_file_patterns(file_names):
464
+ """
465
+ Return a list of files names from string, list, or wildcard pattern.
466
+
467
+ Parameters
468
+ ----------
469
+ file_names: str, list
470
+ File names to be searched for (wildcards allowed).
471
+
472
+ Returns
473
+ -------
474
+ list
475
+ List of file names found.
476
+ """
477
+ if file_names is None:
478
+ raise ValueError("No file list provided.")
479
+ if not isinstance(file_names, list):
480
+ file_names = [file_names]
481
+
482
+ _files = []
483
+ for file_name in file_names:
484
+ # use glob (and not Path.glob) for easier wildcard handling
485
+ _files.extend(Path(f) for f in glob.glob(str(file_name), recursive=True)) # noqa: PTH207
486
+ if not _files:
487
+ raise FileNotFoundError(f"No files found: {file_names}")
488
+ return _files
489
+
490
+
458
491
  def get_log_excerpt(log_file, n_last_lines=30):
459
492
  """
460
493
  Get an excerpt from a log file, namely the n_last_lines of the file.
@@ -696,16 +729,28 @@ def validate_data_type(reference_dtype, value=None, dtype=None, allow_subtypes=T
696
729
  ):
697
730
  return True
698
731
 
699
- if np.issubdtype(dtype, np.bool_) and reference_dtype in ("boolean", "bool"):
700
- return True
732
+ if reference_dtype in ("boolean", "bool"):
733
+ return _is_valid_boolean_type(dtype, value)
734
+
735
+ return _is_valid_numeric_type(dtype, reference_dtype)
701
736
 
702
- if np.issubdtype(dtype, np.integer) and (
703
- np.issubdtype(reference_dtype, np.integer) or np.issubdtype(reference_dtype, np.floating)
704
- ):
705
- return True
706
737
 
707
- if np.issubdtype(dtype, np.floating) and np.issubdtype(reference_dtype, np.floating):
738
+ def _is_valid_boolean_type(dtype, value):
739
+ """Check if dtype or value is a valid boolean type."""
740
+ if value in {0, 1}:
708
741
  return True
742
+ return np.issubdtype(dtype, np.bool_)
743
+
744
+
745
+ def _is_valid_numeric_type(dtype, reference_dtype):
746
+ """Check if dtype is a valid numeric type compared to reference_dtype."""
747
+ if np.issubdtype(dtype, np.integer):
748
+ return np.issubdtype(reference_dtype, np.integer) or np.issubdtype(
749
+ reference_dtype, np.floating
750
+ )
751
+
752
+ if np.issubdtype(dtype, np.floating):
753
+ return np.issubdtype(reference_dtype, np.floating)
709
754
 
710
755
  return False
711
756
 
@@ -801,6 +846,28 @@ def _load_yaml_using_astropy(file):
801
846
  return astropy_yaml.load(file)
802
847
 
803
848
 
849
+ def is_utf8_file(file_name):
850
+ """
851
+ Check if a file is encoded in UTF-8.
852
+
853
+ Parameters
854
+ ----------
855
+ file_name: str, Path
856
+ Name of the file to be checked.
857
+
858
+ Returns
859
+ -------
860
+ bool
861
+ True if the file is encoded in UTF-8, False otherwise.
862
+ """
863
+ try:
864
+ with open(file_name, encoding="utf-8") as file:
865
+ file.read()
866
+ return True
867
+ except UnicodeDecodeError:
868
+ return False
869
+
870
+
804
871
  def read_file_encoded_in_utf_or_latin(file_name):
805
872
  """
806
873
  Read a file encoded in UTF-8 or Latin-1.
@@ -851,8 +918,8 @@ def get_structure_array_from_table(table, column_names):
851
918
  Structured array containing the table data.
852
919
  """
853
920
  return np.array(
854
- list(zip(*[np.array(table[col]) for col in column_names])),
855
- dtype=[(col, np.array(table[col]).dtype) for col in column_names],
921
+ list(zip(*[np.array(table[col]) for col in column_names if col in table.colnames])),
922
+ dtype=[(col, np.array(table[col]).dtype) for col in column_names if col in table.colnames],
856
923
  )
857
924
 
858
925
 
@@ -161,3 +161,22 @@ def rotate(x, y, rotation_around_z_axis, rotation_around_y_axis=0):
161
161
  y_trans = x * np.sin(rotation_around_z_axis) + y * np.cos(rotation_around_z_axis)
162
162
 
163
163
  return x_trans, y_trans
164
+
165
+
166
+ def calculate_circular_mean(angles):
167
+ """
168
+ Calculate circular mean of angles in radians.
169
+
170
+ Parameters
171
+ ----------
172
+ angles: numpy.array
173
+ Array of angles in radians.
174
+
175
+ Returns
176
+ -------
177
+ float
178
+ Circular mean of the angles.
179
+ """
180
+ sin_sum = np.sum(np.sin(angles))
181
+ cos_sum = np.sum(np.cos(angles))
182
+ return np.arctan2(sin_sum, cos_sum)
simtools/utils/names.py CHANGED
@@ -353,6 +353,8 @@ def get_array_element_type_from_name(array_element_name):
353
353
  """
354
354
  Get array element type from array element name (e.g "MSTN" from "MSTN-01").
355
355
 
356
+ For sites, return site name.
357
+
356
358
  Parameters
357
359
  ----------
358
360
  array_element_name: str
@@ -363,7 +365,10 @@ def get_array_element_type_from_name(array_element_name):
363
365
  str
364
366
  Array element type.
365
367
  """
366
- return _validate_name(array_element_name.split("-")[0], array_elements())
368
+ try: # e.g. instrument is 'North' as given for the site parameters
369
+ return validate_site_name(array_element_name)
370
+ except ValueError: # any other telescope or calibration device
371
+ return _validate_name(array_element_name.split("-")[0], array_elements())
367
372
 
368
373
 
369
374
  def get_array_element_id_from_name(array_element_name):
@@ -460,7 +465,7 @@ def get_collection_name_from_array_element_name(array_element_name, array_elemen
460
465
  """
461
466
  try:
462
467
  return array_elements()[get_array_element_type_from_name(array_element_name)]["collection"]
463
- except ValueError as exc:
468
+ except (ValueError, KeyError) as exc:
464
469
  if array_elements_only:
465
470
  raise ValueError(f"Invalid array element name {array_element_name}") from exc
466
471
  try:
@@ -508,6 +513,7 @@ def get_collection_name_from_parameter_name(parameter_name):
508
513
  def get_simulation_software_name_from_parameter_name(
509
514
  parameter_name,
510
515
  simulation_software="sim_telarray",
516
+ set_meta_parameter=False,
511
517
  ):
512
518
  """
513
519
  Get the name used in the given simulation software from the model parameter name.
@@ -521,6 +527,8 @@ def get_simulation_software_name_from_parameter_name(
521
527
  Model parameter name.
522
528
  simulation_software: str
523
529
  Simulation software name.
530
+ set_meta_parameter: bool
531
+ If True, return values with 'set_meta_parameter' field set to True.
524
532
 
525
533
  Returns
526
534
  -------
@@ -532,7 +540,10 @@ def get_simulation_software_name_from_parameter_name(
532
540
  raise KeyError(f"Parameter {parameter_name} without schema definition")
533
541
 
534
542
  for software in _parameter.get("simulation_software", []):
535
- if software.get("name") == simulation_software:
543
+ if (
544
+ software.get("name") == simulation_software
545
+ and software.get("set_meta_parameter", False) is set_meta_parameter
546
+ ):
536
547
  return software.get("internal_parameter_name", parameter_name)
537
548
 
538
549
  return None
@@ -2,11 +2,11 @@
2
2
  """Plot tabular data."""
3
3
 
4
4
  import numpy as np
5
+ from astropy.table import Table
5
6
 
6
7
  import simtools.utils.general as gen
8
+ from simtools.db import db_handler
7
9
  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
10
  from simtools.visualization import visualize
11
11
 
12
12
 
@@ -50,11 +50,15 @@ def read_table_data(config, db_config):
50
50
  if "parameter" in _config:
51
51
  table = _read_table_from_model_database(_config, db_config)
52
52
  elif "file_name" in _config:
53
- table = legacy_data_handler.read_legacy_data_as_table(
54
- _config["file_name"], _config["type"]
55
- )
53
+ if "legacy" in _config.get("type", ""):
54
+ table = legacy_data_handler.read_legacy_data_as_table(
55
+ _config["file_name"], _config["type"]
56
+ )
57
+ else:
58
+ table = Table.read(_config["file_name"], format="ascii.ecsv")
56
59
  else:
57
60
  raise ValueError("No table data defined in configuration.")
61
+
58
62
  if _config.get("normalize_y"):
59
63
  table[_config["column_y"]] = (
60
64
  table[_config["column_y"]] / table[_config["column_y"]].max()
@@ -66,7 +70,13 @@ def read_table_data(config, db_config):
66
70
  _config["select_values"]["value"],
67
71
  )
68
72
  data[_config["label"]] = gen.get_structure_array_from_table(
69
- table, [_config["column_x"], _config["column_y"]]
73
+ table,
74
+ [
75
+ _config["column_x"],
76
+ _config["column_y"],
77
+ _config.get("column_x_err"),
78
+ _config.get("column_y_err"),
79
+ ],
70
80
  )
71
81
  return data
72
82
 
@@ -85,20 +95,15 @@ def _read_table_from_model_database(table_config, db_config):
85
95
  Table
86
96
  Astropy table.
87
97
  """
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"])
98
+ db = db_handler.DatabaseHandler(mongo_db_config=db_config)
99
+ return db.export_model_file(
100
+ parameter=table_config["parameter"],
101
+ site=table_config["site"],
102
+ array_element_name=table_config.get("telescope"),
103
+ parameter_version=table_config.get("parameter_version"),
104
+ model_version=table_config.get("model_version"),
105
+ export_file_as_table=True,
106
+ )
102
107
 
103
108
 
104
109
  def _select_values_from_table(table, column_name, value):
@@ -144,22 +144,23 @@ def _add_unit(title, array):
144
144
  str
145
145
  Title with units.
146
146
  """
147
- unit = ""
148
- if isinstance(array, u.Quantity):
149
- unit = str(array[0].unit)
150
- if len(unit) > 0:
151
- unit = f" [{unit}]"
152
- if re.search(r"\d", unit):
153
- unit = re.sub(r"(\d)", r"^\1", unit)
154
- unit = unit.replace("[", r"$[").replace("]", r"]$")
155
- if "[" in title and "]" in title:
156
- _logger.warning(
157
- "Tried to add a unit from astropy.unit, "
158
- "but axis already has an explicit unit. Left axis title as is."
159
- )
160
- unit = ""
147
+ if title and "[" in title and "]" in title:
148
+ _logger.warning(
149
+ "Tried to add a unit from astropy.unit, "
150
+ "but axis already has an explicit unit. Left axis title as is."
151
+ )
152
+ return title
153
+
154
+ if not isinstance(array, u.Quantity) or not str(array[0].unit):
155
+ return title
161
156
 
162
- return f"{title}{unit}"
157
+ unit = str(array[0].unit)
158
+ unit_str = f" [{unit}]"
159
+ if re.search(r"\d", unit_str):
160
+ unit_str = re.sub(r"(\d)", r"^\1", unit_str)
161
+ unit_str = unit_str.replace("[", r"[$").replace("]", r"$]")
162
+
163
+ return f"{title}{unit_str}"
163
164
 
164
165
 
165
166
  def set_style(palette="default", big_plot=False):
@@ -196,7 +197,7 @@ def set_style(palette="default", big_plot=False):
196
197
  raise KeyError(f"palette must be one of {', '.join(COLORS)}")
197
198
 
198
199
  fontsize = {"default": 17, "big_plot": 30}
199
- markersize = {"default": 8, "big_plot": 18}
200
+ markersize = {"default": 6, "big_plot": 18}
200
201
  plot_size = "big_plot" if big_plot else "default"
201
202
 
202
203
  plt.rc("lines", linewidth=2, markersize=markersize[plot_size])
@@ -418,27 +419,74 @@ def setup_plot(kwargs, plot_ratio, plot_difference):
418
419
  return fig, ax1, gs
419
420
 
420
421
 
422
+ def _plot_error_plots(kwargs, data_now, x_col, y_col, x_err_col, y_err_col, color):
423
+ """Plot error plots."""
424
+ if kwargs.get("error_type") == "fill_between" and y_err_col:
425
+ plt.fill_between(
426
+ data_now[x_col],
427
+ data_now[y_col] - data_now[y_err_col],
428
+ data_now[y_col] + data_now[y_err_col],
429
+ alpha=0.2,
430
+ color=color,
431
+ )
432
+
433
+ if kwargs.get("error_type") == "errorbar" and (x_err_col or y_err_col):
434
+ plt.errorbar(
435
+ data_now[x_col],
436
+ data_now[y_col],
437
+ xerr=data_now[x_err_col] if x_err_col else None,
438
+ yerr=data_now[y_err_col] if y_err_col else None,
439
+ fmt=".",
440
+ color=color,
441
+ )
442
+
443
+
444
+ def _get_data_columns(data_now):
445
+ """Return data columns depending on availability."""
446
+ columns = data_now.dtype.names
447
+ assert len(columns) >= 2, "Input array must have at least two columns with titles."
448
+ x_col, y_col = columns[:2]
449
+ if len(columns) == 3:
450
+ x_err_col = None
451
+ y_err_col = columns[2]
452
+ elif len(columns) == 4:
453
+ x_err_col = columns[2]
454
+ y_err_col = columns[3]
455
+ else:
456
+ x_err_col = None
457
+ y_err_col = None
458
+ return x_col, y_col, x_err_col, y_err_col
459
+
460
+
421
461
  def plot_main_data(data_dict, kwargs, plot_args):
422
462
  """Plot the main data."""
423
463
  for label, data_now in data_dict.items():
424
- assert len(data_now.dtype.names) == 2, "Input array must have two columns with titles."
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)
464
+ x_col, y_col, x_err_col, y_err_col = _get_data_columns(data_now)
465
+
466
+ x_title = kwargs.get("xtitle", x_col)
467
+ y_title = kwargs.get("ytitle", y_col)
468
+
469
+ x_title_unit = _add_unit(x_title, data_now[x_col])
470
+ y_title_unit = _add_unit(y_title, data_now[y_col])
471
+
472
+ (line,) = plt.plot(data_now[x_col], data_now[y_col], label=label, **plot_args)
473
+ color = line.get_color()
474
+
475
+ _plot_error_plots(kwargs, data_now, x_col, y_col, x_err_col, y_err_col, color)
431
476
 
432
477
  plt.xscale(kwargs["xscale"])
433
478
  plt.yscale(kwargs["yscale"])
434
479
  plt.xlim(kwargs["xlim"])
435
480
  plt.ylim(kwargs["ylim"])
436
481
  plt.ylabel(y_title_unit)
482
+
437
483
  if not (kwargs["plot_ratio"] or kwargs["plot_difference"]):
438
484
  plt.xlabel(x_title_unit)
485
+
439
486
  if kwargs["title"]:
440
487
  plt.title(kwargs["title"], y=1.02)
441
- if "_default" not in list(data_dict.keys()) and not kwargs["no_legend"]:
488
+
489
+ if "_default" not in data_dict and not kwargs["no_legend"]:
442
490
  plt.legend()
443
491
 
444
492
 
@@ -692,7 +740,7 @@ def plot_array(
692
740
 
693
741
 
694
742
  def initialize_tel_counters():
695
- return {one_telescope: 0 for one_telescope in names.get_list_of_array_element_types()}
743
+ return dict.fromkeys(names.get_list_of_array_element_types(), 0)
696
744
 
697
745
 
698
746
  def get_rotated_positions(telescopes, rotate_angle):
@@ -1,9 +0,0 @@
1
- # Try to use setuptools_scm to get the current version; this is only used
2
- # in development installations from the git repository.
3
- # see src/simtools/version.py for details
4
- try:
5
- from setuptools_scm import get_version
6
-
7
- version = get_version(root="../../..", relative_to=__file__)
8
- except Exception as e:
9
- raise ImportError(f"setuptools_scm broken or not installed: {e}")
File without changes
@@ -1,95 +0,0 @@
1
- #!/usr/bin/python3
2
-
3
- r"""
4
- Derives the limits for energy, radial distance, and viewcone to be used in CORSIKA simulations.
5
-
6
- The limits are derived based on the event loss fraction specified by the user.
7
-
8
- Command line arguments
9
- ----------------------
10
- event_data_file (str, required)
11
- Path to the file containing the event data.
12
- loss_fraction (float, required)
13
- Fraction of events to be lost.
14
-
15
-
16
- Example
17
- -------
18
- Derive limits for a given file with a specified loss fraction.
19
-
20
- .. code-block:: console
21
-
22
- simtools-production-derive-limits\\
23
- --event_data_file path/to/event_data_file.hdf5 \\
24
- --loss_fraction 1e-6
25
- """
26
-
27
- import logging
28
-
29
- import simtools.utils.general as gen
30
- from simtools.configuration import configurator
31
- from simtools.io_operations.hdf5_handler import read_hdf5
32
- from simtools.production_configuration.limits_calculation import LimitCalculator
33
-
34
- _logger = logging.getLogger(__name__)
35
-
36
-
37
- def _parse():
38
- """
39
- Parse command line configuration.
40
-
41
- Parameters
42
- ----------
43
- event_data_file: str
44
- The event data file.
45
- loss_fraction: float
46
- Loss fraction of events for limit derivation.
47
-
48
- Returns
49
- -------
50
- CommandLineParser
51
- Command line parser object
52
-
53
- """
54
- config = configurator.Configurator(
55
- description="Derive limits for energy, radial distance, and viewcone."
56
- )
57
- config.parser.add_argument(
58
- "--event_data_file",
59
- type=str,
60
- required=True,
61
- help="Path to the event data file containing the event data.",
62
- )
63
- config.parser.add_argument(
64
- "--loss_fraction", type=float, required=True, help="Fraction of events to be lost."
65
- )
66
- return config.initialize(db_config=False)
67
-
68
-
69
- def main():
70
- """Derive limits for energy, radial distance, and viewcone."""
71
- args_dict, _ = _parse()
72
-
73
- logger = logging.getLogger()
74
- logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
75
-
76
- event_data_file_path = args_dict["event_data_file"]
77
- loss_fraction = args_dict["loss_fraction"]
78
-
79
- _logger.info(f"Loading event data file: {event_data_file_path}")
80
- tables = read_hdf5(event_data_file_path)
81
-
82
- calculator = LimitCalculator(tables)
83
-
84
- lower_energy_limit = calculator.compute_lower_energy_limit(loss_fraction)
85
- _logger.info(f"Lower energy threshold: {lower_energy_limit}")
86
-
87
- upper_radial_distance = calculator.compute_upper_radial_distance(loss_fraction)
88
- _logger.info(f"Upper radius threshold: {upper_radial_distance}")
89
-
90
- viewcone = calculator.compute_viewcone(loss_fraction)
91
- _logger.info(f"Viewcone radius: {viewcone}")
92
-
93
-
94
- if __name__ == "__main__":
95
- main()
File without changes
File without changes
File without changes
simtools/db/__init__.py DELETED
File without changes
File without changes
File without changes
File without changes
File without changes