gammasimtools 0.6.1__py3-none-any.whl → 0.8.1__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 (353) hide show
  1. gammasimtools-0.8.1.dist-info/METADATA +172 -0
  2. gammasimtools-0.8.1.dist-info/RECORD +346 -0
  3. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/WHEEL +1 -1
  4. gammasimtools-0.8.1.dist-info/entry_points.txt +31 -0
  5. simtools/_version.py +2 -2
  6. simtools/applications/calculate_trigger_rate.py +210 -0
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +372 -0
  8. simtools/applications/{print_array_elements.py → convert_geo_coordinates_of_array_elements.py} +58 -63
  9. simtools/applications/convert_model_parameter_from_simtel.py +119 -0
  10. simtools/applications/{add_file_to_db.py → db_add_file_to_db.py} +70 -60
  11. simtools/applications/db_add_model_parameters_from_repository_to_db.py +184 -0
  12. simtools/applications/db_add_value_from_json_to_db.py +105 -0
  13. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +180 -0
  14. simtools/applications/db_get_array_layouts_from_db.py +162 -0
  15. simtools/applications/{get_file_from_db.py → db_get_file_from_db.py} +30 -34
  16. simtools/applications/db_get_parameter_from_db.py +131 -0
  17. simtools/applications/db_inspect_databases.py +52 -0
  18. simtools/applications/derive_mirror_rnda.py +39 -255
  19. simtools/applications/derive_psf_parameters.py +441 -0
  20. simtools/applications/generate_array_config.py +82 -0
  21. simtools/applications/generate_corsika_histograms.py +52 -52
  22. simtools/applications/generate_default_metadata.py +5 -8
  23. simtools/applications/generate_regular_arrays.py +117 -0
  24. simtools/applications/generate_simtel_array_histograms.py +97 -56
  25. simtools/applications/plot_array_layout.py +345 -115
  26. simtools/applications/production_generate_simulation_config.py +158 -0
  27. simtools/applications/production_scale_events.py +168 -0
  28. simtools/applications/simulate_light_emission.py +478 -0
  29. simtools/applications/simulate_prod.py +97 -175
  30. simtools/applications/submit_data_from_external.py +9 -12
  31. simtools/applications/submit_model_parameter_from_external.py +122 -0
  32. simtools/applications/validate_camera_efficiency.py +35 -102
  33. simtools/applications/validate_camera_fov.py +20 -19
  34. simtools/applications/{compare_cumulative_psf.py → validate_cumulative_psf.py} +45 -44
  35. simtools/applications/validate_file_using_schema.py +113 -47
  36. simtools/applications/validate_optics.py +17 -22
  37. simtools/camera_efficiency.py +193 -202
  38. simtools/configuration/commandline_parser.py +384 -96
  39. simtools/configuration/configurator.py +55 -71
  40. simtools/constants.py +5 -5
  41. simtools/corsika/corsika_config.py +482 -342
  42. simtools/corsika/corsika_histograms.py +226 -204
  43. simtools/corsika/corsika_histograms_visualize.py +23 -24
  44. simtools/corsika/primary_particle.py +159 -0
  45. simtools/data_model/data_reader.py +25 -20
  46. simtools/data_model/format_checkers.py +52 -0
  47. simtools/data_model/metadata_collector.py +210 -184
  48. simtools/data_model/metadata_model.py +115 -37
  49. simtools/data_model/model_data_writer.py +335 -26
  50. simtools/data_model/validate_data.py +366 -154
  51. simtools/db/db_array_elements.py +130 -0
  52. simtools/db/db_from_repo_handler.py +106 -0
  53. simtools/db/db_handler.py +1246 -0
  54. simtools/io_operations/hdf5_handler.py +3 -1
  55. simtools/io_operations/io_handler.py +32 -57
  56. simtools/job_execution/job_manager.py +82 -69
  57. simtools/layout/array_layout.py +325 -537
  58. simtools/layout/geo_coordinates.py +8 -11
  59. simtools/layout/telescope_position.py +163 -86
  60. simtools/model/array_model.py +305 -256
  61. simtools/model/calibration_model.py +50 -0
  62. simtools/model/camera.py +233 -493
  63. simtools/model/mirrors.py +61 -44
  64. simtools/model/model_parameter.py +602 -0
  65. simtools/model/model_utils.py +7 -35
  66. simtools/model/site_model.py +161 -0
  67. simtools/model/telescope_model.py +127 -621
  68. simtools/production_configuration/calculate_statistical_errors_grid_point.py +454 -0
  69. simtools/production_configuration/event_scaler.py +146 -0
  70. simtools/production_configuration/generate_simulation_config.py +193 -0
  71. simtools/production_configuration/interpolation_handler.py +197 -0
  72. simtools/ray_tracing/__init__.py +0 -0
  73. simtools/ray_tracing/mirror_panel_psf.py +280 -0
  74. simtools/{psf_analysis.py → ray_tracing/psf_analysis.py} +133 -47
  75. simtools/ray_tracing/ray_tracing.py +646 -0
  76. simtools/runners/__init__.py +0 -0
  77. simtools/runners/corsika_runner.py +240 -0
  78. simtools/runners/corsika_simtel_runner.py +225 -0
  79. simtools/runners/runner_services.py +307 -0
  80. simtools/runners/simtel_runner.py +224 -0
  81. simtools/schemas/array_elements.yml +137 -0
  82. simtools/schemas/integration_tests_config.metaschema.yml +93 -0
  83. simtools/schemas/metadata.metaschema.yml +6 -0
  84. simtools/schemas/model_parameter.metaschema.yml +78 -0
  85. simtools/schemas/{data.metaschema.yml → model_parameter_and_data_schema.metaschema.yml} +27 -44
  86. simtools/schemas/model_parameters/adjust_gain.schema.yml +37 -0
  87. simtools/schemas/model_parameters/altitude.schema.yml +37 -0
  88. simtools/schemas/model_parameters/array_coordinates.schema.yml +33 -0
  89. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +77 -0
  90. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +39 -0
  91. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +39 -0
  92. simtools/schemas/model_parameters/array_layouts.schema.yml +48 -0
  93. simtools/schemas/model_parameters/array_triggers.schema.yml +93 -0
  94. simtools/schemas/model_parameters/asum_clipping.schema.yml +38 -0
  95. simtools/schemas/model_parameters/asum_offset.schema.yml +35 -0
  96. simtools/schemas/model_parameters/asum_shaping.schema.yml +35 -0
  97. simtools/schemas/model_parameters/asum_threshold.schema.yml +38 -0
  98. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +32 -0
  99. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +35 -0
  100. simtools/schemas/model_parameters/axes_offsets.schema.yml +53 -0
  101. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +40 -0
  102. simtools/schemas/model_parameters/camera_body_shape.schema.yml +45 -0
  103. simtools/schemas/model_parameters/camera_config_file.schema.yml +40 -0
  104. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +36 -0
  105. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +43 -0
  106. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +42 -0
  107. simtools/schemas/model_parameters/camera_depth.schema.yml +42 -0
  108. simtools/schemas/model_parameters/camera_filter.schema.yml +45 -0
  109. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +29 -0
  110. simtools/schemas/model_parameters/camera_pixels.schema.yml +36 -0
  111. simtools/schemas/model_parameters/camera_transmission.schema.yml +41 -0
  112. simtools/schemas/model_parameters/channels_per_chip.schema.yml +36 -0
  113. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +35 -0
  114. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +27 -0
  115. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +38 -0
  116. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +28 -0
  117. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +23 -0
  118. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +27 -0
  119. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +28 -0
  120. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +27 -0
  121. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +38 -0
  122. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +52 -0
  123. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +27 -0
  124. simtools/schemas/model_parameters/dark_events.schema.yml +32 -0
  125. simtools/schemas/model_parameters/default_trigger.schema.yml +35 -0
  126. simtools/schemas/model_parameters/design_model.schema.yml +31 -0
  127. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +32 -0
  128. simtools/schemas/model_parameters/disc_bins.schema.yml +39 -0
  129. simtools/schemas/model_parameters/disc_start.schema.yml +41 -0
  130. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +42 -0
  131. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +41 -0
  132. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +41 -0
  133. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +39 -0
  134. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +40 -0
  135. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +41 -0
  136. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +33 -0
  137. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +42 -0
  138. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +37 -0
  139. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +44 -0
  140. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +36 -0
  141. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +45 -0
  142. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +40 -0
  143. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +41 -0
  144. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +38 -0
  145. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +38 -0
  146. simtools/schemas/model_parameters/dish_shape_length.schema.yml +41 -0
  147. simtools/schemas/model_parameters/dsum_clipping.schema.yml +38 -0
  148. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +38 -0
  149. simtools/schemas/model_parameters/dsum_offset.schema.yml +37 -0
  150. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +33 -0
  151. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +39 -0
  152. simtools/schemas/model_parameters/dsum_prescale.schema.yml +44 -0
  153. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +38 -0
  154. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +45 -0
  155. simtools/schemas/model_parameters/dsum_shaping.schema.yml +44 -0
  156. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +32 -0
  157. simtools/schemas/model_parameters/dsum_threshold.schema.yml +43 -0
  158. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +42 -0
  159. simtools/schemas/model_parameters/effective_focal_length.schema.yml +61 -0
  160. simtools/schemas/model_parameters/epsg_code.schema.yml +37 -0
  161. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +35 -0
  162. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +46 -0
  163. simtools/schemas/model_parameters/fadc_bins.schema.yml +40 -0
  164. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +50 -0
  165. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +38 -0
  166. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +42 -0
  167. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +49 -0
  168. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +47 -0
  169. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +51 -0
  170. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +37 -0
  171. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +43 -0
  172. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +49 -0
  173. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +43 -0
  174. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +39 -0
  175. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +42 -0
  176. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +40 -0
  177. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +50 -0
  178. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +42 -0
  179. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +41 -0
  180. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +42 -0
  181. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +43 -0
  182. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +39 -0
  183. simtools/schemas/model_parameters/fadc_mhz.schema.yml +31 -0
  184. simtools/schemas/model_parameters/fadc_noise.schema.yml +41 -0
  185. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +40 -0
  186. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +39 -0
  187. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +50 -0
  188. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +43 -0
  189. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +43 -0
  190. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +42 -0
  191. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +41 -0
  192. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +42 -0
  193. simtools/schemas/model_parameters/flatfielding.schema.yml +37 -0
  194. simtools/schemas/model_parameters/focal_length.schema.yml +45 -0
  195. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +158 -0
  196. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +29 -0
  197. simtools/schemas/model_parameters/focus_offset.schema.yml +66 -0
  198. simtools/schemas/model_parameters/gain_variation.schema.yml +43 -0
  199. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +34 -0
  200. simtools/schemas/model_parameters/geomag_rotation.schema.yml +37 -0
  201. simtools/schemas/model_parameters/geomag_vertical.schema.yml +34 -0
  202. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +36 -0
  203. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +34 -0
  204. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +34 -0
  205. simtools/schemas/model_parameters/laser_events.schema.yml +36 -0
  206. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +35 -0
  207. simtools/schemas/model_parameters/laser_photons.schema.yml +32 -0
  208. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +34 -0
  209. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +34 -0
  210. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +33 -0
  211. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +33 -0
  212. simtools/schemas/model_parameters/laser_var_photons.schema.yml +33 -0
  213. simtools/schemas/model_parameters/laser_wavelength.schema.yml +33 -0
  214. simtools/schemas/model_parameters/led_events.schema.yml +34 -0
  215. simtools/schemas/model_parameters/led_photons.schema.yml +34 -0
  216. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +32 -0
  217. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +33 -0
  218. simtools/schemas/model_parameters/led_var_photons.schema.yml +34 -0
  219. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +41 -0
  220. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +43 -0
  221. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +35 -0
  222. simtools/schemas/model_parameters/min_photons.schema.yml +32 -0
  223. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +36 -0
  224. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +64 -0
  225. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +64 -0
  226. simtools/schemas/model_parameters/mirror_class.schema.yml +41 -0
  227. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +51 -0
  228. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +42 -0
  229. simtools/schemas/model_parameters/mirror_list.schema.yml +38 -0
  230. simtools/schemas/model_parameters/mirror_offset.schema.yml +41 -0
  231. simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +39 -0
  232. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +61 -0
  233. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +40 -0
  234. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +46 -0
  235. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +51 -0
  236. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +37 -0
  237. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +79 -0
  238. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +47 -0
  239. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +34 -0
  240. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +33 -0
  241. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +35 -0
  242. simtools/schemas/model_parameters/nsb_skymap.schema.yml +39 -0
  243. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +50 -0
  244. simtools/schemas/model_parameters/num_gains.schema.yml +34 -0
  245. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +33 -0
  246. simtools/schemas/model_parameters/optics_properties.schema.yml +31 -0
  247. simtools/schemas/model_parameters/parabolic_dish.schema.yml +32 -0
  248. simtools/schemas/model_parameters/pedestal_events.schema.yml +32 -0
  249. simtools/schemas/model_parameters/photon_delay.schema.yml +38 -0
  250. simtools/schemas/model_parameters/photons_per_run.schema.yml +33 -0
  251. simtools/schemas/model_parameters/pixel_cells.schema.yml +35 -0
  252. simtools/schemas/model_parameters/pixels_parallel.schema.yml +54 -0
  253. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +40 -0
  254. simtools/schemas/model_parameters/pm_average_gain.schema.yml +34 -0
  255. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +40 -0
  256. simtools/schemas/model_parameters/pm_gain_index.schema.yml +36 -0
  257. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +41 -0
  258. simtools/schemas/model_parameters/pm_transit_time.schema.yml +63 -0
  259. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +39 -0
  260. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +42 -0
  261. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +33 -0
  262. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +33 -0
  263. simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +29 -0
  264. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +168 -0
  265. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +36 -0
  266. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +34 -0
  267. simtools/schemas/model_parameters/qe_variation.schema.yml +43 -0
  268. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +42 -0
  269. simtools/schemas/model_parameters/random_focal_length.schema.yml +45 -0
  270. simtools/schemas/model_parameters/random_generator.schema.yml +36 -0
  271. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +35 -0
  272. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +36 -0
  273. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +36 -0
  274. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +34 -0
  275. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +34 -0
  276. simtools/schemas/model_parameters/sampled_output.schema.yml +31 -0
  277. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +34 -0
  278. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +79 -0
  279. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +42 -0
  280. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +41 -0
  281. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +33 -0
  282. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +36 -0
  283. simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +29 -0
  284. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +168 -0
  285. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +36 -0
  286. simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +35 -0
  287. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +37 -0
  288. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +40 -0
  289. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +40 -0
  290. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +41 -0
  291. simtools/schemas/model_parameters/tailcut_scale.schema.yml +40 -0
  292. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +31 -0
  293. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +35 -0
  294. simtools/schemas/model_parameters/telescope_random_error.schema.yml +34 -0
  295. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +37 -0
  296. simtools/schemas/model_parameters/telescope_transmission.schema.yml +113 -0
  297. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +41 -0
  298. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +36 -0
  299. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +36 -0
  300. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +37 -0
  301. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +38 -0
  302. simtools/schemas/model_parameters/transit_time_error.schema.yml +45 -0
  303. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +36 -0
  304. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +32 -0
  305. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +53 -0
  306. simtools/schemas/model_parameters/trigger_pixels.schema.yml +40 -0
  307. simtools/simtel/simtel_config_reader.py +353 -0
  308. simtools/simtel/simtel_config_writer.py +244 -63
  309. simtools/simtel/{simtel_events.py → simtel_io_events.py} +26 -25
  310. simtools/simtel/simtel_io_histogram.py +661 -0
  311. simtools/simtel/simtel_io_histograms.py +569 -0
  312. simtools/simtel/simulator_array.py +145 -0
  313. simtools/simtel/{simtel_runner_camera_efficiency.py → simulator_camera_efficiency.py} +76 -52
  314. simtools/simtel/simulator_light_emission.py +473 -0
  315. simtools/simtel/simulator_ray_tracing.py +262 -0
  316. simtools/simulator.py +220 -446
  317. simtools/testing/__init__.py +0 -0
  318. simtools/testing/assertions.py +151 -0
  319. simtools/testing/configuration.py +226 -0
  320. simtools/testing/helpers.py +42 -0
  321. simtools/testing/validate_output.py +240 -0
  322. simtools/utils/general.py +340 -437
  323. simtools/utils/geometry.py +12 -12
  324. simtools/utils/names.py +258 -644
  325. simtools/utils/value_conversion.py +176 -0
  326. simtools/version.py +2 -0
  327. simtools/visualization/legend_handlers.py +135 -152
  328. simtools/visualization/plot_camera.py +379 -0
  329. simtools/visualization/visualize.py +346 -167
  330. gammasimtools-0.6.1.dist-info/METADATA +0 -180
  331. gammasimtools-0.6.1.dist-info/RECORD +0 -91
  332. gammasimtools-0.6.1.dist-info/entry_points.txt +0 -23
  333. simtools/applications/db_development_tools/add_new_parameter_to_db.py +0 -81
  334. simtools/applications/db_development_tools/add_unit_to_parameter_in_db.py +0 -59
  335. simtools/applications/db_development_tools/mark_non_optics_parameters_non_applicable.py +0 -102
  336. simtools/applications/get_parameter.py +0 -92
  337. simtools/applications/make_regular_arrays.py +0 -160
  338. simtools/applications/produce_array_config.py +0 -136
  339. simtools/applications/production.py +0 -313
  340. simtools/applications/sim_showers_for_trigger_rates.py +0 -187
  341. simtools/applications/tune_psf.py +0 -334
  342. simtools/corsika/corsika_default_config.py +0 -282
  343. simtools/corsika/corsika_runner.py +0 -450
  344. simtools/corsika_simtel/corsika_simtel_runner.py +0 -197
  345. simtools/db_handler.py +0 -1480
  346. simtools/ray_tracing.py +0 -525
  347. simtools/simtel/simtel_histograms.py +0 -414
  348. simtools/simtel/simtel_runner.py +0 -244
  349. simtools/simtel/simtel_runner_array.py +0 -293
  350. simtools/simtel/simtel_runner_ray_tracing.py +0 -277
  351. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/LICENSE +0 -0
  352. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/top_level.txt +0 -0
  353. /simtools/{corsika_simtel → db}/__init__.py +0 -0
