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
@@ -0,0 +1,240 @@
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_files (str, required)
11
+ Path to a file containing event data file paths.
12
+ telescope_ids (str, required)
13
+ Path to a file containing telescope configurations.
14
+ loss_fraction (float, required)
15
+ Fraction of events to be lost.
16
+ plot_histograms (bool, optional)
17
+ Plot histograms of the event data.
18
+ output_file (str, optional)
19
+ Path to the output file for the derived limits.
20
+
21
+ Example
22
+ -------
23
+ Derive limits for a given file with a specified loss fraction.
24
+
25
+ .. code-block:: console
26
+
27
+ simtools-production-derive-corsika-limits \\
28
+ --event_data_files path/to/event_data_files.yaml \\
29
+ --telescope_ids path/to/telescope_configs.yaml \\
30
+ --loss_fraction 1e-6 \\
31
+ --plot_histograms \\
32
+ --output_file corsika_simulation_limits_lookup.ecsv
33
+ """
34
+
35
+ import datetime
36
+ import logging
37
+
38
+ from astropy.table import Table
39
+
40
+ import simtools.utils.general as gen
41
+ from simtools.configuration import configurator
42
+ from simtools.data_model.metadata_collector import MetadataCollector
43
+ from simtools.io_operations import io_handler
44
+ from simtools.production_configuration.derive_corsika_limits import LimitCalculator
45
+
46
+ _logger = logging.getLogger(__name__)
47
+
48
+
49
+ def _parse():
50
+ """
51
+ Parse command line configuration.
52
+
53
+ Parameters
54
+ ----------
55
+ event_data_files: str
56
+ Path to a file listing event data file paths. These files contain the
57
+ simulation data used for deriving the limits.
58
+ loss_fraction: float
59
+ Fraction of events to be excluded during limit computation. Determines
60
+ thresholds for energy, radial distance, and viewcone.
61
+ telescope_ids: str
62
+ Path to a file defining telescope configurations. Specifies telescope
63
+ arrays or IDs used to filter events during processing.
64
+ plot_histograms: bool
65
+ If True, generates and saves histograms of the event data to visualize
66
+ the computed limits and distributions.
67
+
68
+ Returns
69
+ -------
70
+ CommandLineParser
71
+ Command line parser object
72
+ """
73
+ config = configurator.Configurator(
74
+ description="Derive limits for energy, radial distance, and viewcone."
75
+ )
76
+ config.parser.add_argument(
77
+ "--event_data_files",
78
+ type=str,
79
+ required=True,
80
+ help="Path to a file containing event data file paths.",
81
+ )
82
+ config.parser.add_argument(
83
+ "--telescope_ids",
84
+ type=str,
85
+ required=True,
86
+ help="Path to a file containing telescope configurations.",
87
+ )
88
+ config.parser.add_argument(
89
+ "--loss_fraction", type=float, required=True, help="Fraction of events to be lost."
90
+ )
91
+ config.parser.add_argument(
92
+ "--plot_histograms",
93
+ help="Plot histograms of the event data.",
94
+ action="store_true",
95
+ default=False,
96
+ )
97
+ config.parser.add_argument(
98
+ "--output_file",
99
+ type=str,
100
+ default="corsika_simulation_limits_lookup.ecsv",
101
+ help="Output file for the derived limits (default: "
102
+ "'corsika_simulation_limits_lookup.ecsv').",
103
+ )
104
+ return config.initialize(db_config=False)
105
+
106
+
107
+ def process_file(file_path, telescope_ids, loss_fraction, plot_histograms):
108
+ """
109
+ Process a single file and compute limits.
110
+
111
+ Parameters
112
+ ----------
113
+ file_path : str
114
+ Path to the event data file.
115
+ telescope_ids : list[int]
116
+ List of telescope IDs to filter the events.
117
+ loss_fraction : float
118
+ Fraction of events to be lost.
119
+ plot_histograms : bool
120
+ Whether to plot histograms.
121
+
122
+ Returns
123
+ -------
124
+ dict
125
+ Dictionary containing the computed limits.
126
+ """
127
+ calculator = LimitCalculator(file_path, telescope_list=telescope_ids)
128
+
129
+ lower_energy_limit = calculator.compute_lower_energy_limit(loss_fraction)
130
+ upper_radial_distance = calculator.compute_upper_radial_distance(loss_fraction)
131
+ viewcone = calculator.compute_viewcone(loss_fraction)
132
+
133
+ if plot_histograms:
134
+ _logger.info(
135
+ f"Plotting histograms written to {io_handler.IOHandler().get_output_directory()}"
136
+ )
137
+ calculator.plot_data(
138
+ lower_energy_limit,
139
+ upper_radial_distance,
140
+ viewcone,
141
+ io_handler.IOHandler().get_output_directory(),
142
+ )
143
+
144
+ return {
145
+ "file_path": file_path,
146
+ "telescope_ids": telescope_ids,
147
+ "lower_energy_threshold": lower_energy_limit,
148
+ "upper_radius_threshold": upper_radial_distance,
149
+ "viewcone_radius": viewcone,
150
+ }
151
+
152
+
153
+ def create_results_table(results, loss_fraction):
154
+ """
155
+ Create an Astropy Table from the results.
156
+
157
+ Parameters
158
+ ----------
159
+ results : list[dict]
160
+ List of dictionaries containing the computed limits for each file
161
+ and telescope configuration.
162
+ loss_fraction : float
163
+ Fraction of events to be lost, added as metadata to the table.
164
+
165
+ Returns
166
+ -------
167
+ astropy.table.Table
168
+ An Astropy Table containing the results with appropriate units and metadata.
169
+ """
170
+ table = Table(
171
+ rows=[
172
+ (
173
+ res["file_path"],
174
+ res["telescope_ids"],
175
+ res["lower_energy_threshold"],
176
+ res["upper_radius_threshold"],
177
+ res["viewcone_radius"],
178
+ )
179
+ for res in results
180
+ ],
181
+ names=[
182
+ "file_path",
183
+ "telescope_ids",
184
+ "lower_energy_threshold",
185
+ "upper_radius_threshold",
186
+ "viewcone_radius",
187
+ ],
188
+ )
189
+
190
+ table["lower_energy_threshold"].unit = "TeV"
191
+ table["upper_radius_threshold"].unit = "m"
192
+ table["viewcone_radius"].unit = "deg"
193
+
194
+ table.meta["created"] = datetime.datetime.now().isoformat()
195
+ table.meta["description"] = (
196
+ "Lookup table for CORSIKA limits computed from gamma-ray shower simulations."
197
+ )
198
+ table.meta["loss_fraction"] = loss_fraction
199
+
200
+ return table
201
+
202
+
203
+ def main():
204
+ """Derive limits for energy, radial distance, and viewcone."""
205
+ args_dict, _ = _parse()
206
+
207
+ logger = logging.getLogger()
208
+ logger.setLevel(gen.get_log_level_from_user(args_dict.get("log_level", "info")))
209
+
210
+ event_data_files = gen.collect_data_from_file(args_dict["event_data_files"])["files"]
211
+ telescope_configs = gen.collect_data_from_file(args_dict["telescope_ids"])["telescope_configs"]
212
+
213
+ results = []
214
+ for file_path in event_data_files:
215
+ for array_name, telescope_ids in telescope_configs.items():
216
+ _logger.info(f"Processing file: {file_path} with telescope config: {array_name}")
217
+ result = process_file(
218
+ file_path,
219
+ telescope_ids,
220
+ args_dict["loss_fraction"],
221
+ args_dict["plot_histograms"],
222
+ )
223
+ result["layout"] = array_name
224
+ results.append(result)
225
+
226
+ table = create_results_table(results, args_dict["loss_fraction"])
227
+
228
+ output_dir = io_handler.IOHandler().get_output_directory("corsika_limits")
229
+ output_file = f"{output_dir}/{args_dict['output_file']}"
230
+
231
+ table.write(output_file, format="ascii.ecsv", overwrite=True)
232
+ _logger.info(f"Results saved to {output_file}")
233
+
234
+ metadata_file = f"{output_dir}/metadata.yml"
235
+ MetadataCollector.dump(args_dict, metadata_file)
236
+ _logger.info(f"Metadata saved to {metadata_file}")
237
+
238
+
239
+ if __name__ == "__main__":
240
+ main()
@@ -4,8 +4,8 @@ r"""
4
4
  Application to run the StatisticalErrorEvaluator and interpolate results.
