gammasimtools 0.6.1__py3-none-any.whl → 0.8.2__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 (355) hide show
  1. gammasimtools-0.8.2.dist-info/METADATA +173 -0
  2. gammasimtools-0.8.2.dist-info/RECORD +345 -0
  3. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.2.dist-info}/WHEEL +1 -1
  4. gammasimtools-0.8.2.dist-info/entry_points.txt +31 -0
  5. simtools/_dev_version/__init__.py +9 -0
  6. simtools/_version.py +2 -2
  7. simtools/applications/calculate_trigger_rate.py +210 -0
  8. simtools/applications/convert_all_model_parameters_from_simtel.py +372 -0
  9. simtools/applications/{print_array_elements.py → convert_geo_coordinates_of_array_elements.py} +58 -63
  10. simtools/applications/convert_model_parameter_from_simtel.py +119 -0
  11. simtools/applications/{add_file_to_db.py → db_add_file_to_db.py} +70 -60
  12. simtools/applications/db_add_model_parameters_from_repository_to_db.py +184 -0
  13. simtools/applications/db_add_value_from_json_to_db.py +105 -0
  14. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +180 -0
  15. simtools/applications/db_get_array_layouts_from_db.py +162 -0
  16. simtools/applications/{get_file_from_db.py → db_get_file_from_db.py} +30 -34
  17. simtools/applications/db_get_parameter_from_db.py +131 -0
  18. simtools/applications/db_inspect_databases.py +52 -0
  19. simtools/applications/derive_mirror_rnda.py +39 -255
  20. simtools/applications/derive_psf_parameters.py +441 -0
  21. simtools/applications/generate_array_config.py +82 -0
  22. simtools/applications/generate_corsika_histograms.py +52 -52
  23. simtools/applications/generate_default_metadata.py +5 -8
  24. simtools/applications/generate_regular_arrays.py +117 -0
  25. simtools/applications/generate_simtel_array_histograms.py +97 -56
  26. simtools/applications/plot_array_layout.py +345 -115
  27. simtools/applications/production_generate_simulation_config.py +158 -0
  28. simtools/applications/production_scale_events.py +168 -0
  29. simtools/applications/simulate_light_emission.py +478 -0
  30. simtools/applications/simulate_prod.py +97 -175
  31. simtools/applications/submit_data_from_external.py +9 -12
  32. simtools/applications/submit_model_parameter_from_external.py +122 -0
  33. simtools/applications/validate_camera_efficiency.py +35 -102
  34. simtools/applications/validate_camera_fov.py +20 -19
  35. simtools/applications/{compare_cumulative_psf.py → validate_cumulative_psf.py} +45 -44
  36. simtools/applications/validate_file_using_schema.py +111 -47
  37. simtools/applications/validate_optics.py +17 -22
  38. simtools/camera_efficiency.py +193 -202
  39. simtools/configuration/commandline_parser.py +384 -96
  40. simtools/configuration/configurator.py +55 -71
  41. simtools/constants.py +5 -5
  42. simtools/corsika/corsika_config.py +482 -342
  43. simtools/corsika/corsika_histograms.py +226 -204
  44. simtools/corsika/corsika_histograms_visualize.py +23 -24
  45. simtools/corsika/primary_particle.py +159 -0
  46. simtools/data_model/data_reader.py +25 -20
  47. simtools/data_model/format_checkers.py +52 -0
  48. simtools/data_model/metadata_collector.py +211 -185
  49. simtools/data_model/metadata_model.py +115 -37
  50. simtools/data_model/model_data_writer.py +335 -26
  51. simtools/data_model/validate_data.py +366 -154
  52. simtools/db/db_array_elements.py +130 -0
  53. simtools/db/db_from_repo_handler.py +106 -0
  54. simtools/db/db_handler.py +1246 -0
  55. simtools/io_operations/hdf5_handler.py +3 -1
  56. simtools/io_operations/io_handler.py +32 -57
  57. simtools/job_execution/job_manager.py +82 -69
  58. simtools/layout/array_layout.py +325 -537
  59. simtools/layout/geo_coordinates.py +8 -11
  60. simtools/layout/telescope_position.py +163 -86
  61. simtools/model/array_model.py +312 -259
  62. simtools/model/calibration_model.py +50 -0
  63. simtools/model/camera.py +277 -523
  64. simtools/model/mirrors.py +68 -49
  65. simtools/model/model_parameter.py +602 -0
  66. simtools/model/model_utils.py +11 -39
  67. simtools/model/site_model.py +161 -0
  68. simtools/model/telescope_model.py +143 -633
  69. simtools/production_configuration/calculate_statistical_errors_grid_point.py +454 -0
  70. simtools/production_configuration/event_scaler.py +146 -0
  71. simtools/production_configuration/generate_simulation_config.py +193 -0
  72. simtools/production_configuration/interpolation_handler.py +197 -0
  73. simtools/ray_tracing/__init__.py +0 -0
  74. simtools/ray_tracing/mirror_panel_psf.py +280 -0
  75. simtools/{psf_analysis.py → ray_tracing/psf_analysis.py} +133 -47
  76. simtools/ray_tracing/ray_tracing.py +646 -0
  77. simtools/runners/__init__.py +0 -0
  78. simtools/runners/corsika_runner.py +240 -0
  79. simtools/runners/corsika_simtel_runner.py +225 -0
  80. simtools/runners/runner_services.py +307 -0
  81. simtools/runners/simtel_runner.py +224 -0
  82. simtools/schemas/array_elements.yml +137 -0
  83. simtools/schemas/integration_tests_config.metaschema.yml +93 -0
  84. simtools/schemas/metadata.metaschema.yml +6 -0
  85. simtools/schemas/model_parameter.metaschema.yml +78 -0
  86. simtools/schemas/{data.metaschema.yml → model_parameter_and_data_schema.metaschema.yml} +27 -44
  87. simtools/schemas/model_parameters/adjust_gain.schema.yml +37 -0
  88. simtools/schemas/model_parameters/altitude.schema.yml +37 -0
  89. simtools/schemas/model_parameters/array_coordinates.schema.yml +33 -0
  90. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +77 -0
  91. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +39 -0
  92. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +39 -0
  93. simtools/schemas/model_parameters/array_layouts.schema.yml +48 -0
  94. simtools/schemas/model_parameters/array_triggers.schema.yml +93 -0
  95. simtools/schemas/model_parameters/asum_clipping.schema.yml +38 -0
  96. simtools/schemas/model_parameters/asum_offset.schema.yml +35 -0
  97. simtools/schemas/model_parameters/asum_shaping.schema.yml +35 -0
  98. simtools/schemas/model_parameters/asum_threshold.schema.yml +38 -0
  99. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +32 -0
  100. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +35 -0
  101. simtools/schemas/model_parameters/axes_offsets.schema.yml +53 -0
  102. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +40 -0
  103. simtools/schemas/model_parameters/camera_body_shape.schema.yml +45 -0
  104. simtools/schemas/model_parameters/camera_config_file.schema.yml +40 -0
  105. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +36 -0
  106. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +43 -0
  107. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +42 -0
  108. simtools/schemas/model_parameters/camera_depth.schema.yml +42 -0
  109. simtools/schemas/model_parameters/camera_filter.schema.yml +45 -0
  110. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +29 -0
  111. simtools/schemas/model_parameters/camera_pixels.schema.yml +36 -0
  112. simtools/schemas/model_parameters/camera_transmission.schema.yml +41 -0
  113. simtools/schemas/model_parameters/channels_per_chip.schema.yml +36 -0
  114. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +35 -0
  115. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +27 -0
  116. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +38 -0
  117. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +28 -0
  118. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +23 -0
  119. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +27 -0
  120. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +28 -0
  121. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +27 -0
  122. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +38 -0
  123. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +52 -0
  124. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +27 -0
  125. simtools/schemas/model_parameters/dark_events.schema.yml +32 -0
  126. simtools/schemas/model_parameters/default_trigger.schema.yml +35 -0
  127. simtools/schemas/model_parameters/design_model.schema.yml +31 -0
  128. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +32 -0
  129. simtools/schemas/model_parameters/disc_bins.schema.yml +39 -0
  130. simtools/schemas/model_parameters/disc_start.schema.yml +41 -0
  131. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +42 -0
  132. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +41 -0
  133. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +41 -0
  134. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +39 -0
  135. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +40 -0
  136. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +41 -0
  137. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +33 -0
  138. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +42 -0
  139. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +37 -0
  140. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +44 -0
  141. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +36 -0
  142. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +45 -0
  143. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +40 -0
  144. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +41 -0
  145. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +38 -0
  146. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +38 -0
  147. simtools/schemas/model_parameters/dish_shape_length.schema.yml +41 -0
  148. simtools/schemas/model_parameters/dsum_clipping.schema.yml +38 -0
  149. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +38 -0
  150. simtools/schemas/model_parameters/dsum_offset.schema.yml +37 -0
  151. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +33 -0
  152. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +39 -0
  153. simtools/schemas/model_parameters/dsum_prescale.schema.yml +44 -0
  154. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +38 -0
  155. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +45 -0
  156. simtools/schemas/model_parameters/dsum_shaping.schema.yml +44 -0
  157. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +32 -0
  158. simtools/schemas/model_parameters/dsum_threshold.schema.yml +43 -0
  159. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +42 -0
  160. simtools/schemas/model_parameters/effective_focal_length.schema.yml +61 -0
  161. simtools/schemas/model_parameters/epsg_code.schema.yml +37 -0
  162. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +35 -0
  163. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +46 -0
  164. simtools/schemas/model_parameters/fadc_bins.schema.yml +40 -0
  165. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +50 -0
  166. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +38 -0
  167. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +42 -0
  168. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +49 -0
  169. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +47 -0
  170. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +51 -0
  171. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +37 -0
  172. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +43 -0
  173. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +49 -0
  174. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +43 -0
  175. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +39 -0
  176. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +42 -0
  177. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +40 -0
  178. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +50 -0
  179. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +42 -0
  180. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +41 -0
  181. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +42 -0
  182. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +43 -0
  183. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +39 -0
  184. simtools/schemas/model_parameters/fadc_mhz.schema.yml +31 -0
  185. simtools/schemas/model_parameters/fadc_noise.schema.yml +41 -0
  186. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +40 -0
  187. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +39 -0
  188. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +50 -0
  189. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +43 -0
  190. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +43 -0
  191. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +42 -0
  192. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +41 -0
  193. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +42 -0
  194. simtools/schemas/model_parameters/flatfielding.schema.yml +37 -0
  195. simtools/schemas/model_parameters/focal_length.schema.yml +45 -0
  196. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +158 -0
  197. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +29 -0
  198. simtools/schemas/model_parameters/focus_offset.schema.yml +66 -0
  199. simtools/schemas/model_parameters/gain_variation.schema.yml +43 -0
  200. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +34 -0
  201. simtools/schemas/model_parameters/geomag_rotation.schema.yml +37 -0
  202. simtools/schemas/model_parameters/geomag_vertical.schema.yml +34 -0
  203. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +36 -0
  204. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +34 -0
  205. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +34 -0
  206. simtools/schemas/model_parameters/laser_events.schema.yml +36 -0
  207. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +35 -0
  208. simtools/schemas/model_parameters/laser_photons.schema.yml +32 -0
  209. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +34 -0
  210. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +34 -0
  211. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +33 -0
  212. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +33 -0
  213. simtools/schemas/model_parameters/laser_var_photons.schema.yml +33 -0
  214. simtools/schemas/model_parameters/laser_wavelength.schema.yml +33 -0
  215. simtools/schemas/model_parameters/led_events.schema.yml +34 -0
  216. simtools/schemas/model_parameters/led_photons.schema.yml +34 -0
  217. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +32 -0
  218. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +33 -0
  219. simtools/schemas/model_parameters/led_var_photons.schema.yml +34 -0
  220. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +41 -0
  221. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +43 -0
  222. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +35 -0
  223. simtools/schemas/model_parameters/min_photons.schema.yml +32 -0
  224. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +36 -0
  225. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +64 -0
  226. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +64 -0
  227. simtools/schemas/model_parameters/mirror_class.schema.yml +41 -0
  228. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +51 -0
  229. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +42 -0
  230. simtools/schemas/model_parameters/mirror_list.schema.yml +38 -0
  231. simtools/schemas/model_parameters/mirror_offset.schema.yml +41 -0
  232. simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +39 -0
  233. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +61 -0
  234. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +40 -0
  235. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +46 -0
  236. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +51 -0
  237. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +37 -0
  238. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +79 -0
  239. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +47 -0
  240. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +34 -0
  241. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +33 -0
  242. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +35 -0
  243. simtools/schemas/model_parameters/nsb_skymap.schema.yml +39 -0
  244. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +50 -0
  245. simtools/schemas/model_parameters/num_gains.schema.yml +34 -0
  246. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +33 -0
  247. simtools/schemas/model_parameters/optics_properties.schema.yml +31 -0
  248. simtools/schemas/model_parameters/parabolic_dish.schema.yml +32 -0
  249. simtools/schemas/model_parameters/pedestal_events.schema.yml +32 -0
  250. simtools/schemas/model_parameters/photon_delay.schema.yml +38 -0
  251. simtools/schemas/model_parameters/photons_per_run.schema.yml +33 -0
  252. simtools/schemas/model_parameters/pixel_cells.schema.yml +35 -0
  253. simtools/schemas/model_parameters/pixels_parallel.schema.yml +54 -0
  254. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +40 -0
  255. simtools/schemas/model_parameters/pm_average_gain.schema.yml +34 -0
  256. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +40 -0
  257. simtools/schemas/model_parameters/pm_gain_index.schema.yml +36 -0
  258. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +41 -0
  259. simtools/schemas/model_parameters/pm_transit_time.schema.yml +63 -0
  260. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +39 -0
  261. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +42 -0
  262. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +33 -0
  263. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +33 -0
  264. simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +29 -0
  265. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +168 -0
  266. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +36 -0
  267. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +34 -0
  268. simtools/schemas/model_parameters/qe_variation.schema.yml +43 -0
  269. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +42 -0
  270. simtools/schemas/model_parameters/random_focal_length.schema.yml +45 -0
  271. simtools/schemas/model_parameters/random_generator.schema.yml +36 -0
  272. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +35 -0
  273. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +36 -0
  274. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +36 -0
  275. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +34 -0
  276. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +34 -0
  277. simtools/schemas/model_parameters/sampled_output.schema.yml +31 -0
  278. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +34 -0
  279. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +79 -0
  280. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +42 -0
  281. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +41 -0
  282. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +33 -0
  283. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +36 -0
  284. simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +29 -0
  285. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +168 -0
  286. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +36 -0
  287. simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +35 -0
  288. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +37 -0
  289. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +40 -0
  290. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +40 -0
  291. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +41 -0
  292. simtools/schemas/model_parameters/tailcut_scale.schema.yml +40 -0
  293. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +31 -0
  294. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +35 -0
  295. simtools/schemas/model_parameters/telescope_random_error.schema.yml +34 -0
  296. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +37 -0
  297. simtools/schemas/model_parameters/telescope_transmission.schema.yml +113 -0
  298. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +41 -0
  299. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +36 -0
  300. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +36 -0
  301. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +37 -0
  302. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +38 -0
  303. simtools/schemas/model_parameters/transit_time_error.schema.yml +45 -0
  304. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +36 -0
  305. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +32 -0
  306. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +53 -0
  307. simtools/schemas/model_parameters/trigger_pixels.schema.yml +40 -0
  308. simtools/simtel/simtel_config_reader.py +353 -0
  309. simtools/simtel/simtel_config_writer.py +244 -63
  310. simtools/simtel/{simtel_events.py → simtel_io_events.py} +26 -25
  311. simtools/simtel/simtel_io_histogram.py +661 -0
  312. simtools/simtel/simtel_io_histograms.py +569 -0
  313. simtools/simtel/simulator_array.py +145 -0
  314. simtools/simtel/{simtel_runner_camera_efficiency.py → simulator_camera_efficiency.py} +76 -52
  315. simtools/simtel/simulator_light_emission.py +473 -0
  316. simtools/simtel/simulator_ray_tracing.py +262 -0
  317. simtools/simulator.py +220 -446
  318. simtools/testing/__init__.py +0 -0
  319. simtools/testing/assertions.py +151 -0
  320. simtools/testing/configuration.py +226 -0
  321. simtools/testing/helpers.py +42 -0
  322. simtools/testing/validate_output.py +240 -0
  323. simtools/utils/general.py +340 -437
  324. simtools/utils/geometry.py +12 -12
  325. simtools/utils/names.py +257 -644
  326. simtools/utils/value_conversion.py +176 -0
  327. simtools/version.py +3 -1
  328. simtools/visualization/legend_handlers.py +135 -152
  329. simtools/visualization/plot_camera.py +379 -0
  330. simtools/visualization/visualize.py +346 -167
  331. gammasimtools-0.6.1.dist-info/METADATA +0 -180
  332. gammasimtools-0.6.1.dist-info/RECORD +0 -91
  333. gammasimtools-0.6.1.dist-info/entry_points.txt +0 -23
  334. simtools/_dev_version/scm_version.py +0 -10
  335. simtools/applications/db_development_tools/add_new_parameter_to_db.py +0 -81
  336. simtools/applications/db_development_tools/add_unit_to_parameter_in_db.py +0 -59
  337. simtools/applications/db_development_tools/mark_non_optics_parameters_non_applicable.py +0 -102
  338. simtools/applications/get_parameter.py +0 -92
  339. simtools/applications/make_regular_arrays.py +0 -160
  340. simtools/applications/produce_array_config.py +0 -136
  341. simtools/applications/production.py +0 -313
  342. simtools/applications/sim_showers_for_trigger_rates.py +0 -187
  343. simtools/applications/tune_psf.py +0 -334
  344. simtools/corsika/corsika_default_config.py +0 -282
  345. simtools/corsika/corsika_runner.py +0 -450
  346. simtools/corsika_simtel/corsika_simtel_runner.py +0 -197
  347. simtools/db_handler.py +0 -1480
  348. simtools/ray_tracing.py +0 -525
  349. simtools/simtel/simtel_histograms.py +0 -414
  350. simtools/simtel/simtel_runner.py +0 -244
  351. simtools/simtel/simtel_runner_array.py +0 -293
  352. simtools/simtel/simtel_runner_ray_tracing.py +0 -277
  353. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.2.dist-info}/LICENSE +0 -0
  354. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.2.dist-info}/top_level.txt +0 -0
  355. /simtools/{corsika_simtel → db}/__init__.py +0 -0