@@ -1,5 +1,8 @@
1
+ """Command line parser for applications."""
2
+
1
3
  import argparse
2
4
  import logging
5
+ import re
3
6
  from pathlib import Path
4
7
 
5
8
  import astropy.units as u
@@ -18,7 +21,7 @@ class CommandLineParser(argparse.ArgumentParser):
18
21
 
19
22
  Wrapper around standard python argparse.ArgumentParser.
20
23
 
21
- Command line arguments should be given in snake_case, e.g. `input_meta`.
24
+ Command line arguments should be given in snake_case, e.g. input_meta.
22
25
 
23
26
  Parameters
24
27
  ----------
@@ -31,13 +34,13 @@ class CommandLineParser(argparse.ArgumentParser):
31
34
  self,
32
35
  paths=True,
33
36
  output=False,
34
- telescope_model=False,
35
- site_model=False,
37
+ simulation_model=None,
38
+ simulation_configuration=None,
36
39
  db_config=False,
37
40
  job_submission=False,
38
41
  ):
39
42
  """
40
- Initialize default arguments used by all applications (e.g., verbosity or test flag).
43
+ Initialize default arguments used by all applications (e.g., log level or test flag).
41
44
 
42
45
  Parameters
43
46
  ----------
@@ -45,20 +48,18 @@ class CommandLineParser(argparse.ArgumentParser):
45
48
  Add path configuration to list of args.
46
49
  output: bool
47
50
  Add output file configuration to list of args.
48
- telescope_model: bool
49
- Add telescope model configuration to list of args.
50
- site_model: bool
51
- Add site model configuration to list of args (not required of telescope_model is True).
51
+ simulation_model: list
52
+ List of simulation model configuration parameters to add to list of args
53
+ (use: 'version', 'telescope', 'site')
54
+ simulation_configuration: dict
55
+ Dict of simulation software configuration parameters to add to list of args.
52
56
  db_config: bool
53
57
  Add database configuration parameters to list of args.
54
58
  job_submission: bool
55
59
  Add job submission configuration parameters to list of args.
56
60
  """