5
5
 
6
6
  This application evaluates statistical uncertainties from DL2 MC event files
7
- based on input parameters like zenith angles and offsets, and can perform interpolation
8
- for a specified grid point.
7
+ based on input parameters like zenith angles and offsets, and performs interpolation
8
+ for a specified query point.
9
9
 
10
10
  Command line arguments
11
11
  ----------------------
@@ -15,10 +15,20 @@ zeniths (list of int, required)
15
15
  List of zenith angles to consider.
16
16
  offsets (list of int, required)
17
17
  List of offsets in degrees.
18
- interpolate (bool, optional)
19
- If set, performs interpolation for a specific grid point.
20
- query_point (list of int, optional)
21
- Grid point for interpolation (energy, azimuth, zenith, NSB, offset).
18
+ query_point (list of float, required)
19
+ Query point for interpolation. The query point must contain exactly 5 values:
20
+ - Energy (TeV)
21
+ - Azimuth (degrees)
22
+ - Zenith (degrees)
23
+ - NSB (MHz)
24
+ - Offset (degrees)
25
+ output_file (str, optional)
26
+ Output file to store the results. Default: 'interpolated_scaled_events.json'.
27
+ metrics_file (str, optional)
28
+ Path to the metrics definition file. Default: 'production_simulation_config_metrics.yml'.
29
+ file_name_template (str, optional)
30
+ Template for the file name. Default:
31
+ 'prod6_LaPalma-{zenith}deg_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits'.
22
32
 