@@ -1,607 +1,81 @@
1
+ """MC model of a telescope."""
2
+
1
3
  import logging
2
- import shutil
3
- from copy import copy
4
- from pydoc import locate
4
+ from pathlib import Path
5
5
 
6
6
  import astropy.io.ascii
7
7
  import numpy as np
8
- from astropy import units as u
9
8
  from astropy.table import Table
10
9
 
11
10
  import simtools.utils.general as gen
12
- from simtools import db_handler
13
- from simtools.io_operations import io_handler
14
11
  from simtools.model.camera import Camera
15
12
  from simtools.model.mirrors import Mirrors
16
- from simtools.simtel.simtel_config_writer import SimtelConfigWriter
13
+ from simtools.model.model_parameter import InvalidModelParameterError, ModelParameter
17
14
  from simtools.utils import names
18
15
 
19
- __all__ = ["InvalidParameter", "TelescopeModel"]
20
-
21
-
22
- class InvalidParameter(Exception):
23
- """Exception for invalid parameter."""
16
+ __all__ = ["TelescopeModel"]
24
17
 
25
18
 
26
- class TelescopeModel:
19
+ class TelescopeModel(ModelParameter):
27
20
  """
28
- TelescopeModel represents the MC model of an individual telescope. It contains the list of \
29
- parameters that can be read from the DB. A set of methods are available to manipulate \
30
- parameters (changing, adding, removing etc).
21
+ TelescopeModel represents the MC model of an individual telescope.
22
+
23
+ TelescopeModel contains parameter names and values for a specific telescope model.
31
24
 
32
25
  Parameters
33
26
  ----------
34
27
  site: str
35
- South or North.
36
- telescope_model_name: str
37
- Telescope name (ex. LST-1, ...).
28
+ Site name (e.g., South or North).
29
+ telescope_name: str
30
+ Telescope name (ex. LSTN-01, LSTN-design, ...).
38
31
  mongo_db_config: dict
39
32
  MongoDB configuration.
40
33
  model_version: str
41
- Version of the model (ex. prod5).
42
- label: str
34
+ Model version.
35
+ label: str, optional
43
36
  Instance label. Important for output file naming.
44
37
  """