57
-
58
- if telescope_model:
59
- self.initialize_telescope_model_arguments()
60
- elif site_model:
61
- self.initialize_telescope_model_arguments(add_telescope=False)
61
+ self.initialize_simulation_model_arguments(simulation_model)
62
+ self.initialize_simulation_configuration_arguments(simulation_configuration)
62
63
  if job_submission:
63
64
  self.initialize_job_submission_arguments()
64
65
  if db_config:
@@ -71,11 +72,7 @@ class CommandLineParser(argparse.ArgumentParser):
71
72
  self.initialize_application_execution_arguments()
72
73
 
73
74
  def initialize_config_files(self):
74
- """
75
- Initialize configuration files.
76
-
77
- """
78
-
75
+ """Initialize configuration files."""
79
76
  _job_group = self.add_argument_group("configuration")
80
77
  _job_group.add_argument(
81
78
  "--config",
@@ -93,9 +90,7 @@ class CommandLineParser(argparse.ArgumentParser):
93
90
  )
94
91
 
95
92
  def initialize_path_arguments(self):
96
- """
97
- Initialize paths.
98
- """
93
+ """Initialize paths."""
99
94
  _job_group = self.add_argument_group("paths")
100
95
  _job_group.add_argument(
101
96
  "--data_path",
@@ -132,10 +127,7 @@ class CommandLineParser(argparse.ArgumentParser):
132
127
  )