23
33
  Example
24
34
  -------
@@ -26,14 +36,16 @@ To evaluate statistical uncertainties and perform interpolation, run the command
26
36
 
27
37
  .. code-block:: console
28
38
 
29
- simtools-production-scale-events --base_path tests/resources/production_dl2_fits/ \
30
- --zeniths 20 52 40 60 --offsets 0 --interpolate --query_point 1 180 30 0 0 \
31
- --metrics_file "path/to/metrics.yaml"
39
+ simtools-production-scale-events --base_path tests/resources/production_dl2_fits/ \\
40
+ --zeniths 20 40 52 60 --offsets 0 --query_point 1 180 30 0 0 \\
41
+ --metrics_file "path/to/metrics.yaml" \\
42
+ --output_file "output.json"
32
43
 
33
-
34
- The output will display the scaled events for the specified grid point.
44
+ The output will display the scaled events for the specified query point and save
45
+ the results to the specified output file.
35
46
  """
36
47
 
48
+ import itertools
37
49
  import json
38
50
  import logging
39
51
  from pathlib import Path
@@ -69,33 +81,47 @@ def _parse(label, description):
69
81
  help="Path to the DL2 MC event files for interpolation.",
70
82
  )
71
83
  config.parser.add_argument(
72
- "--zeniths", nargs="+", type=CommandLineParser.zenith_angle, help="List of zenith angles."
84
+ "--zeniths",
85
+ required=True,
86
+ nargs="+",
87
+ type=CommandLineParser.zenith_angle,
88
+ help="List of zenith angles.",
73
89
  )
74
90
  config.parser.add_argument(
75
- "--offsets", nargs="+", type=float, help="List of offsets in degrees."
91
+ "--offsets", required=True, nargs="+", type=float, help="List of offsets in degrees."
76
92
  )
77
93
 
78
- config.parser.add_argument(
79
- "--interpolate", action="store_true", help="Interpolate results for a specific grid point."
80
- )
81
94
  config.parser.add_argument(
82
95
  "--query_point",
96
+ required=True,
83
97
  nargs=5,
84
98
  type=float,
85
99
  help="Grid point for interpolation (energy, azimuth, zenith, NSB, offset).",
86
100
  )
87
101
  config.parser.add_argument(
88
102
  "--output_file",
103
+ required=False,
89
104
  type=str,
90
105
  default="interpolated_scaled_events.json",
91
106
  help="Output file to store the results. (default: 'interpolated_scaled_events.json').",
92
107
  )
93
108
  config.parser.add_argument(
94
109
  "--metrics_file",
110
+ required=False,
95
111
  type=str,
96
112
  default="production_simulation_config_metrics.yml",
97
113
  help="Metrics definition file. (default: production_simulation_config_metrics.yml)",
98
114
  )
115
+ config.parser.add_argument(
116
+ "--file_name_template",
117
+ required=False,
118
+ type=str,
119
+ default=("prod6_LaPalma-{zenith}deg_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits"),
120
+ help=(
121
+ "Template for the file name. (default: "
122
+ "'prod6_LaPalma-{zenith}deg_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits')"
123
+ ),
124
+ )
99
125
  return config.initialize(db_config=False)
100
126
 
101
127
 
@@ -115,27 +141,25 @@ def main():
115
141
 
116
142
  evaluator_instances = []
117
143
 
118
- metrics = (
119
- gen.collect_data_from_file(args_dict["metrics_file"]) if "metrics_file" in args_dict else {}
120
- )
144
+ metrics = gen.collect_data_from_file(args_dict["metrics_file"])
121
145
 
122
146
  if args_dict["base_path"] and args_dict["zeniths"] and args_dict["offsets"]:
123
- for zenith in args_dict["zeniths"]:
124
- for offset in args_dict["offsets"]:
125
- # Build file path based on base_path, zenith, and offset
126
- file_name = f"prod6_LaPalma-{int(zenith.value)}deg_"
127
- file_name += "gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits"
128
- file_path = Path(args_dict["base_path"]).joinpath(file_name)
129
-
130
- evaluator = StatisticalErrorEvaluator(
131
- file_path,
132
- file_type="Gamma-cone",
133
- metrics=metrics,
134
- grid_point=(1 * u.TeV, 180 * u.deg, zenith, 0, offset * u.deg),
135
- )
136
-
137
- evaluator.calculate_metrics()
138
- evaluator_instances.append(evaluator)
147
+ for zenith, offset in itertools.product(args_dict["zeniths"], args_dict["offsets"]):
148
+ file_name = args_dict["file_name_template"].format(zenith=int(zenith.value))
149
+ file_path = Path(args_dict["base_path"]).joinpath(file_name)
150
+
151
+ if not file_path.exists():
152
+ logger.warning(f"File not found: {file_path}. Skipping.")
153
+ continue
154
+
155
+ evaluator = StatisticalErrorEvaluator(
156
+ file_path,
157
+ file_type="Gamma-cone",
158
+ metrics=metrics,
159
+ grid_point=(1 * u.TeV, 180 * u.deg, zenith, 0, offset * u.deg),
160
+ )
161
+ evaluator.calculate_metrics()
162
+ evaluator_instances.append(evaluator)
139
163
 
140
164
  else:
141
165
  logger.warning("No files read")
@@ -143,7 +167,6 @@ def main():
143
167
  logger.warning(f"Zeniths: {args_dict['zeniths']}")
144
168
  logger.warning(f"Offsets: {args_dict['offsets']}")
145
169
 
146
- # Perform interpolation for the given query point
147
170
  interpolation_handler = InterpolationHandler(evaluator_instances, metrics=metrics)
148
171
  query_points = np.array([args_dict["query_point"]])
149
172
  scaled_events = interpolation_handler.interpolate(query_points)
@@ -1,12 +1,30 @@
1
1
  #!/usr/bin/python3
2
2
 
3
3
  """