45
38
 
46
39
  def __init__(
47
40
  self,
48
- site,
49
- telescope_model_name,
50
- mongo_db_config=None,
51
- model_version="Released",
52
- db=None,
53
- label=None,
41
+ site: str,
42
+ telescope_name: str,
43
+ mongo_db_config: dict,
44
+ model_version: str,
45
+ label: str | None = None,
54
46
  ):
55
- """
56
- Initialize TelescopeModel.
57
- """
47
+ """Initialize TelescopeModel."""
48
+ super().__init__(
49
+ site=site,
50
+ array_element_name=telescope_name,
51
+ mongo_db_config=mongo_db_config,
52
+ model_version=model_version,
53
+ db=None,
54
+ label=label,
55
+ )
56
+
58
57
  self._logger = logging.getLogger(__name__)
59
- self._logger.debug("Init TelescopeModel")
60
-
61
- self.site = names.validate_site_name(site)
62
- self.name = names.validate_telescope_model_name(telescope_model_name)
63
- self.model_version = names.validate_model_version_name(model_version)
64
- self.label = label
65
- self._extra_label = None
66
- self._added_parameter_files = None
58
+ self._logger.debug("Init TelescopeModel %s %s", site, telescope_name)
59
+
67
60
  self._single_mirror_list_file_paths = None