133
128
 
134
129
  def initialize_output_arguments(self):
135
- """
136
- Initialize application output files(s)
137
- """
138
-
130
+ """Initialize application output files(s)."""
139
131
  _job_group = self.add_argument_group("output")
140
132
  _job_group.add_argument(
141
133
  "--output_file",
@@ -159,10 +151,7 @@ class CommandLineParser(argparse.ArgumentParser):
159
151
  )
160
152
 
161
153
  def initialize_application_execution_arguments(self):
162
- """
163
- Initialize application execution arguments.
164
- """
165
-
154
+ """Initialize application execution arguments."""
166
155
  _job_group = self.add_argument_group("execution")
167
156
  _job_group.add_argument(
168
157
  "--test",
@@ -187,11 +176,8 @@ class CommandLineParser(argparse.ArgumentParser):
187
176
  )
188
177
 
189
178
  def initialize_db_config_arguments(self):
190
- """
191
- Initialize DB configuration parameters.
192
- """
193
-
194
- _job_group = self.add_argument_group("MongoDB configuration")
179
+ """Initialize DB configuration parameters."""
180
+ _job_group = self.add_argument_group("database configuration")
195
181
  _job_group.add_argument("--db_api_user", help="database user", type=str, required=False)
196
182
  _job_group.add_argument("--db_api_pw", help="database password", type=str, required=False)