4
- Run simtools applications from configuration files for setting workflows.
4
+ Run several simtools applications using a configuration file.
5
5
 
6
6
  Allows to run several simtools applications with a single configuration file, which includes
7
7
  both the name of the simtools application and the configuration for the application.
8
8
 
9
- Strong assumption on the directory structure for input and output files of applications.
9
+ This application is used for model parameter setting workflows.
10
+ Strong assumptions are applied on the directory structure for input and output files of
11
+ applications.
12
+
13
+ Example
14
+ -------
15
+
16
+ Run the application with the configuration file 'config_file_name':
17
+
18
+ .. code-block:: console
19
+
20
+ simtools-run-application --configuration_file config_file_name
21
+
22
+ Run the application with the configuration file 'config_file_name', but skipping all steps except
23
+ step 2 and 3 (useful for debugging):
24
+
25
+ .. code-block:: console
26
+
27
+ simtools-run-application --configuration_file config_file_name --steps 2 3
10
28
 
11
29
  """
12
30
 
@@ -49,7 +67,13 @@ def _parse(label, description, usage):
49
67
  required=True,
50
68
  default=None,
51
69
  )
52
- return config.initialize(db_config=False)
70
+ config.parser.add_argument(
71
+ "--steps",
72
+ type=int,
73
+ nargs="+",
74
+ help="List of steps to be execution (e.g., '--steps 7 8 9'; do not specify to run all).",
75
+ )
76
+ return config.initialize(db_config=True)
53
77
 
54
78
 
55
79
  def run_application(application, configuration, logger):
@@ -81,7 +105,7 @@ def get_subdirectory_name(path):
81
105
  raise ValueError(f"Could not find subdirectory under 'input': {exc}") from exc
82
106
 
83
107
 
84
- def read_application_configuration(configuration_file, logger):
108
+ def read_application_configuration(configuration_file, steps, logger):
85
109
  """