68
- self.simtel_config_writer = None
69
61
  self._mirrors = None
70
- self._reference_data = None
71
- self._derived = None
72
62
  self._camera = None
73
63
 
74
- self.io_handler = io_handler.IOHandler()
75
- self.db = None
76
- if db is not None:
77
- self.db = db
78
- elif mongo_db_config is not None:
79
- self._logger.debug("Connecting to DB")
80
- self.db = db_handler.DatabaseHandler(mongo_db_config=mongo_db_config)
81
-
82
- self._parameters = {}
83
-
84
- self._load_parameters_from_db()
85
-
86
- self._set_config_file_directory_and_name()
87
- self._is_config_file_up_to_date = False
88
- self._is_exported_model_files_up_to_date = False
89
-
90
64
  @property
91
65
  def mirrors(self):
92
- """
93
- Load the mirror information if the class instance hasn't done it yet.
94
- """
66
+ """Load the mirror information if the class instance hasn't done it yet."""
95
67
  if self._mirrors is None:
96
68
  self._load_mirrors()
97
69
  return self._mirrors
98
70
 
99
71
  @property
100
72
  def camera(self):
101
- """
102
- Load the camera information if the class instance hasn't done it yet.
103
- """
73
+ """Load the camera information if the class instance hasn't done it yet."""
104
74
  if self._camera is None:
105
75
  self._load_camera()
106
76
  return self._camera
107
77
 
