gammasimtools 0.21.0__py3-none-any.whl → 0.23.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 (370) hide show
  1. {gammasimtools-0.21.0.dist-info → gammasimtools-0.23.0.dist-info}/METADATA +3 -3
  2. gammasimtools-0.23.0.dist-info/RECORD +414 -0
  3. {gammasimtools-0.21.0.dist-info → gammasimtools-0.23.0.dist-info}/entry_points.txt +2 -1
  4. simtools/_version.py +2 -2
  5. simtools/application_control.py +118 -0
  6. simtools/applications/calculate_incident_angles.py +17 -25
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +29 -45
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +26 -45
  9. simtools/applications/convert_model_parameter_from_simtel.py +21 -42
  10. simtools/applications/db_add_file_to_db.py +12 -13
  11. simtools/applications/db_add_simulation_model_from_repository_to_db.py +20 -33
  12. simtools/applications/db_add_value_from_json_to_db.py +28 -23
  13. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +19 -34
  14. simtools/applications/db_generate_compound_indexes.py +12 -27
  15. simtools/applications/db_get_array_layouts_from_db.py +19 -39
  16. simtools/applications/db_get_file_from_db.py +15 -17
  17. simtools/applications/db_get_parameter_from_db.py +33 -35
  18. simtools/applications/db_inspect_databases.py +10 -11
  19. simtools/applications/db_upload_model_repository.py +104 -0
  20. simtools/applications/derive_ctao_array_layouts.py +16 -21
  21. simtools/applications/derive_mirror_rnda.py +9 -14
  22. simtools/applications/derive_photon_electron_spectrum.py +7 -10
  23. simtools/applications/derive_psf_parameters.py +24 -21
  24. simtools/applications/derive_trigger_rates.py +6 -9
  25. simtools/applications/docs_produce_array_element_report.py +22 -23
  26. simtools/applications/docs_produce_calibration_reports.py +26 -24
  27. simtools/applications/docs_produce_model_parameter_reports.py +15 -22
  28. simtools/applications/docs_produce_simulation_configuration_report.py +21 -22
  29. simtools/applications/generate_array_config.py +14 -33
  30. simtools/applications/generate_corsika_histograms.py +22 -43
  31. simtools/applications/generate_default_metadata.py +15 -36
  32. simtools/applications/generate_regular_arrays.py +11 -15
  33. simtools/applications/generate_simtel_event_data.py +23 -33
  34. simtools/applications/maintain_simulation_model_add_production.py +17 -48
  35. simtools/applications/maintain_simulation_model_compare_productions.py +10 -12
  36. simtools/applications/maintain_simulation_model_verify_production_tables.py +8 -11
  37. simtools/applications/merge_tables.py +15 -24
  38. simtools/applications/plot_array_layout.py +77 -55
  39. simtools/applications/plot_simtel_events.py +11 -13
  40. simtools/applications/plot_tabular_data.py +17 -38
  41. simtools/applications/plot_tabular_data_for_model_parameter.py +16 -23
  42. simtools/applications/print_version.py +14 -42
  43. simtools/applications/production_derive_corsika_limits.py +5 -9
  44. simtools/applications/production_derive_statistics.py +12 -26
  45. simtools/applications/production_generate_grid.py +20 -48
  46. simtools/applications/production_merge_corsika_limits.py +17 -21
  47. simtools/applications/run_application.py +12 -32
  48. simtools/applications/simulate_flasher.py +79 -81
  49. simtools/applications/simulate_illuminator.py +56 -197
  50. simtools/applications/{simulate_calibration_events.py → simulate_pedestals.py} +22 -68
  51. simtools/applications/simulate_prod.py +21 -33
  52. simtools/applications/simulate_prod_htcondor_generator.py +11 -25
  53. simtools/applications/submit_array_layouts.py +15 -18
  54. simtools/applications/submit_data_from_external.py +18 -34
  55. simtools/applications/submit_model_parameter_from_external.py +27 -41
  56. simtools/applications/validate_camera_efficiency.py +23 -22
  57. simtools/applications/validate_camera_fov.py +21 -27
  58. simtools/applications/validate_cumulative_psf.py +28 -37
  59. simtools/applications/validate_file_using_schema.py +35 -45
  60. simtools/applications/validate_optics.py +27 -33
  61. simtools/camera/camera_efficiency.py +8 -13
  62. simtools/configuration/commandline_parser.py +33 -11
  63. simtools/configuration/configurator.py +0 -7
  64. simtools/corsika/corsika_config.py +9 -16
  65. simtools/corsika/corsika_histograms.py +1 -1
  66. simtools/data_model/data_reader.py +0 -2
  67. simtools/data_model/metadata_collector.py +0 -2
  68. simtools/data_model/model_data_writer.py +87 -27
  69. simtools/data_model/schema.py +61 -2
  70. simtools/data_model/validate_data.py +1 -3
  71. simtools/db/db_handler.py +58 -39
  72. simtools/db/db_model_upload.py +210 -5
  73. simtools/io/hdf5_handler.py +0 -5
  74. simtools/io/io_handler.py +31 -83
  75. simtools/io/legacy_data_handler.py +0 -5
  76. simtools/job_execution/job_manager.py +43 -1
  77. simtools/layout/array_layout.py +0 -2
  78. simtools/layout/array_layout_utils.py +1 -5
  79. simtools/layout/telescope_position.py +0 -2
  80. simtools/model/array_model.py +95 -46
  81. simtools/model/calibration_model.py +0 -2
  82. simtools/model/camera.py +0 -2
  83. simtools/model/mirrors.py +0 -2
  84. simtools/model/model_parameter.py +50 -16
  85. simtools/model/model_repository.py +139 -106
  86. simtools/model/model_utils.py +21 -11
  87. simtools/model/site_model.py +0 -2
  88. simtools/model/telescope_model.py +20 -2
  89. simtools/production_configuration/calculate_statistical_uncertainties_grid_point.py +0 -2
  90. simtools/production_configuration/derive_corsika_limits.py +1 -1
  91. simtools/production_configuration/derive_production_statistics.py +0 -2
  92. simtools/production_configuration/interpolation_handler.py +0 -2
  93. simtools/ray_tracing/incident_angles.py +7 -7
  94. simtools/ray_tracing/mirror_panel_psf.py +1 -1
  95. simtools/ray_tracing/psf_analysis.py +0 -2
  96. simtools/ray_tracing/psf_parameter_optimisation.py +180 -73
  97. simtools/ray_tracing/ray_tracing.py +1 -5
  98. simtools/reporting/docs_auto_report_generator.py +108 -0
  99. simtools/reporting/docs_read_parameters.py +168 -104
  100. simtools/resources/array_elements.yml +26 -0
  101. simtools/runners/corsika_runner.py +0 -2
  102. simtools/runners/corsika_simtel_runner.py +11 -19
  103. simtools/runners/runner_services.py +5 -6
  104. simtools/runners/simtel_runner.py +0 -2
  105. simtools/runners/simtools_runner.py +0 -2
  106. simtools/schemas/application_workflow.metaschema.yml +1 -1
  107. simtools/schemas/common_definitions.schema.yml +39 -0
  108. simtools/schemas/model_parameter.metaschema.yml +19 -13
  109. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +6 -12
  110. simtools/schemas/model_parameters/adjust_gain.schema.yml +0 -5
  111. simtools/schemas/model_parameters/altitude.schema.yml +0 -5
  112. simtools/schemas/model_parameters/array_coordinates.schema.yml +0 -5
  113. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +0 -5
  114. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +0 -7
  115. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +0 -7
  116. simtools/schemas/model_parameters/array_layouts.schema.yml +0 -5
  117. simtools/schemas/model_parameters/array_triggers.schema.yml +0 -5
  118. simtools/schemas/model_parameters/array_window.schema.yml +0 -7
  119. simtools/schemas/model_parameters/asum_clipping.schema.yml +0 -3
  120. simtools/schemas/model_parameters/asum_offset.schema.yml +0 -7
  121. simtools/schemas/model_parameters/asum_shaping.schema.yml +0 -7
  122. simtools/schemas/model_parameters/asum_threshold.schema.yml +0 -7
  123. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +0 -5
  124. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +0 -5
  125. simtools/schemas/model_parameters/axes_offsets.schema.yml +0 -7
  126. simtools/schemas/model_parameters/calibration_devices.schema.yml +30 -0
  127. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +0 -7
  128. simtools/schemas/model_parameters/camera_body_shape.schema.yml +0 -7
  129. simtools/schemas/model_parameters/camera_config_file.schema.yml +0 -7
  130. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +0 -7
  131. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +0 -7
  132. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +0 -7
  133. simtools/schemas/model_parameters/camera_depth.schema.yml +0 -7
  134. simtools/schemas/model_parameters/camera_filter.schema.yml +0 -7
  135. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +0 -3
  136. simtools/schemas/model_parameters/camera_pixels.schema.yml +0 -7
  137. simtools/schemas/model_parameters/camera_transmission.schema.yml +0 -7
  138. simtools/schemas/model_parameters/channels_per_chip.schema.yml +0 -7
  139. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +0 -7
  140. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +0 -5
  141. simtools/schemas/model_parameters/dark_events.schema.yml +4 -3
  142. simtools/schemas/model_parameters/default_trigger.schema.yml +0 -7
  143. simtools/schemas/model_parameters/design_model.schema.yml +0 -7
  144. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +0 -7
  145. simtools/schemas/model_parameters/disc_bins.schema.yml +0 -7
  146. simtools/schemas/model_parameters/disc_start.schema.yml +0 -7
  147. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +0 -7
  148. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +0 -7
  149. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +0 -7
  150. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +0 -7
  151. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +0 -7
  152. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +0 -7
  153. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +0 -7
  154. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +0 -7
  155. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +0 -7
  156. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +0 -7
  157. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +0 -7
  158. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -9
  159. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +0 -7
  160. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +0 -7
  161. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +0 -7
  162. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +0 -7
  163. simtools/schemas/model_parameters/dish_shape_length.schema.yml +0 -5
  164. simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -5
  165. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +0 -3
  166. simtools/schemas/model_parameters/dsum_offset.schema.yml +0 -3
  167. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +0 -3
  168. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +0 -3
  169. simtools/schemas/model_parameters/dsum_prescale.schema.yml +0 -3
  170. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +0 -3
  171. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +0 -3
  172. simtools/schemas/model_parameters/dsum_shaping.schema.yml +0 -3
  173. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +0 -3
  174. simtools/schemas/model_parameters/dsum_threshold.schema.yml +2 -12
  175. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +0 -3
  176. simtools/schemas/model_parameters/effective_focal_length.schema.yml +0 -7
  177. simtools/schemas/model_parameters/epsg_code.schema.yml +0 -5
  178. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +0 -7
  179. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -9
  180. simtools/schemas/model_parameters/fadc_bins.schema.yml +0 -7
  181. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +0 -7
  182. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +0 -2
  183. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +0 -7
  184. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +0 -7
  185. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -9
  186. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +0 -7
  187. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +0 -2
  188. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +0 -7
  189. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +0 -7
  190. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +0 -7
  191. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +0 -2
  192. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +0 -7
  193. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +0 -7
  194. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +0 -7
  195. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +0 -7
  196. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +0 -7
  197. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +0 -7
  198. simtools/schemas/model_parameters/fadc_long_event_threshold.schema.yml +0 -3
  199. simtools/schemas/model_parameters/fadc_long_sum_bins.schema.yml +0 -3
  200. simtools/schemas/model_parameters/fadc_long_sum_offset.schema.yml +0 -3
  201. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +0 -7
  202. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +0 -2
  203. simtools/schemas/model_parameters/fadc_mhz.schema.yml +0 -7
  204. simtools/schemas/model_parameters/fadc_noise.schema.yml +0 -7
  205. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +0 -7
  206. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +0 -7
  207. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +0 -7
  208. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +0 -7
  209. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +0 -7
  210. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +0 -7
  211. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +0 -7
  212. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +0 -7
  213. simtools/schemas/model_parameters/fake_mirror_list.schema.yml +0 -3
  214. simtools/schemas/model_parameters/flasher_angular_distribution.schema.yml +32 -0
  215. simtools/schemas/model_parameters/flasher_angular_distribution_width.schema.yml +32 -0
  216. simtools/schemas/model_parameters/flasher_bunch_size.schema.yml +28 -0
  217. simtools/schemas/model_parameters/flasher_external_trigger.schema.yml +32 -0
  218. simtools/schemas/model_parameters/flasher_photons.schema.yml +34 -0
  219. simtools/schemas/model_parameters/flasher_position.schema.yml +43 -0
  220. simtools/schemas/model_parameters/flasher_pulse_exp_decay.schema.yml +29 -0
  221. simtools/schemas/model_parameters/flasher_pulse_offset.schema.yml +35 -0
  222. simtools/schemas/model_parameters/flasher_pulse_shape.schema.yml +30 -0
  223. simtools/schemas/model_parameters/flasher_pulse_width.schema.yml +32 -0
  224. simtools/schemas/model_parameters/flasher_type.schema.yml +28 -0
  225. simtools/schemas/model_parameters/flasher_var_photons.schema.yml +31 -0
  226. simtools/schemas/model_parameters/flasher_wavelength.schema.yml +33 -0
  227. simtools/schemas/model_parameters/flatfielding.schema.yml +0 -7
  228. simtools/schemas/model_parameters/focal_length.schema.yml +0 -7
  229. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +0 -3
  230. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +0 -3
  231. simtools/schemas/model_parameters/focus_offset.schema.yml +0 -7
  232. simtools/schemas/model_parameters/gain_variation.schema.yml +0 -7
  233. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +2 -7
  234. simtools/schemas/model_parameters/geomag_rotation.schema.yml +2 -7
  235. simtools/schemas/model_parameters/geomag_vertical.schema.yml +2 -7
  236. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +0 -5
  237. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +0 -7
  238. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +0 -7
  239. simtools/schemas/model_parameters/laser_events.schema.yml +4 -3
  240. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +4 -3
  241. simtools/schemas/model_parameters/laser_photons.schema.yml +4 -3
  242. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +4 -3
  243. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +4 -3
  244. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +4 -3
  245. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +4 -3
  246. simtools/schemas/model_parameters/laser_var_photons.schema.yml +4 -3
  247. simtools/schemas/model_parameters/laser_wavelength.schema.yml +4 -3
  248. simtools/schemas/model_parameters/led_events.schema.yml +4 -3
  249. simtools/schemas/model_parameters/led_photons.schema.yml +4 -3
  250. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +4 -3
  251. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +4 -3
  252. simtools/schemas/model_parameters/led_var_photons.schema.yml +4 -3
  253. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +0 -7
  254. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +0 -7
  255. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +0 -7
  256. simtools/schemas/model_parameters/min_photons.schema.yml +0 -7
  257. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +0 -5
  258. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +0 -7
  259. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +0 -7
  260. simtools/schemas/model_parameters/mirror_class.schema.yml +2 -9
  261. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +0 -7
  262. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +0 -5
  263. simtools/schemas/model_parameters/mirror_list.schema.yml +0 -7
  264. simtools/schemas/model_parameters/mirror_offset.schema.yml +0 -7
  265. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +0 -7
  266. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +0 -7
  267. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +0 -7
  268. simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +0 -7
  269. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +0 -7
  270. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +0 -3
  271. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +0 -7
  272. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +0 -7
  273. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +0 -5
  274. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +0 -5
  275. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +0 -5
  276. simtools/schemas/model_parameters/nsb_sky_map.schema.yml +0 -5
  277. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +0 -5
  278. simtools/schemas/model_parameters/num_gains.schema.yml +0 -7
  279. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +0 -7
  280. simtools/schemas/model_parameters/optics_properties.schema.yml +0 -7
  281. simtools/schemas/model_parameters/parabolic_dish.schema.yml +0 -3
  282. simtools/schemas/model_parameters/pedestal_events.schema.yml +4 -7
  283. simtools/schemas/model_parameters/photon_delay.schema.yml +0 -7
  284. simtools/schemas/model_parameters/photons_per_run.schema.yml +4 -4
  285. simtools/schemas/model_parameters/pixel_cells.schema.yml +0 -3
  286. simtools/schemas/model_parameters/pixels_parallel.schema.yml +0 -3
  287. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +0 -7
  288. simtools/schemas/model_parameters/pm_average_gain.schema.yml +0 -5
  289. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +0 -5
  290. simtools/schemas/model_parameters/pm_gain_index.schema.yml +0 -5
  291. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +0 -7
  292. simtools/schemas/model_parameters/pm_transit_time.schema.yml +4 -9
  293. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +0 -5
  294. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +0 -7
  295. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +0 -3
  296. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +0 -3
  297. simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +0 -3
  298. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +0 -3
  299. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +0 -3
  300. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +0 -3
  301. simtools/schemas/model_parameters/qe_variation.schema.yml +0 -7
  302. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +0 -7
  303. simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -7
  304. simtools/schemas/model_parameters/random_generator.schema.yml +0 -7
  305. simtools/schemas/model_parameters/random_mono_probability.schema.yml +0 -7
  306. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +0 -5
  307. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +0 -5
  308. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +0 -5
  309. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +0 -5
  310. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +0 -5
  311. simtools/schemas/model_parameters/sampled_output.schema.yml +0 -7
  312. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +0 -7
  313. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +0 -3
  314. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +0 -3
  315. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +0 -3
  316. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +0 -3
  317. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +0 -3
  318. simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +0 -3
  319. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +0 -3
  320. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +0 -3
  321. simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +0 -3
  322. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +0 -3
  323. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +0 -3
  324. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +0 -3
  325. simtools/schemas/model_parameters/stars.schema.yml +0 -5
  326. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +0 -7
  327. simtools/schemas/model_parameters/tailcut_scale.schema.yml +0 -7
  328. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +0 -7
  329. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +0 -7
  330. simtools/schemas/model_parameters/telescope_random_error.schema.yml +0 -7
  331. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +0 -7
  332. simtools/schemas/model_parameters/telescope_transmission.schema.yml +0 -7
  333. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +0 -7
  334. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +0 -7
  335. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +0 -7
  336. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +0 -7
  337. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +0 -7
  338. simtools/schemas/model_parameters/transit_time_error.schema.yml +0 -7
  339. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +0 -7
  340. simtools/schemas/model_parameters/transit_time_random.schema.yml +29 -0
  341. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +0 -7
  342. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +0 -7
  343. simtools/schemas/model_parameters/trigger_pixels.schema.yml +0 -7
  344. simtools/schemas/production_tables.schema.yml +8 -8
  345. simtools/schemas/simulation_models_info.schema.yml +78 -0
  346. simtools/simtel/simtel_config_reader.py +0 -2
  347. simtools/simtel/simtel_config_writer.py +118 -26
  348. simtools/simtel/simtel_io_metadata.py +3 -3
  349. simtools/simtel/simulator_array.py +43 -85
  350. simtools/simtel/simulator_camera_efficiency.py +0 -2
  351. simtools/simtel/simulator_light_emission.py +336 -631
  352. simtools/simtel/simulator_ray_tracing.py +2 -4
  353. simtools/simulator.py +45 -19
  354. simtools/testing/assertions.py +2 -2
  355. simtools/testing/configuration.py +21 -6
  356. simtools/testing/sim_telarray_metadata.py +4 -4
  357. simtools/utils/general.py +5 -13
  358. simtools/utils/geometry.py +34 -5
  359. simtools/utils/names.py +1 -13
  360. simtools/version.py +83 -0
  361. simtools/visualization/plot_array_layout.py +129 -23
  362. simtools/visualization/plot_incident_angles.py +0 -2
  363. simtools/visualization/plot_psf.py +163 -61
  364. simtools/visualization/plot_simtel_events.py +1 -12
  365. simtools/visualization/visualize.py +0 -12
  366. gammasimtools-0.21.0.dist-info/RECORD +0 -396
  367. simtools/model/flasher_model.py +0 -106
  368. {gammasimtools-0.21.0.dist-info → gammasimtools-0.23.0.dist-info}/WHEEL +0 -0
  369. {gammasimtools-0.21.0.dist-info → gammasimtools-0.23.0.dist-info}/licenses/LICENSE +0 -0
  370. {gammasimtools-0.21.0.dist-info → gammasimtools-0.23.0.dist-info}/top_level.txt +0 -0