197
183
  _job_group.add_argument("--db_api_port", help="database port", type=int, required=False)
@@ -205,68 +191,324 @@ class CommandLineParser(argparse.ArgumentParser):
205
191
  required=False,
206
192
  default="admin",
207
193
  )
194
+ _job_group.add_argument(
195
+ "--db_simulation_model",
196
+ help="name of simulation model database",
197
+ type=str.strip,
198
+ required=False,
199
+ default=None,
200
+ )
201
+ _job_group.add_argument(
202
+ "--db_simulation_model_url",
203
+ help="simulation model repository URL",
204
+ type=str,
205
+ required=False,
206
+ default=None,
207
+ )
208
208
 
209
209
  def initialize_job_submission_arguments(self):
210
- """
211
- Initialize job submission arguments for simulator.
212
-
213
- """
210
+ """Initialize job submission arguments for simulator."""
214
211
  _job_group = self.add_argument_group("job submission")
215
212
  _job_group.add_argument(
216
- "--submit_command",
213
+ "--submit_engine",
217
214
  help="job submission command",
218
215
  type=str,
219
216
  required=True,
220
217
  choices=[
221
218
  "qsub",
222
- "condor_submit",
219
+ "htcondor",
223
220
  "local",
224
221
  ],
222
+ default="local",
225
223
  )
226
224
  _job_group.add_argument(
227
- "--extra_submit_options",
228
- help="additional options for submission command",
225
+ "--submit_options",
226
+ help="additional options (comma separated) for submission command",
229
227
  type=str,
230
228
  required=False,
231
229
  )
232
230
 
233
- def initialize_telescope_model_arguments(self, add_model_version=True, add_telescope=True):
231
+ def initialize_simulation_model_arguments(self, model_options):
234
232
  """
235
- Initialize default arguments for site and telescope model definition
233
+ Initialize default arguments for simulation model definition.
234
+
235
+ Note that the model version is always required.
236
236
 
237
237
  Parameters
238
238
  ----------
239
- add_model_version: bool
240
- Set to allow a simulation model argument.
241
- add_telescope: bool
242
- Set to allow a telescope name argument.
239
+ model_options: list
240
+ Options to be set: "telescope", "site", "layout", "layout_file"
243
241
  """
242
+ if model_options is None:
243
+ return
244
244
 
245
- if add_telescope:
246
- _job_group = self.add_argument_group("telescope model")
247
- else:
248
- _job_group = self.add_argument_group("site model")
245
+ _job_group = self.add_argument_group("simulation model")
249
246
  _job_group.add_argument(
250
- "--site", help="CTAO site (e.g., North, South)", type=self.site, required=False
247
+ "--model_version",
248
+ help="model version",
249
+ type=str,
250
+ default=None,
251
251
  )
252
- if add_telescope:
252
+ if any(
253
+ option in model_options for option in ["site", "telescope", "layout", "layout_file"]
254
+ ):
255
+ self._add_model_option_site(_job_group)
256
+
257
+ if "telescope" in model_options:
253
258
  _job_group.add_argument(
254
259
  "--telescope",
255
- help="telescope model name (e.g., LST-1, SST-D, ...)",
260
+ help="telescope model name (e.g., LSTN-01, SSTS-design, ...)",
256
261
  type=self.telescope,
257
262
  )