108
- @property
109
- def reference_data(self):
110
- """
111
- Load the reference data information if the class instance hasn't done it yet.
112
- """
113
- if self._reference_data is None:
114
- self._load_reference_data()
115
- return self._reference_data
116
-
117
- @property
118
- def derived(self):
119
- """
120
- Load the derived values and export them if the class instance hasn't done it yet.
121
- """
122
- if self._derived is None:
123
- self._load_derived_values()
124
- self.export_derived_files()
125
- return self._derived
126
-
127
- @property
128
- def extra_label(self):
129
- """
130
- Return the extra label if defined, if not return ''.
131
- """
132
- return self._extra_label if self._extra_label is not None else ""
133
-
134
- @classmethod
135
- def from_config_file(cls, config_file_name, site, telescope_model_name, label=None):
136
- """
137
- Create a TelescopeModel from a sim_telarray config file.
138
-
139
- Notes
140
- -----
141
- This function does not deal with ifdef/indef etc., it just keeps the last version
142
- of the parameters in the file. This is fine for now since we do not
143
- expect to read from sim_telarray config files in the future.
144
-
145
- Parameters
146
- ----------
147
- config_file_name: str or Path
148
- Path to the input config file.
149
- site: str
150
- South or North.
151
- telescope_model_name: str
152
- Telescope model name for the base set of parameters (ex. LST-1, ...).
153
- label: str
154
- Instance label. Important for output file naming.
155
-
156
- Returns
157
- -------
158
- TelescopeModel
159
- Instance of TelescopeModel.
160
- """
161
- parameters = {}
162
- tel = cls(
163
- site=site,
164
- telescope_model_name=telescope_model_name,
165
- mongo_db_config=None,
166
- label=label,
167
- )
168
-
169
- def _process_line(words):
170
- """
171
- Process a line of the input config file that contains a parameter.
172
-
173
- Parameters
174
- ----------
175
- words: list of str
176
- List of str from the split of a line from the file.
177
-
178
- Returns
179
- -------
180
- (par_name, par_value)
181
- """
182
- i_comment = len(words) # Index of any possible comment
183
- for w in words:
184
- if "%" in w:
185
- i_comment = words.index(w)
186
- break
187
- words = words[0:i_comment] # Removing comment
188
- par_name = words[0].replace("=", "")
189
- par_value = ""
190
- for w in words[1:]:
191
- w = w.replace("=", "")
192
- w = w.replace(",", " ")
193
- par_value += w + " "
194
- par_value = par_value.rstrip().lstrip() # Removing trailing spaces (left and right)
195
- return par_name, par_value
196
-
197
- with open(config_file_name, "r", encoding="utf-8") as file:
198
- for line in file:
199
- words = line.split()
200
- if len(words) == 0:
201
- continue
202
- if "%" in words[0] or "echo" in words:
203
- continue
204
- if "#" not in line and len(words) > 0:
205
- par, value = _process_line(words)
206
- parameters[par] = value
207
-
208
- for par, value in parameters.items():
209
- tel.add_parameter(par, value)
210
-
211
- tel._is_exported_model_files_up_to_date = True
212
- return tel
213
-
214
- def set_extra_label(self, extra_label):
215
- """
216
- Set an extra label for the name of the config file.
217
-
218
- Notes
219
- -----
220
- The config file directory name is not affected by the extra label. Only the file name is \
221
- changed. This is important for the ArrayModel class to export multiple config files in the\
222
- same directory.
223
-
224
- Parameters
225
- ----------
226
- extra_label: str
227
- Extra label to be appended to the original label.
228
- """
229
-
230
- self._extra_label = extra_label
231
- self._set_config_file_directory_and_name()
232
-
233
- def _set_config_file_directory_and_name(self):
234
- """Define the variable _config_file_directory and create directories, if needed."""
235
-
236
- self._config_file_directory = self.io_handler.get_output_directory(
237
- label=self.label, sub_dir="model"
238
- )
239
-
240
- # Setting file name and the location
241
- config_file_name = names.simtel_telescope_config_file_name(
242
- self.site, self.name, self.model_version, self.label, self._extra_label
243
- )
244
- self._config_file_path = self._config_file_directory.joinpath(config_file_name)
245
-
246
- def _load_parameters_from_db(self):
247
- """Read parameters from DB and store them in _parameters."""
248
-
249
- if self.db is None:
250
- return
251
-
252
- self._logger.debug("Reading telescope parameters from DB")
253
-
254
- self._set_config_file_directory_and_name()
255
- self._parameters = self.db.get_model_parameters(
256
- self.site, self.name, self.model_version, only_applicable=True
257
- )
258
-
259
- self._logger.debug("Reading site parameters from DB")
260
- _site_pars = self.db.get_site_parameters(
261
- self.site, self.model_version, only_applicable=True
262
- )
263
- self._parameters.update(_site_pars)
264
-
265
- def has_parameter(self, par_name):
266
- """
267
- Verify if the parameter is in the model.
268
-
269
- Parameters
270
- ----------
271
- par_name: str
272
- Name of the parameter.
273
-
274
- Returns
275
- -------
276
- bool
277
- True if parameter is in the model.
278
- """
279
- return par_name in self._parameters
280
-
281
- def get_parameter(self, par_name):
282
- """
283
- Get an existing parameter of the model, including derived parameters.
284
-
285
- Parameters
286
- ----------
287
- par_name: str
288
- Name of the parameter.
289
-
290
- Returns
291
- -------
292
- Value of the parameter
293
-
294
- Raises
295
- ------
296
- InvalidParameter
297
- If par_name does not match any parameter in this model.
298
- """
299
- try:
300
- return self._parameters[par_name]
301
- except KeyError:
302
- pass # search in the derived parameters
303
- try:
304
- return self.derived[par_name]
305
- except KeyError as e:
306
- msg = f"Parameter {par_name} was not found in the model"
307
- self._logger.error(msg)
308
- raise InvalidParameter(msg) from e
309
-
310
- def get_parameter_value(self, par_name):
311
- """
312
- Get the value of an existing parameter of the model.
313
-
314
- Parameters
315
- ----------
316
- par_name: str
317
- Name of the parameter.
318
-
319
- Returns
320
- -------
321
- Value of the parameter.
322
-
323
- Raises
324
- ------
325
- InvalidParameter
326
- If par_name does not match any parameter in this model.
327
- """
328
- par_info = self.get_parameter(par_name)
329
- return par_info["Value"]
330
-
331
- def get_parameter_value_with_unit(self, par_name):
332
- """
333
- Get the value of an existing parameter of the model as an Astropy Quantity with its unit.\
334
- If no unit is provided in the model, the value is returned without a unit.
335
-
336
- Parameters
337
- ----------
338
- par_name: str
339
- Name of the parameter.
340
-
341
- Returns
342
- -------
343
- Astropy quantity with the value of the parameter multiplied by its unit. If no unit is \
344
- provided in the model, the value is returned without a unit.
345
-
346
- Raises
347
- ------
348
- InvalidParameter
349
- If par_name does not match any parameter in this model.
350
- """
351
- par_info = self.get_parameter(par_name)
352
- if "units" in par_info:
353
- return par_info["Value"] * u.Unit(par_info["units"])
354
- return par_info["Value"]
355
-
356
- def add_parameter(self, par_name, value, is_file=False, is_aplicable=True):
357
- """
358
- Add a new parameters to the model. This function does not modify the DB, it affects only \
359
- the current instance.
360
-
361
- Parameters
362
- ----------
363
- par_name: str
364
- Name of the parameter.
365
- value:
366
- Value of the parameter.
367
- is_file: bool
368
- Indicates whether the new parameter is a file or not.
369
- is_aplicable: bool
370
- Indicates whether the new parameter is applicable or not.
371
-
372
- Raises
373
- ------
374
- InvalidParameter
375
- If an existing parameter is tried to be added.
376
- """
377
- if par_name in self._parameters:
378
- msg = f"Parameter {par_name} already in the model, use change_parameter instead"
379
- self._logger.error(msg)
380
- raise InvalidParameter(msg)
381
-
382
- self._logger.info(f"Adding {par_name}={value} to the model")
383
- self._parameters[par_name] = {}
384
- self._parameters[par_name]["Value"] = value
385
- self._parameters[par_name]["Type"] = type(value)
386
- self._parameters[par_name]["Applicable"] = is_aplicable
387
- self._parameters[par_name]["File"] = is_file
388
-
389
- self._is_config_file_up_to_date = False
390
- if is_file:
391
- self._is_exported_model_files_up_to_date = False
392
-
393
- def change_parameter(self, par_name, value):
394
- """
395
- Change the value of an existing parameter to the model. This function does not modify the \
396
- DB, it affects only the current instance.
397
-
398
- Parameters
399
- ----------
400
- par_name: str
401
- Name of the parameter.
402
- value:
403
- Value of the parameter.
404
-
405
- Raises
406
- ------
407
- InvalidParameter
408
- If the parameter to be changed does not exist in this model.
409
- """
410
- if par_name not in self._parameters:
411
- msg = f"Parameter {par_name} not in the model, use add_parameters instead"
412
- self._logger.error(msg)
413
- raise InvalidParameter(msg)
414
-
415
- type_of_par_name = locate(self._parameters[par_name]["Type"])
416
- if not isinstance(value, type_of_par_name):
417
- self._logger.warning(
418
- f"The type of the provided value ({value}, {type(value)}) "
419
- f"is different from the type of {par_name} "
420
- f"({self._parameters[par_name]['Type']}). "
421
- f"Attempting to cast to the correct type."
422
- )
423
- try:
424
- value = type_of_par_name(value)
425
- except ValueError:
426
- self._logger.error(
427
- f"Could not cast {value} to {self._parameters[par_name]['Type']}."
428
- )
429
- raise
430
-
431
- self._logger.debug(
432
- f"Changing parameter {par_name} "
433
- f"from {self._parameters[par_name]['Value']} to {value}"
434
- )
435
- self._parameters[par_name]["Value"] = value
436
-
437
- # In case parameter is a file, the model files will be outdated
438
- if self._parameters[par_name]["File"]:
439
- self._is_exported_model_files_up_to_date = False
440
-
441
- self._is_config_file_up_to_date = False
442
-
443
- def change_multiple_parameters(self, **kwargs):
444
- """
445
- Change the value of multiple existing parameters in the model. This function does not \
446
- modify the DB, it affects only the current instance.
447
-
448
- Parameters
449
- ----------
450
- **kwargs
451
- Parameters should be passed as parameter_name=value.
452
-
453
- Raises
454
- ------
455
- InvalidParameter
456
- If at least one of the parameters to be changed does not exist in this model.
457
- """
458
- for par, value in kwargs.items():
459
- if par in self._parameters:
460
- self.change_parameter(par, value)
461
- else:
462
- self.add_parameter(par, value)
463
-
464
- self._is_config_file_up_to_date = False
465
-
466
- def remove_parameters(self, *args):
467
- """
468
- Remove a set of parameters from the model.
469
-
470
- Parameters
471
- ----------
472
- *args
473
- Each parameter to be removed has to be passed as args.
474
-
475
- Raises
476
- ------
477
- InvalidParameter
478
- If at least one of the parameter to be removed is not in this model.
479
- """
480
- for par in args:
481
- if par in self._parameters:
482
- self._logger.info(f"Removing parameter {par}")
483
- del self._parameters[par]
484
- else:
485
- msg = f"Could not remove parameter {par} because it does not exist"
486
- self._logger.error(msg)
487
- raise InvalidParameter(msg)
488
- self._is_config_file_up_to_date = False
489
-
490
- def add_parameter_file(self, par_name, file_path):
491
- """
492
- Add a file to the config file directory.
493
-
494
- Parameters
495
- ----------
496
- par_name: str
497
- Name of the parameter.
498
- file_path: str
499
- Path of the file to be added to the config file directory.
500
- """
501
- if self._added_parameter_files is None:
502
- self._added_parameter_files = []
503
- self._added_parameter_files.append(par_name)
504
- shutil.copy(file_path, self._config_file_directory)
505
-
506
- def export_model_files(self):
507
- """Exports the model files into the config file directory."""
508
-
509
- # Removing parameter files added manually (which are not in DB)
510
- pars_from_db = copy(self._parameters)
511
- if self._added_parameter_files is not None:
512
- for par in self._added_parameter_files:
513
- pars_from_db.pop(par)
514
-
515
- self.db.export_model_files(pars_from_db, self._config_file_directory)
516
- self._is_exported_model_files_up_to_date = True
517
-
518
- def print_parameters(self):
519
- """Print parameters and their values for debugging purposes."""
520
- for par, info in self._parameters.items():
521
- print(f"{par} = {info['Value']}")
522
-
523
- def export_config_file(self):
524
- """Export the config file used by sim_telarray."""
525
-
526
- # Exporting model file
527
- if not self._is_exported_model_files_up_to_date:
528
- self.export_model_files()
529
-
530
- # Using SimtelConfigWriter to write the config file.
531
- self._load_simtel_config_writer()
532
- self.simtel_config_writer.write_telescope_config_file(
533
- config_file_path=self._config_file_path, parameters=self._parameters
534
- )
535
-
536
- def export_derived_files(self):
537
- """Write to disk a file from the derived values DB."""
538
-
539
- for par_now in self.derived.values():
540
- if par_now["File"]:
541
- self.db.export_file_db(
542
- db_name=self.db.DB_DERIVED_VALUES,
543
- dest=self.io_handler.get_output_directory(label=self.label, sub_dir="derived"),
544
- file_name=par_now["Value"],
545
- )
546
-
547
- def get_config_file(self, no_export=False):
548
- """
549
- Get the path of the config file for sim_telarray. The config file is produced if the file\
550
- is not updated.
551
-
552
- Parameters
553
- ----------
554
- no_export: bool
555
- Turn it on if you do not want the file to be exported.
556
-
557
- Returns
558
- -------
559
- Path
560
- Path of the exported config file for sim_telarray.
561
- """
562
- if not self._is_config_file_up_to_date and not no_export:
563
- self.export_config_file()
564
- return self._config_file_path
565
-
566
- def get_config_directory(self):
567
- """
568
- Get the path where all the configuration files for sim_telarray are written to.
569
-
570
- Returns
571
- -------
572
- Path
573
- Path where all the configuration files for sim_telarray are written to.
574
- """
575
- return self._config_file_directory
576
-
577
- def get_derived_directory(self):
578
- """
579
- Get the path where all the files with derived values for are written to.
580
-
581
- Returns
582
- -------
583
- Path
584
- Path where all the files with derived values are written to.
585
- """
586
- return self._config_file_directory.parents[0].joinpath("derived")
587
-
588
- def get_telescope_transmission_parameters(self):
589
- """
590
- Get tel. transmission pars as a list of floats.
591
-
592
- Returns
593
- -------
594
- list of floats
595
- List of 4 parameters that describe the tel. transmission vs off-axis.
596
- """
597
-
598
- telescope_transmission = self.get_parameter_value("telescope_transmission")
599
- if isinstance(telescope_transmission, str):
600
- return [float(v) for v in self.get_parameter_value("telescope_transmission").split()]
601
-
602
- return [float(telescope_transmission), 0, 0, 0]
603
-
604
- def export_single_mirror_list_file(self, mirror_number, set_focal_length_to_zero):
78
+ def export_single_mirror_list_file(self, mirror_number: int, set_focal_length_to_zero: bool):
605
79
  """
606
80
  Export a mirror list file with a single mirror in it.
607
81
 
@@ -621,7 +95,7 @@ class TelescopeModel:
621
95
  )
622
96
  if self._single_mirror_list_file_paths is None:
623
97
  self._single_mirror_list_file_paths = {}
624
- self._single_mirror_list_file_paths[mirror_number] = self._config_file_directory.joinpath(
98
+ self._single_mirror_list_file_paths[mirror_number] = self.config_file_directory.joinpath(
625
99
  file_name
626
100
  )
627
101
 
@@ -634,7 +108,9 @@ class TelescopeModel:
634
108
  set_focal_length_to_zero,
635
109
  )
636
110
 
637
- def get_single_mirror_list_file(self, mirror_number, set_focal_length_to_zero=False):
111
+ def get_single_mirror_list_file(
112
+ self, mirror_number: int, set_focal_length_to_zero: bool = False
113
+ ):
638
114
  """