@@ -2,17 +2,59 @@
2
2
 
3
3
  import logging
4
4
  import subprocess
5
+ import time
5
6
  from pathlib import Path
6
7
 
7
8
  import simtools.utils.general as gen
8
9
 
9
- __all__ = ["JobExecutionError", "JobManager"]
10
+ logger = logging.getLogger(__name__)
10
11
 
11
12
 
12
13
  class JobExecutionError(Exception):
13
14
  """Job execution error."""
14
15
 
15
16
 
17
+ def retry_command(command, max_attempts=3, delay=10):
18
+ """
19
+ Execute a shell command with retry logic for network-related failures.
20
+
21
+ Parameters
22
+ ----------
23
+ command : str
24
+ Shell command to execute.
25
+ max_attempts : int
26
+ Maximum number of retry attempts (default: 3).
27
+ delay : int
28
+ Delay in seconds between attempts (default: 10).
29
+
30
+ Returns
31
+ -------
32
+ bool
33
+ True if command succeeded, False if all attempts failed.
34
+
35
+ Raises
36
+ ------
37
+ subprocess.CalledProcessError
38
+ If command fails after all retry attempts.
39
+ """
40
+ for attempt in range(1, max_attempts + 1):
41
+ logger.info(f"Attempt {attempt} of {max_attempts}: {command}")
42
+ try:
43
+ subprocess.run(command, shell=True, check=True, text=True)
44
+ logger.info(f"Command succeeded on attempt {attempt}")
45
+ return True
46
+ except subprocess.CalledProcessError as exc:
47
+ logger.warning(f"Command failed on attempt {attempt}")
48
+ if attempt < max_attempts:
49
+ logger.info(f"Waiting {delay}s before retry...")
50
+ time.sleep(delay)
51
+ else:
52
+ logger.error(f"Command failed after {max_attempts} attempts")
53
+ raise exc from None
54
+
55
+ return False
56
+
57
+
16
58
  class JobManager:
17
59
  """
18
60
  Job manager for submitting jobs to a compute node.
@@ -17,8 +17,6 @@ from simtools.model.site_model import SiteModel
17
17
  from simtools.model.telescope_model import TelescopeModel
18
18
  from simtools.utils import names, value_conversion
19
19
 
20
- __all__ = ["ArrayLayout", "InvalidTelescopeListFileError"]
21
-
22
20
 
23
21
  class InvalidTelescopeListFileError(Exception):
24
22
  """Exception for invalid telescope list file."""
@@ -154,10 +154,7 @@ def write_array_layouts(array_layouts, args_dict, db_config):
154
154
  _logger.info(f"Writing updated array layouts to the database for site {site}.")
155
155
 
156
156
  io_handler_instance = io_handler.IOHandler()
157
- io_handler_instance.set_paths(
158
- output_path=args_dict["output_path"],
159
- use_plain_output_path=args_dict["use_plain_output_path"],
160
- )
157
+ io_handler_instance.set_paths(output_path=args_dict["output_path"])
161
158
  output_file = io_handler_instance.get_output_file(
162
159
  f"array-layouts-{args_dict['updated_parameter_version']}.json"
163
160
  )
@@ -168,7 +165,6 @@ def write_array_layouts(array_layouts, args_dict, db_config):
168
165
  instrument=site,
169
166
  parameter_version=args_dict.get("updated_parameter_version"),
170
167
  output_file=output_file,
171
- use_plain_output_path=args_dict["use_plain_output_path"],
172
168
  db_config=db_config,
173
169
  )
174
170
  MetadataCollector.dump(
@@ -6,8 +6,6 @@ import astropy.units as u
6
6
  import numpy as np
7
7
  import pyproj
8
8
 
9
- __all__ = ["InvalidCoordSystemErrorError", "TelescopePosition"]
10
-
11
9
 
12
10
  class InvalidCoordSystemErrorError(Exception):
13
11
  """Exception for invalid coordinate system."""
@@ -9,13 +9,12 @@ from astropy.table import QTable
9
9
  from simtools.data_model import data_reader, schema
10
10
  from simtools.db import db_handler
11
11
  from simtools.io import io_handler
12
+ from simtools.model.calibration_model import CalibrationModel
12
13
  from simtools.model.site_model import SiteModel
13
14
  from simtools.model.telescope_model import TelescopeModel
14
15
  from simtools.simtel.simtel_config_writer import SimtelConfigWriter
15
16
  from simtools.utils import general, names
16
17
 
17
- __all__ = ["ArrayModel"]
18
-
19
18
 
20
19
  class ArrayModel:
21
20
  """