86
110
  Read application configuration from file and modify for setting workflows.
87
111
 
@@ -97,6 +121,8 @@ def read_application_configuration(configuration_file, logger):
97
121
  ----------
98
122
  configuration_file : str
99
123
  Configuration file name.
124
+ steps : list
125
+ List of steps to be executed (None: all steps).
100
126
  logger : Logger
101
127
  Logger object.
102
128
 
@@ -111,46 +137,49 @@ def read_application_configuration(configuration_file, logger):
111
137
  application_config = gen.collect_data_from_file(configuration_file).get("CTA_SIMPIPE")
112
138
  place_holder = "__SETTING_WORKFLOW__"
113
139
  workflow_dir, setting_workflow = get_subdirectory_name(configuration_file)
114
- output_path = str(workflow_dir).replace("input", "output") + setting_workflow
140
+ output_path = Path(str(workflow_dir).replace("input", "output")) / Path(setting_workflow)
141
+ output_path.mkdir(parents=True, exist_ok=True)
115
142
  logger.info(f"Setting workflow output path to {output_path}")
116
- log_file = (
117
- Path(application_config.get("LOG_PATH", "./").replace(place_holder, setting_workflow))
118
- / "simtools.log"
119
- )
120
- log_file.parent.mkdir(parents=True, exist_ok=True)
143
+ log_file = output_path / "simtools.log"
121
144
  configurations = application_config.get("APPLICATIONS")
122
- for config in configurations:
145
+ for step_count, config in enumerate(configurations, start=1):
146
+ config["RUN_APPLICATION"] = step_count in steps if steps else True
123
147
  for key, value in config.get("CONFIGURATION", {}).items():
124
148
  if isinstance(value, str):
125
149
  config["CONFIGURATION"][key] = value.replace(place_holder, setting_workflow)
126
150
  if isinstance(value, list):
127
151
  config["CONFIGURATION"][key] = [
128
- item.replace(place_holder, setting_workflow) for item in value
152
+ item.replace(place_holder, setting_workflow) if isinstance(item, str) else item
153
+ for item in value
129
154
  ]
130
155
  config["CONFIGURATION"]["USE_PLAIN_OUTPUT_PATH"] = True
131
- config["OUTPUT_PATH"] = output_path
156
+ config["CONFIGURATION"]["OUTPUT_PATH"] = str(output_path)
132
157
 
133
158
  return configurations, log_file
134
159
 
135
160
 
136
161
  def main(): # noqa: D103
137
- args_dict, _ = _parse(
162
+ args_dict, db_config = _parse(
138
163
  Path(__file__).stem,
139
- description="Run simtools applications from configuration file.",
164
+ description="Run simtools applications using a configuration file.",
140
165
  usage="simtools-run-application --config_file config_file_name",
141
166
  )
142
167
  logger = logging.getLogger()
143
168
  logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
144
169
 
145
170
  configurations, log_file = read_application_configuration(
146
- args_dict["configuration_file"], logger
171
+ args_dict["configuration_file"], args_dict["steps"], logger
147
172
  )
148
173
 
149
174
  with log_file.open("w", encoding="utf-8") as file:
150
175
  file.write("Running simtools applications\n")
151
- file.write(dependencies.get_version_string())
176
+ file.write(dependencies.get_version_string(db_config))
152
177
  for config in configurations:
153
- logger.info(f"Running application: {config.get('APPLICATION')}")
178
+ if config.get("RUN_APPLICATION"):
179
+ logger.info(f"Running application: {config.get('APPLICATION')}")
180
+ else:
181
+ logger.info(f"Skipping application: {config.get('APPLICATION')}")
182
+ continue
154
183
  config = gen.change_dict_keys_case(config, False)
155
184
  stdout, stderr = run_application(
156
185
  config.get("APPLICATION"), config.get("CONFIGURATION"), logger