639
115
  Get the path to the single mirror list file.
640
116
 
@@ -655,46 +131,70 @@ class TelescopeModel:
655
131
 
656
132
  def _load_mirrors(self):
657
133
  """Load the attribute mirrors by creating a Mirrors object with the mirror list file."""
658
- mirror_list_file_name = self._parameters["mirror_list"]["Value"]
134
+ mirror_list_file_name = self.get_parameter_value("mirror_list")
135
+ self._logger.debug(f"Reading mirror list from {mirror_list_file_name}")
659
136
  try:
660
- mirror_list_file = gen.find_file(mirror_list_file_name, self._config_file_directory)
137
+ mirror_list_file = gen.find_file(mirror_list_file_name, self.config_file_directory)
661
138
  except FileNotFoundError:
662
139
  mirror_list_file = gen.find_file(mirror_list_file_name, self.io_handler.model_path)
663
140
  self._logger.warning(
664
141
  "Mirror_list_file was not found in the config directory - "
665
142
  "Using the one found in the model_path"
666
143
  )
144
+ except TypeError as exc:
145
+ raise TypeError("Undefined mirror list") from exc
146
+
667
147
  self._mirrors = Mirrors(mirror_list_file, parameters=self._parameters)
668
148
 
669
- def _load_reference_data(self):
670
- """Load the reference data for this telescope from the DB."""
671
- self._logger.debug("Reading reference data from DB")
672
- self._reference_data = self.db.get_reference_data(
673
- self.site, self.model_version, only_applicable=True
674
- )
149
+ def get_telescope_effective_focal_length(
150
+ self, unit: str = "m", return_focal_length_if_zero: bool = False
151
+ ) -> float:
152
+ """
153
+ Return effective focal length.
675
154
 
676
- def _load_derived_values(self):
677
- """Load the derived values for this telescope from the DB."""
678
- self._logger.debug("Reading derived data from DB")
679
- self._derived = self.db.get_derived_values(
680
- self.site,
681
- self.name,
682
- self.model_version,
683
- )
155
+ The function ensures backwards compatibility with older sim-telarray versions.
156
+
157
+ Parameters
158
+ ----------
159
+ unit: str
160
+ Unit of the effective focal length. Default is 'm'.
161
+ return_focal_length_if_zero: bool
162
+ If True, return the focal length if the effective focal length is 0.
163
+
164
+ Returns
165
+ -------
166
+ float:
167
+ Effective focal length.
168
+ """
169
+ try:
170
+ eff_focal_length = self.get_parameter_value_with_unit("effective_focal_length")[0]
171
+ except TypeError:
172
+ eff_focal_length = self.get_parameter_value_with_unit("effective_focal_length")
173
+ try:
174
+ eff_focal_length = eff_focal_length.to(unit).value
175
+ except AttributeError:
176
+ eff_focal_length = 0.0
177
+ if return_focal_length_if_zero and (eff_focal_length is None or eff_focal_length == 0.0):
178
+ self._logger.warning("Using focal_length because effective_focal_length is 0")
179
+ return self.get_parameter_value_with_unit("focal_length").to(unit).value
180
+ return eff_focal_length
684
181
 