@@ -40,18 +39,21 @@ class ArrayModel:
40
39
  Dictionary with configuration for sim_telarray random instrument setup.
41
40
  simtel_path: str, Path, optional
42
41
  Path to the sim_telarray installation directory.
42
+ calibration_device_types: List[str], optional
43
+ List of calibration device types (e.g., 'flat_fielding') attached to each telescope.
43
44
  """
44
45
 
45
46
  def __init__(
46
47
  self,
47
- mongo_db_config: dict,
48
- model_version: str,
49
- label: str | None = None,
50
- site: str | None = None,
51
- layout_name: str | None = None,
52
- array_elements: str | Path | list[str] | None = None,
53
- sim_telarray_seeds: dict | None = None,
54
- simtel_path: str | Path | None = None,
48
+ mongo_db_config,
49
+ model_version,
50
+ label=None,
51
+ site=None,
52
+ layout_name=None,
53
+ array_elements=None,
54
+ sim_telarray_seeds=None,
55
+ simtel_path=None,
56
+ calibration_device_types=None,
55
57
  ):
56
58
  """Initialize ArrayModel."""
57
59
  self._logger = logging.getLogger(__name__)
@@ -69,8 +71,8 @@ class ArrayModel:
69
71
  self.io_handler = io_handler.IOHandler()
70
72
  self.db = db_handler.DatabaseHandler(mongo_db_config=mongo_db_config)
71
73
 
72
- self.array_elements, self.site_model, self.telescope_model = self._initialize(
73
- site, array_elements
74
+ self.array_elements, self.site_model, self.telescope_models, self.calibration_models = (
75
+ self._initialize(site, array_elements, calibration_device_types)
74
76
  )
75
77
 
76
78
  self._telescope_model_files_exported = False
@@ -78,7 +80,7 @@ class ArrayModel:
78
80
  self.sim_telarray_seeds = sim_telarray_seeds
79
81
  self.simtel_path = simtel_path
80
82
 
81
- def _initialize(self, site: str, array_elements_config: str | Path | list[str]):
83
+ def _initialize(self, site, array_elements_config, calibration_device_types):
82
84
  """
