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
@@ -21,9 +21,11 @@ from simtools.data_model import model_data_writer as writer
21
21
  from simtools.ray_tracing.ray_tracing import RayTracing
22
22
  from simtools.utils import general as gen
23
23
  from simtools.visualization import plot_psf
24
+ from simtools.visualization.plot_psf import DEFAULT_FRACTION, get_psf_diameter_label
24
25
 
25
26
  logger = logging.getLogger(__name__)
26
27
 
28
+
27
29
  # Constants
28
30
  RADIUS = "Radius"
29
31
  CUMULATIVE_PSF = "Cumulative PSF"
@@ -105,7 +107,8 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars):
105
107
  ray.simulate(test=args_dict.get("test", False), force=True)
106
108
  ray.analyze(force=True, use_rx=False)
107
109
  im = ray.images()[0]
108
- return im.get_psf(), im
110
+ fraction = args_dict.get("fraction", DEFAULT_FRACTION)
111
+ return im.get_psf(fraction=fraction), im
109
112
 
110
113
 
111
114
  def run_psf_simulation(
@@ -146,12 +149,12 @@ def run_psf_simulation(
146
149
  Returns
147
150
  -------
148
151
  tuple of (float, float, float or None, array)
149
- - d80: D80 diameter of the simulated PSF in cm
152
+ - psf_diameter: PSF containment diameter of the simulated PSF in cm
150
153
  - metric: RMSD or KS statistic value
151
154
  - p_value: p-value from KS test (None if using RMSD)
152
155
  - simulated_data: Structured array with simulated cumulative PSF data
153
156
  """
154
- d80, im = _run_ray_tracing_simulation(tel_model, site, args_dict, pars)
157
+ psf_diameter, im = _run_ray_tracing_simulation(tel_model, site, args_dict, pars)
155
158
 
156
159
  if radius is None:
157
160
  raise ValueError("Radius data is not available.")
@@ -175,16 +178,17 @@ def run_psf_simulation(
175
178
  plot_psf.create_psf_parameter_plot(
176
179
  data_to_plot,
177
180
  pars,
178
- d80,
181
+ psf_diameter,
179
182
  metric,
180
183
  is_best,
181
184
  pdf_pages,
185
+ fraction=args_dict.get("fraction", DEFAULT_FRACTION),
182
186
  p_value=p_value,
183
187
  use_ks_statistic=use_ks_statistic,
184
188
  )
185
189
  del data_to_plot["simulated"]
186
190
 
187
- return d80, metric, p_value, simulated_data
191
+ return psf_diameter, metric, p_value, simulated_data
188
192
 
189
193
 
190
194
  def load_and_process_data(args_dict):
@@ -228,23 +232,27 @@ def load_and_process_data(args_dict):
228
232
  return OrderedDict([("measured", data)]), data[RADIUS]
229
233
 
230
234
 
231
- def write_tested_parameters_to_file(results, best_pars, best_d80, output_dir, tel_model):
235
+ def write_tested_parameters_to_file(
236
+ results, best_pars, best_psf_diameter, output_dir, tel_model, fraction=DEFAULT_FRACTION
237
+ ):
232
238
  """
233
239
  Write optimization results and tested parameters to a log file.
234
240
 
235
241
  Parameters
236
242
  ----------
237
243
  results : list
238
- List of tuples containing (parameters, ks_statistic, p_value, d80, simulated_data)
244
+ List of tuples containing (parameters, ks_statistic, p_value, psf_diameter, simulated_data)
239
245
  for each tested parameter set.
240
246
  best_pars : dict
241
247
  Dictionary containing the best parameter values found.
242
- best_d80 : float
243
- D80 diameter in cm for the best parameter set.
248
+ best_psf_diameter : float
249
+ PSF containment diameter in cm for the best parameter set.
244
250
  output_dir : Path
245
251
  Directory where the log file will be written.
246
252
  tel_model : TelescopeModel
247
253
  Telescope model object for naming the output file.
254
+ fraction : float, optional
255
+ PSF containment fraction for labeling (default: 0.8).
248
256
 
249
257
  Returns
250
258
  -------
@@ -252,6 +260,8 @@ def write_tested_parameters_to_file(results, best_pars, best_d80, output_dir, te
252
260
  Path to the created log file.
253
261
  """
254
262
  param_file = output_dir.joinpath(f"psf_optimization_{tel_model.name}.log")
263
+ psf_label = get_psf_diameter_label(fraction)
264
+
255
265
  with open(param_file, "w", encoding="utf-8") as f:
256
266
  header = _create_log_header_and_format_value(
257
267
  "PSF Parameter Optimization Log",
@@ -261,11 +271,11 @@ def write_tested_parameters_to_file(results, best_pars, best_d80, output_dir, te
261
271
  f.write(header)
262
272
 
263
273
  f.write("PARAMETER TESTING RESULTS:\n")
264
- for i, (pars, ks_statistic, p_value, d80, _) in enumerate(results):
274
+ for i, (pars, ks_statistic, p_value, psf_diameter, _) in enumerate(results):
265
275
  status = "BEST" if pars is best_pars else "TESTED"
266
276
  f.write(
267
277
  f"[{status}] Set {i + 1:03d}: KS_stat={ks_statistic:.5f}, "
268
- f"p_value={p_value:.5f}, D80={d80:.5f} cm\n"
278
+ f"p_value={p_value:.5f}, {psf_label}={psf_diameter:.5f} cm\n"
269
279
  )
270
280
  for par, value in pars.items():
271
281
  f.write(f" {par}: {value}\n")
@@ -273,7 +283,7 @@ def write_tested_parameters_to_file(results, best_pars, best_d80, output_dir, te
273
283
 
274
284
  f.write("OPTIMIZATION SUMMARY:\n")
275
285
  f.write(f"Best KS statistic: {min(result[1] for result in results):.5f}\n")
276
- f.write(f"Best D80: {best_d80:.5f} cm\n")
286
+ f.write(f"Best {psf_label}: {best_psf_diameter:.5f} cm\n")
277
287
  f.write("\nOPTIMIZED PARAMETERS:\n")
278
288
  for par, value in best_pars.items():
279
289
  f.write(f"{par}: {value}\n")
@@ -339,7 +349,6 @@ def export_psf_parameters(best_pars, telescope, parameter_version, output_dir):
339
349
  parameter_version=parameter_version,
340
350
  output_file=f"{parameter_name}-{parameter_version}.json",
341
351
  output_path=parameter_output_path,
342
- use_plain_output_path=True,
343
352
  )
344
353
  logger.info(f"simulation model parameter files exported to {output_dir}")
345
354
 
@@ -574,7 +583,7 @@ def _perform_gradient_step_with_retries(
574
583
  -------
575
584
  tuple of (dict, float, float, float or None, array, bool, float)
576
585
  - new_params: Updated parameter dictionary if step accepted, None if rejected
577
- - new_d80: D80 diameter in cm for new parameters, None if step rejected
586
+ - new_psf_diameter: PSF containment diameter in cm for new parameters, None if step rejected
578
587
  - new_metric: New optimization metric value, None if step rejected
579
588
  - new_p_value: p-value from KS test if applicable, None otherwise
580
589
  - new_simulated_data: Simulated PSF data array, None if step rejected
@@ -598,7 +607,7 @@ def _perform_gradient_step_with_retries(
598
607
  )
599
608
  new_params = apply_gradient_step(current_params, gradients, current_lr)
600
609
 
601
- new_d80, new_metric, new_p_value, new_simulated_data = run_psf_simulation(
610
+ new_psf_diameter, new_metric, new_p_value, new_simulated_data = run_psf_simulation(
602
611
  tel_model,
603
612
  site_model,
604
613
  args_dict,
@@ -613,7 +622,7 @@ def _perform_gradient_step_with_retries(
613
622
  if new_metric < current_metric:
614
623
  return (
615
624
  new_params,
616
- new_d80,
625
+ new_psf_diameter,
617
626
  new_metric,
618
627
  new_p_value,
619
628
  new_simulated_data,
@@ -642,7 +651,7 @@ def _create_step_plot(
642
651
  args_dict,
643
652
  data_to_plot,
644
653
  current_params,
645
- new_d80,
654
+ new_psf_diameter,
646
655
  new_metric,
647
656
  new_p_value,
648
657
  new_simulated_data,
@@ -655,10 +664,11 @@ def _create_step_plot(
655
664
  plot_psf.create_psf_parameter_plot(
656
665
  data_to_plot,
657
666
  current_params,
658
- new_d80,
667
+ new_psf_diameter,
659
668
  new_metric,
660
669
  False,
661
670
  pdf_pages,
671
+ fraction=args_dict.get("fraction", DEFAULT_FRACTION),
662
672
  p_value=new_p_value,
663
673
  use_ks_statistic=False,
664
674
  )
@@ -666,7 +676,14 @@ def _create_step_plot(
666
676
 
667
677
 
668
678
  def _create_final_plot(
669
- pdf_pages, tel_model, site_model, args_dict, best_params, data_to_plot, radius, best_d80
679
+ pdf_pages,
680
+ tel_model,
681
+ site_model,
682
+ args_dict,
683
+ best_params,
684
+ data_to_plot,
685
+ radius,
686
+ best_psf_diameter,
670
687
  ):
671
688
  """Create final plot for best parameters."""
672
689
  if pdf_pages is None or best_params is None:
@@ -692,10 +709,11 @@ def _create_final_plot(
692
709
  plot_psf.create_psf_parameter_plot(
693
710
  data_to_plot,
694
711
  best_params,
695
- best_d80,
712
+ best_psf_diameter,
696
713
  best_rmsd,
697
714
  True,
698
715
  pdf_pages,
716
+ fraction=args_dict.get("fraction", DEFAULT_FRACTION),
699
717
  p_value=best_p_value,
700
718
  use_ks_statistic=False,
701
719
  second_metric=best_ks_stat,
@@ -741,8 +759,9 @@ def run_gradient_descent_optimization(
741
759
  -------
742
760
  tuple of (dict, float, list)
743
761
  - best_params: Dictionary of optimized parameter values
744
- - best_d80: D80 diameter in cm for the best parameters
745
- - results: List of (params, metric, p_value, d80, simulated_data) for each iteration
762
+ - best_psf_diameter: PSF containment diameter in cm for the best parameters
763
+ - results: List of (params, metric, p_value, psf_diameter, simulated_data)
764
+ for each iteration
746
765
 
747
766
  Returns None values if optimization fails or no measurement data is provided.
748
767
  """
@@ -755,7 +774,7 @@ def run_gradient_descent_optimization(
755
774
  results = []
756
775
 
757
776
  # Evaluate initial parameters
758
- current_d80, current_metric, current_p_value, simulated_data = run_psf_simulation(
777
+ current_psf_diameter, current_metric, current_p_value, simulated_data = run_psf_simulation(
759
778
  tel_model,
760
779
  site_model,
761
780
  args_dict,
@@ -768,11 +787,21 @@ def run_gradient_descent_optimization(
768
787
  )
769
788
 
770
789
  results.append(
771
- (current_params.copy(), current_metric, current_p_value, current_d80, simulated_data)
790
+ (
791
+ current_params.copy(),
792
+ current_metric,
793
+ current_p_value,
794
+ current_psf_diameter,
795
+ simulated_data,
796
+ )
797
+ )
798
+ best_metric, best_params, best_psf_diameter = (
799
+ current_metric,
800
+ current_params.copy(),
801
+ current_psf_diameter,
772
802
  )
773
- best_metric, best_params, best_d80 = current_metric, current_params.copy(), current_d80
774
803
 
775
- logger.info(f"Initial RMSD: {current_metric:.6f}, D80: {current_d80:.6f} cm")
804
+ logger.info(f"Initial RMSD: {current_metric:.6f}, PSF diameter: {current_psf_diameter:.6f} cm")
776
805
 
777
806
  iteration = 0
778
807
  max_total_iterations = 100
@@ -800,7 +829,7 @@ def run_gradient_descent_optimization(
800
829
  )
801
830
  (
802
831
  new_params,
803
- new_d80,
832
+ new_psf_diameter,
804
833
  new_metric,
805
834
  new_p_value,
806
835
  new_simulated_data,
@@ -814,20 +843,28 @@ def run_gradient_descent_optimization(
814
843
  continue
815
844
 
816
845
  # Step was accepted - update state
817
- current_params, current_metric, current_d80 = new_params, new_metric, new_d80
846
+ current_params, current_metric, current_psf_diameter = (
847
+ new_params,
848
+ new_metric,
849
+ new_psf_diameter,
850
+ )
818
851
  results.append(
819
- (current_params.copy(), current_metric, None, current_d80, new_simulated_data)
852
+ (current_params.copy(), current_metric, None, current_psf_diameter, new_simulated_data)
820
853
  )
821
854
 
822
855
  if current_metric < best_metric:
823
- best_metric, best_params, best_d80 = current_metric, current_params.copy(), current_d80
856
+ best_metric, best_params, best_psf_diameter = (
857
+ current_metric,
858
+ current_params.copy(),
859
+ current_psf_diameter,
860
+ )
824
861
 
825
862
  _create_step_plot(
826
863
  pdf_pages,
827
864
  args_dict,
828
865
  data_to_plot,
829
866
  current_params,
830
- new_d80,
867
+ new_psf_diameter,
831
868
  new_metric,
832
869
  new_p_value,
833
870
  new_simulated_data,
@@ -835,9 +872,16 @@ def run_gradient_descent_optimization(
835
872
  logger.info(f" Accepted step: improved to {new_metric:.6f}")
836
873
 
837
874
  _create_final_plot(
838
- pdf_pages, tel_model, site_model, args_dict, best_params, data_to_plot, radius, best_d80
875
+ pdf_pages,
876
+ tel_model,
877
+ site_model,
878
+ args_dict,
879
+ best_params,
880
+ data_to_plot,
881
+ radius,
882
+ best_psf_diameter,
839
883
  )
840
- return best_params, best_d80, results
884
+ return best_params, best_psf_diameter, results
841
885
 
842
886
 
843
887
  def _write_log_interpretation(f, use_ks_statistic):
@@ -857,38 +901,66 @@ def _write_log_interpretation(f, use_ks_statistic):
857
901
 
858
902
 
859
903
  def _write_iteration_entry(
860
- f, iteration, pars, metric, p_value, d80, use_ks_statistic, metric_name, total_iterations
904
+ f,
905
+ iteration,
906
+ pars,
907
+ metric,
908
+ p_value,
909
+ psf_diameter,
910
+ use_ks_statistic,
911
+ metric_name,
912
+ total_iterations,
913
+ fraction=DEFAULT_FRACTION,
861
914
  ):
862
915
  """Write a single iteration entry."""
863
916
  status = "FINAL" if iteration == total_iterations - 1 else f"ITER-{iteration:02d}"
864
917
 
865
918
  if use_ks_statistic and p_value is not None:
866
919
  significance = plot_psf.get_significance_label(p_value)
920
+ label = get_psf_diameter_label(fraction)
867
921
  f.write(
868
922
  f"[{status}] Iteration {iteration}: KS_stat={metric:.6f}, "
869
- f"p_value={p_value:.6f} ({significance}), D80={d80:.6f} cm\n"
923
+ f"p_value={p_value:.6f} ({significance}), {label}={psf_diameter:.6f} cm\n"
870
924
  )
871
925
  else:
872
- f.write(f"[{status}] Iteration {iteration}: {metric_name}={metric:.6f}, D80={d80:.6f} cm\n")
926
+ label = get_psf_diameter_label(fraction)
927
+ f.write(
928
+ f"[{status}] Iteration {iteration}: {metric_name}={metric:.6f}, "
929
+ f"{label}={psf_diameter:.6f} cm\n"
930
+ )
873
931
 
874
932
  for par, value in pars.items():
875
933
  f.write(f" {par}: {_create_log_header_and_format_value(None, None, None, value)}\n")
876
934
  f.write("\n")
877
935
 
878
936
 
879
- def _write_optimization_summary(f, gd_results, best_pars, best_d80, metric_name):
937
+ def _write_optimization_summary(
938
+ f, gd_results, best_pars, best_psf_diameter, metric_name, fraction=DEFAULT_FRACTION
939
+ ):
880
940
  """Write optimization summary section."""
881
941
  f.write("OPTIMIZATION SUMMARY:\n")
882
942
  best_metric_from_results = min(metric for _, metric, _, _, _ in gd_results)
883
943
  f.write(f"Best {metric_name.lower()}: {best_metric_from_results:.6f}\n")
884
- f.write(f"Best D80: {best_d80:.6f} cm\n" if best_d80 is not None else "Best D80: N/A\n")
944
+
945
+ label = get_psf_diameter_label(fraction)
946
+ f.write(
947
+ f"Best {label}: {best_psf_diameter:.6f} cm\n"
948
+ if best_psf_diameter is not None
949
+ else f"Best {label}: N/A\n"
950
+ )
885
951
  f.write(f"Total iterations: {len(gd_results)}\n\nFINAL OPTIMIZED PARAMETERS:\n")
886
952
  for par, value in best_pars.items():
887
953
  f.write(f"{par}: {_create_log_header_and_format_value(None, None, None, value)}\n")
888
954
 
889
955
 
890
956
  def write_gradient_descent_log(
891
- gd_results, best_pars, best_d80, output_dir, tel_model, use_ks_statistic=False
957
+ gd_results,
958
+ best_pars,
959
+ best_psf_diameter,
960
+ output_dir,
961
+ tel_model,
962
+ use_ks_statistic=False,
963
+ fraction=DEFAULT_FRACTION,
892
964
  ):
893
965
  """
894
966
  Write gradient descent optimization progression to a log file.
@@ -896,18 +968,20 @@ def write_gradient_descent_log(
896
968
  Parameters
897
969
  ----------
898
970
  gd_results : list
899
- List of tuples containing (params, metric, p_value, d80, simulated_data)
971
+ List of tuples containing (params, metric, p_value, psf_diameter, simulated_data)
900
972
  for each optimization iteration.
901
973
  best_pars : dict
902
974
  Dictionary containing the best parameter values found.
903
- best_d80 : float
904
- D80 diameter in cm for the best parameter set.
975
+ best_psf_diameter : float
976
+ PSF containment diameter in cm for the best parameter set.
905
977
  output_dir : Path
906
978
  Directory where the log file will be written.
907
979
  tel_model : TelescopeModel
908
980
  Telescope model object for naming the output file.
909
981
  use_ks_statistic : bool, optional
910
982
  If True, log KS statistic values; if False, log RMSD values (default: False).
983
+ fraction : float, optional
984
+ PSF containment fraction for labeling (default: 0.8).
911
985
 
912
986
  Returns
913
987
  -------
@@ -932,20 +1006,23 @@ def write_gradient_descent_log(
932
1006
  )
933
1007
  _write_log_interpretation(f, use_ks_statistic)
934
1008
 
935
- for iteration, (pars, metric, p_value, d80, _) in enumerate(gd_results):
1009
+ for iteration, (pars, metric, p_value, psf_diameter, _) in enumerate(gd_results):
936
1010
  _write_iteration_entry(
937
1011
  f,
938
1012
  iteration,
939
1013
  pars,
940
1014
  metric,
941
1015
  p_value,
942
- d80,
1016
+ psf_diameter,
943
1017
  use_ks_statistic,
944
1018
  metric_name,
945
1019
  len(gd_results),
1020
+ fraction,
946
1021
  )
947
1022
 
948
- _write_optimization_summary(f, gd_results, best_pars, best_d80, metric_name)
1023
+ _write_optimization_summary(
1024
+ f, gd_results, best_pars, best_psf_diameter, metric_name, fraction
1025
+ )
949
1026
 
950
1027
  return param_file
951
1028
 
@@ -985,9 +1062,9 @@ def analyze_monte_carlo_error(
985
1062
  - mean_p_value: Mean p-value (None if using RMSD)
986
1063
  - std_p_value: Standard deviation of p-values (None if using RMSD)
987
1064
  - p_values: List of all p-values from simulations
988
- - mean_d80: Mean D80 diameter in cm
989
- - std_d80: Standard deviation of D80 values
990
- - d80_values: List of all D80 values from simulations
1065
+ - mean_psf_diameter: Mean PSF containment diameter in cm
1066
+ - std_psf_diameter: Standard deviation of PSF diameter values
1067
+ - psf_diameter_values: List of all PSF diameter values from simulations
991
1068
  """
992
1069
  if data_to_plot is None or radius is None:
993
1070
  logger.error("No PSF measurement data provided. Cannot analyze Monte Carlo error.")
@@ -998,11 +1075,11 @@ def analyze_monte_carlo_error(
998
1075
  logger.info(f" {param_name}: {param_values}")
999
1076
 
1000
1077
  use_ks_statistic = args_dict.get("ks_statistic", False)
1001
- metric_values, p_values, d80_values = [], [], []
1078
+ metric_values, p_values, psf_diameter_values = [], [], []
1002
1079
 
1003
1080
  for i in range(n_simulations):
1004
1081
  try:
1005
- d80, metric, p_value, _ = run_psf_simulation(
1082
+ psf_diameter, metric, p_value, _ = run_psf_simulation(
1006
1083
  tel_model,
1007
1084
  site_model,
1008
1085
  args_dict,
@@ -1012,7 +1089,7 @@ def analyze_monte_carlo_error(
1012
1089
  use_ks_statistic=use_ks_statistic,
1013
1090
  )
1014
1091
  metric_values.append(metric)
1015
- d80_values.append(d80)
1092
+ psf_diameter_values.append(psf_diameter)
1016
1093
  p_values.append(p_value)
1017
1094
  except (ValueError, RuntimeError) as e:
1018
1095
  logger.warning(f"WARNING: Simulation {i + 1} failed: {e}")
@@ -1022,7 +1099,10 @@ def analyze_monte_carlo_error(
1022
1099
  return None, None, [], None, None, []
1023
1100
 
1024
1101
  mean_metric, std_metric = np.mean(metric_values), np.std(metric_values, ddof=1)
1025
- mean_d80, std_d80 = np.mean(d80_values), np.std(d80_values, ddof=1)
1102
+ mean_psf_diameter, std_psf_diameter = (
1103
+ np.mean(psf_diameter_values),
1104
+ np.std(psf_diameter_values, ddof=1),
1105
+ )
1026
1106
 
1027
1107
  if use_ks_statistic:
1028
1108
  valid_p_values = [p for p in p_values if p is not None]
@@ -1038,13 +1118,15 @@ def analyze_monte_carlo_error(
1038
1118
  mean_p_value,
1039
1119
  std_p_value,
1040
1120
  p_values,
1041
- mean_d80,
1042
- std_d80,
1043
- d80_values,
1121
+ mean_psf_diameter,
1122
+ std_psf_diameter,
1123
+ psf_diameter_values,
1044
1124
  )
1045
1125
 
1046
1126
 
1047
- def write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statistic=False):
1127
+ def write_monte_carlo_analysis(
1128
+ mc_results, output_dir, tel_model, use_ks_statistic=False, fraction=DEFAULT_FRACTION
1129
+ ):
1048
1130
  """
1049
1131
  Write Monte Carlo uncertainty analysis results to a log file.
1050
1132
 
@@ -1058,6 +1140,8 @@ def write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statist
1058
1140
  Telescope model object for naming the output file.
1059
1141
  use_ks_statistic : bool, optional
1060
1142
  If True, analyze KS statistic results; if False, analyze RMSD results (default: False).
1143
+ fraction : float, optional
1144
+ PSF containment fraction for labeling (default: 0.8).
1061
1145
 
1062
1146
  Returns
1063
1147
  -------
@@ -1071,15 +1155,17 @@ def write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statist
1071
1155
  mean_p_value,
1072
1156
  std_p_value,
1073
1157
  p_values,
1074
- mean_d80,
1075
- std_d80,
1076
- d80_values,
1158
+ mean_psf_diameter,
1159
+ std_psf_diameter,
1160
+ psf_diameter_values,
1077
1161
  ) = mc_results
1078
1162
 
1079
1163
  metric_name = "KS Statistic" if use_ks_statistic else "RMSD"
1080
1164
  file_suffix = "ks" if use_ks_statistic else "rmsd"
1081
1165
  mc_file = output_dir.joinpath(f"monte_carlo_{file_suffix}_analysis_{tel_model.name}.log")
1082
1166
 
1167
+ psf_label = get_psf_diameter_label(fraction)
1168
+
1083
1169
  with open(mc_file, "w", encoding="utf-8") as f:
1084
1170
  header = _create_log_header_and_format_value(
1085
1171
  f"Monte Carlo {metric_name} Error Analysis",
@@ -1124,15 +1210,17 @@ def write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statist
1124
1210
  )
1125
1211
 
1126
1212
  f.write(
1127
- f"D80 STATISTICS:\nMean D80: {mean_d80:.6f} cm\n"
1128
- f"Standard deviation: {std_d80:.6f} cm\n"
1129
- f"Minimum D80: {min(d80_values):.6f} cm\n"
1130
- f"Maximum D80: {max(d80_values):.6f} cm\n"
1131
- f"Relative error: {(std_d80 / mean_d80) * 100:.2f}%\n\n"
1213
+ f"{psf_label} STATISTICS:\nMean {psf_label}: {mean_psf_diameter:.6f} cm\n"
1214
+ f"Standard deviation: {std_psf_diameter:.6f} cm\n"
1215
+ f"Minimum {psf_label}: {min(psf_diameter_values):.6f} cm\n"
1216
+ f"Maximum {psf_label}: {max(psf_diameter_values):.6f} cm\n"
1217
+ f"Relative error: {(std_psf_diameter / mean_psf_diameter) * 100:.2f}%\n\n"
1132
1218
  )
1133
1219
 
1134
1220
  f.write("INDIVIDUAL SIMULATION RESULTS:\n")
1135
- for i, (metric_val, p_value, d80) in enumerate(zip(metric_values, p_values, d80_values)):
1221
+ for i, (metric_val, p_value, psf_diameter) in enumerate(
1222
+ zip(metric_values, p_values, psf_diameter_values)
1223
+ ):
1136
1224
  if use_ks_statistic and p_value is not None:
1137
1225
  if p_value > 0.05:
1138
1226
  significance = "GOOD"
@@ -1142,11 +1230,12 @@ def write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statist
1142
1230
  significance = "POOR"
1143
1231
  f.write(
1144
1232
  f"Simulation {i + 1:2d}: {metric_name}={metric_val:.6f}, "
1145
- f"p_value={p_value:.6f} ({significance}), D80={d80:.6f} cm\n"
1233
+ f"p_value={p_value:.6f} ({significance}), {psf_label}={psf_diameter:.6f} cm\n"
1146
1234
  )
1147
1235
  else:
1148
1236
  f.write(
1149
- f"Simulation {i + 1:2d}: {metric_name}={metric_val:.6f}, D80={d80:.6f} cm\n"
1237
+ f"Simulation {i + 1:2d}: {metric_name}={metric_val:.6f}, "
1238
+ f"{psf_label}={psf_diameter:.6f} cm\n"
1150
1239
  )
1151
1240
 
1152
1241
  return mc_file
@@ -1161,10 +1250,18 @@ def _handle_monte_carlo_analysis(
1161
1250
 
1162
1251
  mc_results = analyze_monte_carlo_error(tel_model, site_model, args_dict, data_to_plot, radius)
1163
1252
  if mc_results[0] is not None:
1164
- mc_file = write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statistic)
1253
+ mc_file = write_monte_carlo_analysis(
1254
+ mc_results,
1255
+ output_dir,
1256
+ tel_model,
1257
+ use_ks_statistic,
1258
+ args_dict.get("fraction", DEFAULT_FRACTION),
1259
+ )
1165
1260
  logger.info(f"Monte Carlo analysis results written to {mc_file}")
1166
1261
  mc_plot_file = output_dir.joinpath(f"monte_carlo_uncertainty_{tel_model.name}.pdf")
1167
- plot_psf.create_monte_carlo_uncertainty_plot(mc_results, mc_plot_file, use_ks_statistic)
1262
+ plot_psf.create_monte_carlo_uncertainty_plot(
1263
+ mc_results, mc_plot_file, args_dict.get("fraction", DEFAULT_FRACTION), use_ks_statistic
1264
+ )
1168
1265
  return True
1169
1266
 
1170
1267
 
@@ -1182,7 +1279,7 @@ def run_psf_optimization_workflow(tel_model, site_model, args_dict, output_dir):
1182
1279
  threshold = args_dict.get("rmsd_threshold")
1183
1280
  learning_rate = args_dict.get("learning_rate")
1184
1281
 
1185
- best_pars, best_d80, gd_results = run_gradient_descent_optimization(
1282
+ best_pars, best_psf_diameter, gd_results = run_gradient_descent_optimization(
1186
1283
  tel_model,
1187
1284
  site_model,
1188
1285
  args_dict,
@@ -1209,15 +1306,25 @@ def run_psf_optimization_workflow(tel_model, site_model, args_dict, output_dir):
1209
1306
  f"gradient_descent_convergence_{tel_model.name}.png"
1210
1307
  )
1211
1308
  plot_psf.create_gradient_descent_convergence_plot(
1212
- gd_results, threshold, convergence_plot_file, use_ks_statistic
1309
+ gd_results,
1310
+ threshold,
1311
+ convergence_plot_file,
1312
+ args_dict.get("fraction", DEFAULT_FRACTION),
1313
+ use_ks_statistic,
1213
1314
  )
1214
1315
 
1215
1316
  param_file = write_gradient_descent_log(
1216
- gd_results, best_pars, best_d80, output_dir, tel_model, use_ks_statistic
1317
+ gd_results,
1318
+ best_pars,
1319
+ best_psf_diameter,
1320
+ output_dir,
1321
+ tel_model,
1322
+ use_ks_statistic,
1323
+ args_dict.get("fraction", DEFAULT_FRACTION),
1217
1324
  )
1218
1325
  logger.info(f"\nGradient descent progression written to {param_file}")
1219
1326
 
1220
- plot_psf.create_d80_vs_offaxis_plot(tel_model, site_model, args_dict, best_pars, output_dir)
1327
+ plot_psf.create_psf_vs_offaxis_plot(tel_model, site_model, args_dict, best_pars, output_dir)
1221
1328
 
1222
1329
  if args_dict.get("write_psf_parameters", False):
1223
1330
  logger.info("Exporting best parameters as model files...")
@@ -20,8 +20,6 @@ from simtools.simtel.simulator_ray_tracing import SimulatorRayTracing
20
20
  from simtools.utils import names
21
21
  from simtools.visualization import visualize
22
22
 
23
- __all__ = ["RayTracing"]
24
-
25
23
  INVALID_KEY_TO_PLOT = "Invalid key to plot"
26
24
 
27
25
 
@@ -92,9 +90,7 @@ class RayTracing:
92
90
  self.use_random_focal_length = use_random_focal_length
93
91
  self.random_focal_length_seed = random_focal_length_seed
94
92
  self.mirrors = self._initialize_mirror_configuration(source_distance, mirror_numbers)
95
- self.output_directory = self._io_handler.get_output_directory(
96
- label=self.label, sub_dir="ray_tracing"
97
- )
93
+ self.output_directory = self._io_handler.get_output_directory()
98
94
  self.output_directory.joinpath("results").mkdir(parents=True, exist_ok=True)
99
95
  self._file_results = self.output_directory.joinpath("results").joinpath(
100
96
  self._generate_file_name(file_type="ray_tracing", suffix=".ecsv")