685
182
  def _load_camera(self):
686
- """Loading camera attribute by creating a Camera object with the camera config file."""
183
+ """Load camera attribute by creating a Camera object with the camera config file."""
687
184
  camera_config_file = self.get_parameter_value("camera_config_file")
688
- focal_length = self.get_parameter_value("effective_focal_length")
689
- if focal_length == 0.0:
690
- self._logger.warning("Using focal_length because effective_focal_length is 0.")
691
- focal_length = self.get_parameter_value("focal_length")
185
+ focal_length = self.get_telescope_effective_focal_length("cm", True)
692
186
  try:
693
- camera_config_file_path = gen.find_file(camera_config_file, self._config_file_directory)
187
+ camera_config_file_path = gen.find_file(camera_config_file, self.config_file_directory)
188
+ except TypeError as exc:
189
+ self._logger.error(
190
+ f"Camera config file {camera_config_file} or "
191
+ f"config file directory ({self.config_file_directory}) is None"
192
+ )
193
+ raise TypeError from exc
694
194
  except FileNotFoundError:
695
195
  self._logger.warning(
696
- "The camera_config_file was not found in the config directory - "
697
- "Using the one found in the model_path"
196
+ f"Camera config file {camera_config_file} not found in the config directory "
197
+ f"{self.config_file_directory}. Using the one found in the model_path"
698
198
  )
699
199
  camera_config_file_path = gen.find_file(camera_config_file, self.io_handler.model_path)
700
200
 
@@ -704,20 +204,7 @@ class TelescopeModel:
704
204
  focal_length=focal_length,
705
205
  )
706
206
 
707
- def _load_simtel_config_writer(self):
708
- """
709
- Load the SimtelConfigWriter object.
710
-
711
- """
712
- if self.simtel_config_writer is None:
713
- self.simtel_config_writer = SimtelConfigWriter(
714
- site=self.site,
715
- telescope_model_name=self.name,
716
- model_version=self.model_version,
717
- label=self.label,
718
- )
719
-
720
- def is_file_2d(self, par):
207
+ def is_file_2d(self, par: str) -> bool:
721
208
  """
722
209
  Check if the file referenced by par is a 2D table.
723
210
 
@@ -729,23 +216,24 @@ class TelescopeModel:
729
216
  Returns
730
217
  -------
731
218
  bool:
732
- True if the file is a 2D map type, False otherwise.
219
+ True if the file is a 2D map type.
733
220
  """
734
- if not self.has_parameter(par):
221
+ try:
222
+ file_name = self.get_parameter_value(par)
223
+ except KeyError:
735
224
  logging.error(f"Parameter {par} does not exist")
736
225
  return False
737
226
 