83
85
  Initialize ArrayModel taking different configuration options into account.
84
86
 
@@ -88,6 +90,8 @@ class ArrayModel:
88
90
  Site name.
89
91
  array_elements_config: Union[str, Path, List[str]]
90
92
  Array element definitions.
93
+ calibration_device_types: str
94
+ Calibration device types.
91
95
 
92
96
  Returns
93
97
  -------
@@ -106,7 +110,6 @@ class ArrayModel:
106
110
  label=self.label,
107
111
  )
108
112
 
109
- array_elements = {}
110
113
  # Case 1: array_elements is a file name
111
114
  if isinstance(array_elements_config, str | Path):
112
115
  array_elements = self._load_array_element_positions_from_file(
@@ -120,16 +123,20 @@ class ArrayModel:
120
123
  array_elements = self._get_array_elements_from_list(
121
124
  site_model.get_array_elements_for_layout(self.layout_name)
122
125
  )
123
- if not array_elements:
126
+ else:
124
127
  raise ValueError(
125
128
  "No array elements found. "
126
129
  "Possibly missing valid layout name or missing telescope list."
127
130
  )
128
- telescope_model = self._build_telescope_models(site_model, array_elements)
129
- return array_elements, site_model, telescope_model
131
+
132
+ telescope_models, calibration_models = self._build_telescope_models(
133
+ site_model, array_elements, calibration_device_types
134
+ )
135
+
136
+ return array_elements, site_model, telescope_models, calibration_models
130
137
 
131
138
  @property
132
- def config_file_path(self) -> Path:
139
+ def config_file_path(self):
133
140
  """
134
141
  Return the path of the array config file for sim_telarray.
135
142
 
@@ -149,7 +156,7 @@ class ArrayModel:
149
156
  return self._config_file_path
150
157
 
151
158
  @property
152
- def number_of_telescopes(self) -> int:
159
+ def number_of_telescopes(self):
153
160
  """
154
161
  Return the number of telescopes.
155
162
 
@@ -158,7 +165,7 @@ class ArrayModel:
158
165
  int
159
166
  Number of telescopes.
160
167
  """
161
- return len(self.telescope_model)
168
+ return len(self.telescope_models)
162
169
 
163
170
  @property
164
171
  def site(self) -> str:
@@ -200,12 +207,16 @@ class ArrayModel:
200
207
  )
201
208
  self._model_version = model_version
202
209
 
203
- def _build_telescope_models(self, site_model: SiteModel, array_elements: dict) -> dict:
210
+ def _build_telescope_models(self, site_model, array_elements, calibration_device_types):
204
211
  """
205
- Build the the telescope models for all telescopes of this array.
212
+ Build telescope models for all telescopes of this array.
206
213
 
207
- Includes reading of telescope model parameters from the DB.
208
- The array is defined in the telescopes dictionary. Array element positions
214
+ Adds calibration device models, if requested through the calibration_device_types argument.
215
+ Calibration device models are stored in a dictionary with the telescope name as key (to
216
+ identify the calibration device model on a given telescope).
217
+
218
+ Includes reading of telescope model parameters from the database.
219
+ The array is defined in the array_elements dictionary. Array element positions
209
220
  are read from the database if no values are given in this dictionary.
210
221
 
211
222
  Parameters
@@ -214,40 +225,78 @@ class ArrayModel:
214
225
  Site model.
215
226
  array_elements: dict
216
227
  Dict with array elements.
228
+ calibration_device_types: List[str]
229
+ List of calibration device types (e.g., 'flat_fielding')
230
+
231
+ Returns
232
+ -------
233
+ dict, dict
234
+ Dictionaries with telescope and calibration models.
235
+ """
236
+ telescope_models, calibration_models = {}, {}
237
+
238
+ for element_name in array_elements:
239
+ if names.get_collection_name_from_array_element_name(element_name) != "telescopes":
240
+ continue
241
+
242
+ telescope_models[element_name] = TelescopeModel(
243
+ site=site_model.site,
244
+ telescope_name=element_name,
245
+ model_version=self.model_version,
246
+ mongo_db_config=self.mongo_db_config,
247
+ label=self.label,
248
+ )
249
+ calibration_models[element_name] = self._build_calibration_models(
250
+ telescope_models[element_name],
251
+ site_model,
252
+ calibration_device_types,
253
+ )
254
+
255
+ return telescope_models, calibration_models
256
+
257
+ def _build_calibration_models(self, telescope_model, site_model, calibration_device_types):
258
+ """
259
+ Build calibration device models for all telescopes in the array.
260
+
261
+ A telescope can have multiple calibration devices of different types.
217
262
 
218
263
  Returns
219
264
  -------
220
265
  dict
221
- Dictionary with telescope models.
222
- """
223
- telescope_model = {}
224
- for element_name, _ in array_elements.items():
225
- collection = names.get_collection_name_from_array_element_name(element_name)
226
- if collection == "telescopes":
227
- telescope_model[element_name] = TelescopeModel(
228
- site=site_model.site,
229
- telescope_name=element_name,
230
- model_version=self.model_version,
231
- mongo_db_config=self.mongo_db_config,
232
- label=self.label,
233
- )
234
- return telescope_model
266
+ Dict with calibration device models.
267
+ """
268
+ calibration_models = {}
269
+ for calibration_device_type in calibration_device_types or []:
270
+ device_name = telescope_model.get_calibration_device_name(calibration_device_type)
271
+ if device_name is None:
272
+ continue
273
+
274
+ calibration_models[device_name] = CalibrationModel(
275
+ site=site_model.site,
276
+ calibration_device_model_name=device_name,
277
+ mongo_db_config=self.mongo_db_config,
278
+ model_version=self.model_version,
279
+ label=self.label,
280
+ )
281
+ return calibration_models
235
282
 
236
283
  def print_telescope_list(self):
237
284
  """Print list of telescopes."""
238
- for tel_name, data in self.telescope_model.items():
285
+ for tel_name, data in self.telescope_models.items():
239
286
  print(f"Name: {tel_name}\t Model: {data.name}")
240
287
 
241
288
  def export_simtel_telescope_config_files(self):
242
289
  """Export sim_telarray configuration files for all telescopes into the model directory."""
243
290
  exported_models = []
244
- for _, tel_model in self.telescope_model.items():
291
+ for tel_model in self.telescope_models.values():
245
292
  name = tel_model.name + (
246
293
  "_" + tel_model.extra_label if tel_model.extra_label != "" else ""
247
294
  )
248
295
  if name not in exported_models:
249
296
  self._logger.debug(f"Exporting configuration file for telescope {name}")
250
- tel_model.write_sim_telarray_config_file()
297
+ tel_model.write_sim_telarray_config_file(
298
+ additional_models=self.calibration_models.get(tel_model.name)
299
+ )
251
300
  exported_models.append(name)
252
301
  else:
253
302
  self._logger.debug(
@@ -270,7 +319,7 @@ class ArrayModel:
270
319
  )
271
320
  simtel_writer.write_array_config_file(
272
321
  config_file_path=self.config_file_path,
273
- telescope_model=self.telescope_model,
322
+ telescope_model=self.telescope_models,
274
323
  site_model=self.site_model,
275
324
  additional_metadata=self._get_additional_simtel_metadata(),
276
325
  )
@@ -298,7 +347,7 @@ class ArrayModel:
298
347
  """
299
348
  if self._config_file_directory is None:
300
349
  self._config_file_directory = self.io_handler.get_model_configuration_directory(
301
- self.label, self.model_version
350
+ model_version=self.model_version
302
351
  )
303
352
  return self._config_file_directory
304
353
 
@@ -316,8 +365,8 @@ class ArrayModel:
316
365
  self._logger.warning("No model files found to pack.")
317
366
  return None
318
367
 
319
- archive_name = self.get_config_directory() / "model_files.tar.gz"
320
- general.pack_tar_file(archive_name, model_files)
368
+ archive_name = self.get_config_directory() / f"model_files_{self.model_version}.tar.gz"
369
+ general.pack_tar_file(archive_name, model_files, sub_dir=f"model/{self.model_version}")
321
370
  self._logger.info(f"Packed model files into {archive_name}")
322
371
  return archive_name
323
372
 
@@ -459,7 +508,7 @@ class ArrayModel:
459
508
  table = QTable(meta={"array_name": self.layout_name, "site": self.site_model.site})
460
509
 
461
510
  name, pos_x, pos_y, pos_z, tel_r = [], [], [], [], []
462
- for tel_name, data in self.telescope_model.items():
511
+ for tel_name, data in self.telescope_models.items():
463
512
  name.append(tel_name)
464
513
  xyz = data.position(coordinate_system=coordinate_system)
465
514
  pos_x.append(xyz[0])
@@ -4,8 +4,6 @@ import logging
4
4
 
5
5
  from simtools.model.model_parameter import ModelParameter
6
6
 
7
- __all__ = ["CalibrationModel"]
8
-
9
7
 
10
8
  class CalibrationModel(ModelParameter):
11
9
  """
simtools/model/camera.py CHANGED
@@ -8,8 +8,6 @@ import numpy as np
8
8
 
9
9
  from simtools.utils.geometry import rotate
10
10
 
11
- __all__ = ["Camera"]
12
-
13
11
 
14
12
  class Camera:
15
13
  """
simtools/model/mirrors.py CHANGED
@@ -8,8 +8,6 @@ import astropy.units as u
8
8
  import numpy as np
9
9
  from astropy.table import Table
10
10
 
11
- __all__ = ["InvalidMirrorListFileError", "Mirrors"]
12
-
13
11
 
14
12
  class InvalidMirrorListFileError(Exception):
15
13
  """Exception for invalid mirror list file."""
@@ -13,8 +13,6 @@ from simtools.io import ascii_handler, io_handler
13
13
  from simtools.simtel.simtel_config_writer import SimtelConfigWriter
14
14
  from simtools.utils import names
15
15
 
16
- __all__ = ["InvalidModelParameterError", "ModelParameter"]
17
-
18
16
 
19
17
  class InvalidModelParameterError(Exception):
20
18
  """Exception for invalid model parameter."""
@@ -198,6 +196,31 @@ class ModelParameter:
198
196
 
199
197
  return _parameter
200
198
 
199
+ def _create_quantity_for_value(self, value, unit):
200
+ """
201
+ Create an astropy quantity for a single value and unit.
202
+
203
+ Parameters
204
+ ----------
205
+ value: numeric or str
206
+ The value to create a quantity for.
207
+ unit: str or None
208
+ The unit string or None.
209
+
210
+ Returns
211
+ -------
212
+ astropy.Quantity or original value
213
+ Astropy quantity for numeric values with units,
214
+ original value for non-numeric values.
215
+ """
216
+ if not isinstance(value, int | float):
217
+ return value
218
+
219
+ if unit is None or unit == "null":
220
+ return value * u.dimensionless_unscaled
221
+
222
+ return value * u.Unit(unit)
223
+
201
224
  def get_parameter_value_with_unit(self, par_name):
202
225
  """
203
226
  Get the value of an existing parameter of the model as an Astropy Quantity with its unit.
@@ -226,15 +249,16 @@ class ModelParameter:
226
249
  if (isinstance(_value, (int | float))) or (len(_value) > len(_unit)):
227
250
  return _value * u.Unit(_unit[0])
228
251
 
229
- # entries with 'null' units should be returned as dimensionless
230
- _astropy_units = [
231
- u.Unit(item) if item != "null" else u.dimensionless_unscaled for item in _unit
252
+ # Create list of quantities for multiple values with different units
253
+ return [
254
+ self._create_quantity_for_value(_value[i], _unit[i] if i < len(_unit) else None)
255
+ for i in range(len(_value))
232
256
  ]
233
257
 
234
- return [_value[i] * _astropy_units[i] for i in range(len(_value))]
235
-
236
258
  except (KeyError, TypeError, AttributeError) as exc:
237
- self._logger.debug(f"{exc} encountered, returning only value without units.")
259
+ self._logger.debug(
260
+ f"{exc} encountered for parameter {par_name}, returning only value without units."
261
+ )
238
262
  return _value # if unit is NoneType
239
263
 
240
264
  def get_parameter_type(self, par_name):
@@ -308,7 +332,7 @@ class ModelParameter:
308
332
  return
309
333
 
310
334
  self._config_file_directory = self.io_handler.get_model_configuration_directory(
311
- label=self.label, model_version=self.model_version
335
+ model_version=self.model_version
312
336
  )
313
337
 
314
338
  # Setting file name and the location
@@ -495,23 +519,19 @@ class ModelParameter:
495
519
  )
496
520
  self._is_exported_model_files_up_to_date = True
497
521
 
498
- def write_sim_telarray_config_file(self, additional_model=None):
522
+ def write_sim_telarray_config_file(self, additional_models=None):
499
523
  """
500
524
  Write the sim_telarray configuration file.
501
525
 
502
526
  Parameters
503
527
  ----------
504
- additional_model: TelescopeModel or SiteModel
528
+ additional_models: TelescopeModel or SiteModel
505
529
  Model object for additional parameter to be written to the config file.
506
530
  """
507
531
  self.parameters.update(self._simulation_config_parameters.get("sim_telarray", {}))
508
532
  self.export_model_files(update_if_necessary=True)
509
533
 
510
- if additional_model:
511
- self.parameters.update(additional_model.parameters)
512
- additional_model.export_model_files(
513
- self.config_file_directory, update_if_necessary=True
514
- )
534
+ self._add_additional_models(additional_models)
515
535
 
516
536
  self._load_simtel_config_writer()
517
537
  self.simtel_config_writer.write_telescope_config_file(
@@ -519,6 +539,19 @@ class ModelParameter:
519
539
  parameters=self.parameters,
520
540
  )
521
541
 
542
+ def _add_additional_models(self, additional_models):
543
+ """Add additional models to the current model parameters."""
544
+ if additional_models is None:
545
+ return
546
+
547
+ if isinstance(additional_models, dict):
548
+ for additional_model in additional_models.values():
549
+ self._add_additional_models(additional_model)
550
+ return
551
+
552
+ self.parameters.update(additional_models.parameters)
553
+ additional_models.export_model_files(self.config_file_directory, update_if_necessary=True)
554
+
522
555
  @property
523
556
  def config_file_directory(self):
524
557
  """Directory for configuration files. Configure if not yet set."""
@@ -539,6 +572,7 @@ class ModelParameter:
539
572
  self.simtel_config_writer = SimtelConfigWriter(
540
573
  site=self.site,
541
574
  telescope_model_name=self.name,
575
+ telescope_design_model=self.design_model,
542
576
  model_version=self.model_version,
543
577
  label=self.label,
544
578
  )