258
- if add_model_version:
259
263
  _job_group.add_argument(
260
- "--model_version",
261
- help="model version",
264
+ "--telescope_model_file",
265
+ help=(
266
+ "File with changes to telescope model "
267
+ " (yaml format; experimental with insufficient validation steps)."
268
+ ),
269
+ type=Path,
270
+ required=False,
271
+ )
272
+ if "layout" in model_options or "layout_file" in model_options:
273
+ _job_group = self._add_model_option_layout(
274
+ job_group=_job_group,
275
+ add_layout_file="layout_file" in model_options,
276
+ # layout info is always required for layout related tasks with the exception
277
+ # of listing the available layouts in the DB
278
+ required="--list_available_layouts" not in self._option_string_actions,
279
+ )
280
+
281
+ def initialize_simulation_configuration_arguments(self, simulation_configuration):
282
+ """
283
+ Initialize default arguments for simulation configuration and simulation software.
284
+
285
+ Parameters
286
+ ----------
287
+ simulation_configuration: dict
288
+ Dict of simulation software configuration parameters.
289
+ """
290
+ if simulation_configuration is None:
291
+ return
292
+
293
+ if "software" in simulation_configuration:
294
+ self._initialize_simulation_software()
295
+ if "corsika_configuration" in simulation_configuration:
296
+ self._initialize_simulation_configuration(
297
+ group_name="simulation configuration",
298
+ selected_parameters=simulation_configuration["corsika_configuration"],
299
+ available_parameters=self._get_dictionary_with_corsika_configuration(),
300
+ )
301
+ self._initialize_simulation_configuration(
302
+ group_name="shower parameters",
303
+ selected_parameters=simulation_configuration["corsika_configuration"],
304
+ available_parameters=self._get_dictionary_with_shower_configuration(),
305
+ )
306
+
307
+ def _initialize_simulation_software(self):
308
+ """Initialize simulation software arguments."""
309
+ _software_group = self.add_argument_group("simulation software")
310
+ _software_group.add_argument(
311
+ "--simulation_software",
312
+ help="Simulation software steps.",
313
+ type=str,
314
+ choices=["corsika", "simtel", "corsika_simtel"],
315
+ required=True,
316
+ default="corsika_simtel",
317
+ )
318
+
319
+ @staticmethod
320
+ def _get_dictionary_with_corsika_configuration():
321
+ """Return dictionary with CORSIKA configuration parameters."""
322
+ from simtools.corsika.primary_particle import PrimaryParticle # pylint: disable=C0415
323
+
324
+ return {
325
+ "primary": {
326
+ "help": (
327
+ "Primary particle to simulate. "
328
+ "(choices for common names: "
329
+ f"{', '.join(PrimaryParticle.particle_names().keys())}; "
330
+ "use '--primary_ID_type' to use other particle ID types)."
331
+ ),
332
+ "type": str.lower,
333
+ "required": True,
334
+ },
335
+ "primary_id_type": {
336
+ "help": "Primary particle ID type",
337
+ "type": str,
338
+ "required": False,
339
+ "choices": ["common_name", "corsika7_id", "pdg_id"],
340
+ "default": "common_name",
341
+ },
342
+ "azimuth_angle": {
343
+ "help": (
344
+ "Telescope pointing direction in azimuth. "
345
+ "It can be in degrees between 0 and 360 or one of north, south, east or west. "
346
+ "North is 0 degrees and the azimuth grows clockwise (East is 90 degrees)."
347
+ ),
348
+ "type": CommandLineParser.azimuth_angle,
349
+ "required": True,
350
+ },
351
+ "zenith_angle": {
352
+ "help": "Zenith angle in degrees (between 0 and 180).",
353
+ "type": CommandLineParser.zenith_angle,
354
+ "required": True,
355
+ },
356
+ "nshow": {
357
+ "help": "Number of showers per run to simulate.",
358
+ "type": int,
359
+ "required": False,
360
+ },
361
+ "run_number_start": {
362
+ "help": "Run number for the first run.",
363
+ "type": int,
364
+ "required": True,
365
+ "default": 1,
366
+ },
367
+ "number_of_runs": {
368
+ "help": "Number of runs to be simulated.",
369
+ "type": int,
370
+ "required": True,
371
+ "default": 1,
372
+ },
373
+ "event_number_first_shower": {
374
+ "help": "Event number of first shower",
375
+ "type": int,
376
+ "required": False,
377
+ "default": 1,
378
+ },
379
+ "correct_for_b_field_alignment": {
380
+ "help": "Correct for B-field alignment",
381
+ "action": "store_true",
382
+ "required": False,
383
+ "default": True,
384
+ },
385
+ }
386
+
387
+ @staticmethod
388
+ def _get_dictionary_with_shower_configuration():
389
+ """Return dictionary with shower configuration parameters."""
390
+ return {
391
+ "eslope": {
392
+ "help": "Slope of the energy spectrum.",
393
+ "type": float,
394
+ "required": False,
395
+ "default": -2.0,
396
+ },
397
+ "energy_range": {
398
+ "help": (
399
+ "Energy range of the primary particle (min/max value, e'g', '10 GeV 5 TeV')."
400
+ ),
401
+ "type": CommandLineParser.parse_quantity_pair,
402
+ "required": False,
403
+ "default": ["3 GeV 330 TeV"],
404
+ },
405
+ "view_cone": {
406
+ "help": (
407
+ "View cone radius for primary arrival directions "
408
+ "(min/max value, e.g. '0 deg 10 deg')."
409
+ ),
410
+ "type": CommandLineParser.parse_quantity_pair,
411
+ "required": False,
412
+ "default": ["0 deg 0 deg"],
413
+ },
414
+ "core_scatter": {
415
+ "help": "Scatter radius for shower cores (number of use; scatter radius).",
416
+ "type": CommandLineParser.parse_integer_and_quantity,
417
+ "required": False,
418
+ "default": ["10 1400 m"],
419
+ },
420
+ }
421
+
422
+ def _initialize_simulation_configuration(
423
+ self, group_name, selected_parameters, available_parameters
424
+ ):
425
+ """
426
+ Initialize simulation configuration arguments.
427
+
428
+ Parameters
429
+ ----------
430
+ group_name : str
431
+ Name of the group of arguments.
432
+ selected_parameters : list
433
+ List of selected parameters to be added to the group.
434
+ available_parameters : dict
435
+ Dictionary with available parameters and their configuration.
436
+ """
437
+ configuration_group = self.add_argument_group(group_name)
438
+
439
+ if "all" in selected_parameters:
440
+ selected_parameters = available_parameters.keys()
441
+
442
+ for param in selected_parameters:
443
+ try:
444
+ configuration_group.add_argument(f"--{param}", **available_parameters[param])
445
+ except KeyError:
446
+ pass
447
+
448
+ @staticmethod
449
+ def _add_model_option_layout(job_group, add_layout_file, required=True):
450
+ """
451
+ Add layout option to the job group.
452
+
453
+ Parameters
454
+ ----------
455
+ job_group: argparse.ArgumentParser
456
+ Job group
457
+ add_layout_file: bool
458
+ Add layout file option
459
+
460
+ Returns
461
+ -------
462
+ argparse.ArgumentParser
463
+ """
464
+ _layout_group = job_group.add_mutually_exclusive_group(required=required)
465
+ _layout_group.add_argument(
466
+ "--array_layout_name",
467
+ help="array layout name (e.g., alpha, subsystem_msts)",
468
+ type=str,
469
+ required=False,
470
+ )
471
+ _layout_group.add_argument(
472
+ "--array_element_list",
473
+ help="list of array elements (e.g., LSTN-01, LSTN-02, MSTN).",
474
+ nargs="+",
475
+ type=str,
476
+ required=False,
477
+ default=None,
478
+ )
479
+ if add_layout_file:
480
+ _layout_group.add_argument(
481
+ "--array_layout_file",
482
+ help="file(s) with the list of array elements (astropy table format).",
483
+ nargs="+",
262
484
  type=str,
263
- default="Released",
485
+ required=False,
486
+ default=None,
264
487
  )