738
- file_name = self.get_parameter_value(par)
739
- file = self.get_config_directory().joinpath(file_name)
740
- with open(file, "r", encoding="utf-8") as f:
741
- is_2d = "@RPOL@" in f.read()
742
- return is_2d
227
+ file = self.config_file_directory.joinpath(file_name)
228
+ with open(file, encoding="utf-8") as f:
229
+ return "@RPOL@" in f.read()
743
230
 
744
- def read_two_dim_wavelength_angle(self, file_name):
231
+ def read_two_dim_wavelength_angle(self, file_name: str | Path) -> dict:
745
232
  """
746
- Read a two dimensional distribution of wavelngth and angle (z-axis can be anything). Return\
747
- a dictionary with three arrays, wavelength, angles, z (can be transmission, reflectivity,\
748
- etc.)
233
+ Read a two dimensional distribution of wavelength and angle (z-axis can be anything).
234
+
235
+ Return a dictionary with three arrays, wavelength, angles, z (can be transmission,
236
+ reflectivity, etc.)
749
237
 
750
238
  Parameters
751
239
  ----------
@@ -757,10 +245,10 @@ class TelescopeModel:
757
245
  dict:
758
246
  dict of three arrays, wavelength, degrees, z.
759
247
  """
760
-
761
- _file = self.get_config_directory().joinpath(file_name)
248
+ _file = self.config_file_directory.joinpath(file_name)
249
+ self._logger.debug("Reading two dimensional distribution from %s", _file)
762
250
  line_to_start_from = 0
763
- with open(_file, "r", encoding="utf-8") as f:
251
+ with open(_file, encoding="utf-8") as f:
764
252
  for i_line, line in enumerate(f):
765
253
  if line.startswith("ANGLE"):
766
254
  degrees = np.array(line.strip().split("=")[1].split(), dtype=np.float16)
@@ -775,21 +263,20 @@ class TelescopeModel:
775
263
  "z": np.array(_data[:, 1:]).T,
776
264
  }
777
265
 
778
- def get_on_axis_eff_optical_area(self):
266
+ def get_on_axis_eff_optical_area(self) -> float:
779
267
  """Return the on-axis effective optical area (derived previously for this telescope)."""
780
-
781
268
  ray_tracing_data = astropy.io.ascii.read(
782
- self.get_derived_directory().joinpath(self.derived["ray_tracing"]["Value"])
269
+ self.config_file_directory.joinpath(self.get_parameter_value("optics_properties"))
783
270
  )
784
271
  if not np.isclose(ray_tracing_data["Off-axis angle"][0], 0):
785
272
  self._logger.error(
786
273
  f"No value for the on-axis effective optical area exists."
787
- f" The minumum off-axis angle is {ray_tracing_data['Off-axis angle'][0]}"
274
+ f" The minimum off-axis angle is {ray_tracing_data['Off-axis angle'][0]}"
788
275
  )
789
276
  raise ValueError
790
277
  return ray_tracing_data["eff_area"][0]
791
278
 
792
- def read_incidence_angle_distribution(self, incidence_angle_dist_file):
279
+ def read_incidence_angle_distribution(self, incidence_angle_dist_file: str) -> Table:
793
280
  """
794
281
  Read the incidence angle distribution from a file.
795
282
 
@@ -803,17 +290,19 @@ class TelescopeModel:
803
290
  incidence_angle_dist: astropy.table.Table
804
291
  Instance of astropy.table.Table with the incidence angle distribution.
805
292
  """
806
-
807
- incidence_angle_dist = astropy.io.ascii.read(
808
- self.get_derived_directory().joinpath(incidence_angle_dist_file)
293
+ self._logger.debug(
294
+ "Reading incidence angle distribution from %s",
295
+ self.config_file_directory.joinpath(incidence_angle_dist_file),
809
296
  )
810
- return incidence_angle_dist
297
+ return astropy.io.ascii.read(self.config_file_directory.joinpath(incidence_angle_dist_file))
811
298
 
812
299
  @staticmethod
813
- def calc_average_curve(curves, incidence_angle_dist):
300
+ def calc_average_curve(curves: dict, incidence_angle_dist: Table) -> Table:
814
301
  """
815
- Calculate an average curve from a set of curves, using as weights the distribution of \
816
- incidence angles provided in incidence_angle_dist.
302
+ Calculate an average curve from a set of curves.
303
+
304
+ The calculation uses weights the distribution of incidence angles provided in
305
+ incidence_angle_dist.
817
306
 
818
307
  Parameters
819
308
  ----------
@@ -830,7 +319,6 @@ class TelescopeModel:
830
319
  average_curve: astropy.table.Table
831
320
  Instance of astropy.table.Table with the averaged curve.
832
321
  """
833
-
834
322
  weights = []
835
323
  for angle_now in curves["Angle"]:
836
324
  weights.append(
@@ -839,14 +327,12 @@ class TelescopeModel:
839
327
  ]
840
328
  )
841
329
 
842
- average_curve = Table(
330
+ return Table(
843
331
  [curves["Wavelength"], np.average(curves["z"], weights=weights, axis=0)],
844
332
  names=("Wavelength", "z"),
845
333
  )
846
334
 
847
- return average_curve
848
-
849
- def export_table_to_model_directory(self, file_name, table):
335
+ def export_table_to_model_directory(self, file_name: str, table: Table) -> str:
850
336
  """
851
337
  Write out a file with the provided table to the model directory.
852
338
 
@@ -862,7 +348,31 @@ class TelescopeModel:
862
348
  Path:
863
349
  Path to the file exported.
864
350
  """
865
-
866
- file_to_write_to = self._config_file_directory.joinpath(file_name)
351
+ file_to_write_to = self.config_file_directory.joinpath(file_name)
867
352
  table.write(file_to_write_to, format="ascii.commented_header", overwrite=True)
868
353
  return file_to_write_to.absolute()
354
+
355
+ def position(self, coordinate_system: str = "ground") -> list:
356
+ """
357
+ Get coordinates in the given system.
358
+
359
+ Parameters
360
+ ----------
361
+ coordinate_system: str
362
+ Coordinates system. Default is 'ground'.
363
+
364
+ Returns
365
+ -------
366
+ list :
367
+ List of telescope position in the requested coordinate system.
368
+
369
+ Raises
370
+ ------
371
+ KeyError
372
+ If the coordinate system is not found.
373
+ """
374
+ try:
375
+ return self.get_parameter_value_with_unit(f"array_element_position_{coordinate_system}")
376
+ except InvalidModelParameterError as exc:
377
+ self._logger.error(f"Coordinate system {coordinate_system} not found.")
378
+ raise exc