488
+ return job_group
489
+
490
+ def _add_model_option_site(self, job_group):
491
+ """
492
+ Add site option to the job group.
493
+
494
+ Parameters
495
+ ----------
496
+ job_group: argparse.ArgumentParser
497
+ Job group
498
+
499
+ Returns
500
+ -------
501
+ argparse.ArgumentParser
502
+ """
503
+ job_group.add_argument(
504
+ "--site", help="site (e.g., North, South)", type=self.site, required=False
505
+ )
506
+ return job_group
265
507
 
266
508
  @staticmethod
267
509
  def site(value):
268
510
  """
269
- Argument parser type to check that a valid site name is given
511
+ Argument parser type to check that a valid site name is given.
270
512
 
271
513
  Parameters
272
514
  ----------
@@ -282,16 +524,14 @@ class CommandLineParser(argparse.ArgumentParser):
282
524
  ------
283
525
  argparse.ArgumentTypeError
284
526
  for invalid sites
285
-
286
527
  """
287
-
288
528
  names.validate_site_name(str(value))
289
529
  return str(value)
290
530
 
291
531
  @staticmethod
292
532
  def telescope(value):
293
533
  """
294
- Argument parser type to check that a valid telescope name is given
534
+ Argument parser type to check that a valid telescope name is given.
295
535
 
296
536
  Parameters
297
537
  ----------
@@ -307,17 +547,14 @@ class CommandLineParser(argparse.ArgumentParser):
307
547
  ------
308
548
  argparse.ArgumentTypeError
309
549
  for invalid telescope
310
-
311
550
  """
312
-
313
- names.validate_telescope_model_name(str(value))
551
+ names.validate_array_element_name(str(value))
314
552
  return str(value)
315
553
 
316
554
  @staticmethod
317
555
  def efficiency_interval(value):
318
556
  """
319
- Argument parser type to check that value is an efficiency
320
- in the interval [0,1]
557
+ Argument parser type to check that value is an efficiency in the interval [0,1].
321
558
 
322
559
  Parameters
323
560
  ----------
@@ -333,8 +570,6 @@ class CommandLineParser(argparse.ArgumentParser):
333
570
  ------
334
571
  argparse.ArgumentTypeError
335
572
  When value is outside of the interval [0,1]
336
-
337
-
338
573
  """
339
574
  fvalue = float(value)
340
575
  if fvalue < 0.0 or fvalue > 1.0:
@@ -346,9 +581,10 @@ class CommandLineParser(argparse.ArgumentParser):
346
581
  def zenith_angle(angle):
347
582
  """
348
583
  Argument parser type to check that the zenith angle provided is in the interval [0, 180].
584
+
349
585
  We allow here zenith angles larger than 90 degrees in the improbable case
350
586
  such simulations are requested. It is not guaranteed that the actual simulation software
351
- supports such angles!
587
+ supports such angles!.
352
588
 
353
589
  Parameters
354
590
  ----------
@@ -364,10 +600,7 @@ class CommandLineParser(argparse.ArgumentParser):
364
600
  ------
365
601
  argparse.ArgumentTypeError
366
602
  When angle is outside of the interval [0, 180]
367
-
368
-
369
603
  """
370
-
371
604
  logger = logging.getLogger(__name__)
372
605
 
373
606
  try:
@@ -385,13 +618,13 @@ class CommandLineParser(argparse.ArgumentParser):
385
618
  f"The provided zenith angle, {angle:.1f}, "
386
619
  "is outside of the allowed [0, 180] interval"
387
620
  )
388
-
389
621
  return fangle
390
622
 
391
623
  @staticmethod
392
624
  def azimuth_angle(angle):
393
625
  """
394
626
  Argument parser type to check that the azimuth angle provided is in the interval [0, 360].
627
+
395
628
  Other allowed options are north, south, east or west which will be translated to an angle
396
629
  where north corresponds to zero.
397
630
 
@@ -409,10 +642,7 @@ class CommandLineParser(argparse.ArgumentParser):
409
642
  ------
410
643
  argparse.ArgumentTypeError
411
644
  When angle is outside of the interval [0, 360] or not in (north, south, east, west)
412
-
413
-
414
645
  """
415
-
416
646
  logger = logging.getLogger(__name__)
417
647
  try:
418
648
  fangle = float(angle)
@@ -428,6 +658,9 @@ class CommandLineParser(argparse.ArgumentParser):
428
658
  "The azimuth angle provided is not a valid numeric value. "
429
659
  "Will check if it is an astropy.Quantity instead"
430
660
  )
661
+ except TypeError as exc:
662
+ logger.error("The azimuth angle provided is not a valid numerical or string value.")
663
+ raise exc
431
664
  try:
432
665
  return u.Quantity(angle).to("deg")
433
666
  except TypeError:
@@ -435,22 +668,77 @@ class CommandLineParser(argparse.ArgumentParser):
435
668
  "The azimuth angle provided is not a valid astropy.Quantity. "
436
669
  "Will check if it is (north, south, east, west) instead"
437
670
  )
438
- if isinstance(angle, str):
439
- azimuth_angle = angle.lower()
440
- if azimuth_angle == "north":
441
- return 0 * u.deg
442
- if azimuth_angle == "south":
443
- return 180 * u.deg
444
- if azimuth_angle == "east":
445
- return 90 * u.deg
446
- if azimuth_angle == "west":
447
- return 270 * u.deg
448
- raise argparse.ArgumentTypeError(
449
- "The azimuth angle can only be a number or one of "
450
- f"(north, south, east, west), not {angle}"
451
- )
452
- logger.error(
453
- f"The azimuth value provided, {angle}, is not a valid number "
454
- "nor one of (north, south, east, west)."
671
+ azimuth_map = {
672
+ "north": 0 * u.deg,
673
+ "south": 180 * u.deg,
674
+ "east": 90 * u.deg,
675
+ "west": 270 * u.deg,
676
+ }
677
+ azimuth_angle = angle.lower()
678
+ if azimuth_angle in azimuth_map:
679
+ return azimuth_map[azimuth_angle]
680
+ raise argparse.ArgumentTypeError(
681
+ "The azimuth angle given as string can only be one of "
682
+ f"(north, south, east, west), not {angle}. Otherwise use numerical values."
683
+ )
684
+
685
+ @staticmethod
686
+ def parse_quantity_pair(string):
687
+ """
688
+ Parse a string representing a pair of astropy quantities separated by a space.
689
+
690
+ Args:
691
+ string: The input string (e.g., "0 deg 1.5 deg").
692
+
693
+ Returns
694
+ -------
695
+ tuple: A tuple containing two astropy.units.Quantity objects.
696
+
697
+ Raises
698
+ ------
699
+ ValueError: If the string is not formatted correctly (e.g., missing space).
700
+ """
701
+ pattern = r"(\d+\.?\d*)\s*([a-zA-Z]+)"
702
+ matches = re.findall(pattern, string)
703
+ if len(matches) != 2:
704
+ raise ValueError("Input string does not contain exactly two quantities.")
705
+
706
+ return (
707
+ u.Quantity(float(matches[0][0]), matches[0][1]),
708
+ u.Quantity(float(matches[1][0]), matches[1][1]),
455
709
  )
456
- raise TypeError
710
+
711
+ @staticmethod
712
+ def parse_integer_and_quantity(input_string):
713
+ """
714
+ Parse a string representing an integer and a quantity with units.
715
+
716
+ This is e.g., used for the 'core_scatter' argument.
717
+
718
+ Parameters
719
+ ----------
720
+ input_string: str
721
+ The input string (e.g., "5 1500 m") or
722
+ a tuple converted to string (e.g., "(5, <Quantity 1500 m>)").
723
+
724
+ Returns
725
+ -------
726
+ tuple: A tuple containing an integer and an astropy.units.Quantity object.
727
+
728
+ Raises
729
+ ------
730
+ ValueError: If the input string does not match the required format.
731
+ """
732
+ # tuple converted to string: "(5, <Quantity 1500 m>)"
733
+ if all(char in input_string for char in ["(", ")", ","]):
734
+ pattern = r"\((\d+), <Quantity ([\d.]+) (.+)>\)"
735
+ match = re.match(pattern, input_string)
736
+ # string with integer and quantity: "5 1500 m"
737
+ else:
738
+ pattern = r"(\d+)\s+(\d+\.?\d*)\s*([a-zA-Z]+)"
739
+ match = re.match(pattern, input_string.strip())
740
+
741
+ if not match:
742
+ raise ValueError("Input string does not contain an integer and a astropy quantity.")
743
+
744
+ return (int(match.group(1)), u.Quantity(float(match.group(2)), match.group(3)))