gammasimtools 0.6.1__py3-none-any.whl → 0.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. gammasimtools-0.8.1.dist-info/METADATA +172 -0
  2. gammasimtools-0.8.1.dist-info/RECORD +346 -0
  3. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/WHEEL +1 -1
  4. gammasimtools-0.8.1.dist-info/entry_points.txt +31 -0
  5. simtools/_version.py +2 -2
  6. simtools/applications/calculate_trigger_rate.py +210 -0
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +372 -0
  8. simtools/applications/{print_array_elements.py → convert_geo_coordinates_of_array_elements.py} +58 -63
  9. simtools/applications/convert_model_parameter_from_simtel.py +119 -0
  10. simtools/applications/{add_file_to_db.py → db_add_file_to_db.py} +70 -60
  11. simtools/applications/db_add_model_parameters_from_repository_to_db.py +184 -0
  12. simtools/applications/db_add_value_from_json_to_db.py +105 -0
  13. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +180 -0
  14. simtools/applications/db_get_array_layouts_from_db.py +162 -0
  15. simtools/applications/{get_file_from_db.py → db_get_file_from_db.py} +30 -34
  16. simtools/applications/db_get_parameter_from_db.py +131 -0
  17. simtools/applications/db_inspect_databases.py +52 -0
  18. simtools/applications/derive_mirror_rnda.py +39 -255
  19. simtools/applications/derive_psf_parameters.py +441 -0
  20. simtools/applications/generate_array_config.py +82 -0
  21. simtools/applications/generate_corsika_histograms.py +52 -52
  22. simtools/applications/generate_default_metadata.py +5 -8
  23. simtools/applications/generate_regular_arrays.py +117 -0
  24. simtools/applications/generate_simtel_array_histograms.py +97 -56
  25. simtools/applications/plot_array_layout.py +345 -115
  26. simtools/applications/production_generate_simulation_config.py +158 -0
  27. simtools/applications/production_scale_events.py +168 -0
  28. simtools/applications/simulate_light_emission.py +478 -0
  29. simtools/applications/simulate_prod.py +97 -175
  30. simtools/applications/submit_data_from_external.py +9 -12
  31. simtools/applications/submit_model_parameter_from_external.py +122 -0
  32. simtools/applications/validate_camera_efficiency.py +35 -102
  33. simtools/applications/validate_camera_fov.py +20 -19
  34. simtools/applications/{compare_cumulative_psf.py → validate_cumulative_psf.py} +45 -44
  35. simtools/applications/validate_file_using_schema.py +113 -47
  36. simtools/applications/validate_optics.py +17 -22
  37. simtools/camera_efficiency.py +193 -202
  38. simtools/configuration/commandline_parser.py +384 -96
  39. simtools/configuration/configurator.py +55 -71
  40. simtools/constants.py +5 -5
  41. simtools/corsika/corsika_config.py +482 -342
  42. simtools/corsika/corsika_histograms.py +226 -204
  43. simtools/corsika/corsika_histograms_visualize.py +23 -24
  44. simtools/corsika/primary_particle.py +159 -0
  45. simtools/data_model/data_reader.py +25 -20
  46. simtools/data_model/format_checkers.py +52 -0
  47. simtools/data_model/metadata_collector.py +210 -184
  48. simtools/data_model/metadata_model.py +115 -37
  49. simtools/data_model/model_data_writer.py +335 -26
  50. simtools/data_model/validate_data.py +366 -154
  51. simtools/db/db_array_elements.py +130 -0
  52. simtools/db/db_from_repo_handler.py +106 -0
  53. simtools/db/db_handler.py +1246 -0
  54. simtools/io_operations/hdf5_handler.py +3 -1
  55. simtools/io_operations/io_handler.py +32 -57
  56. simtools/job_execution/job_manager.py +82 -69
  57. simtools/layout/array_layout.py +325 -537
  58. simtools/layout/geo_coordinates.py +8 -11
  59. simtools/layout/telescope_position.py +163 -86
  60. simtools/model/array_model.py +305 -256
  61. simtools/model/calibration_model.py +50 -0
  62. simtools/model/camera.py +233 -493
  63. simtools/model/mirrors.py +61 -44
  64. simtools/model/model_parameter.py +602 -0
  65. simtools/model/model_utils.py +7 -35
  66. simtools/model/site_model.py +161 -0
  67. simtools/model/telescope_model.py +127 -621
  68. simtools/production_configuration/calculate_statistical_errors_grid_point.py +454 -0
  69. simtools/production_configuration/event_scaler.py +146 -0
  70. simtools/production_configuration/generate_simulation_config.py +193 -0
  71. simtools/production_configuration/interpolation_handler.py +197 -0
  72. simtools/ray_tracing/__init__.py +0 -0
  73. simtools/ray_tracing/mirror_panel_psf.py +280 -0
  74. simtools/{psf_analysis.py → ray_tracing/psf_analysis.py} +133 -47
  75. simtools/ray_tracing/ray_tracing.py +646 -0
  76. simtools/runners/__init__.py +0 -0
  77. simtools/runners/corsika_runner.py +240 -0
  78. simtools/runners/corsika_simtel_runner.py +225 -0
  79. simtools/runners/runner_services.py +307 -0
  80. simtools/runners/simtel_runner.py +224 -0
  81. simtools/schemas/array_elements.yml +137 -0
  82. simtools/schemas/integration_tests_config.metaschema.yml +93 -0
  83. simtools/schemas/metadata.metaschema.yml +6 -0
  84. simtools/schemas/model_parameter.metaschema.yml +78 -0
  85. simtools/schemas/{data.metaschema.yml → model_parameter_and_data_schema.metaschema.yml} +27 -44
  86. simtools/schemas/model_parameters/adjust_gain.schema.yml +37 -0
  87. simtools/schemas/model_parameters/altitude.schema.yml +37 -0
  88. simtools/schemas/model_parameters/array_coordinates.schema.yml +33 -0
  89. simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +77 -0
  90. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +39 -0
  91. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +39 -0
  92. simtools/schemas/model_parameters/array_layouts.schema.yml +48 -0
  93. simtools/schemas/model_parameters/array_triggers.schema.yml +93 -0
  94. simtools/schemas/model_parameters/asum_clipping.schema.yml +38 -0
  95. simtools/schemas/model_parameters/asum_offset.schema.yml +35 -0
  96. simtools/schemas/model_parameters/asum_shaping.schema.yml +35 -0
  97. simtools/schemas/model_parameters/asum_threshold.schema.yml +38 -0
  98. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +32 -0
  99. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +35 -0
  100. simtools/schemas/model_parameters/axes_offsets.schema.yml +53 -0
  101. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +40 -0
  102. simtools/schemas/model_parameters/camera_body_shape.schema.yml +45 -0
  103. simtools/schemas/model_parameters/camera_config_file.schema.yml +40 -0
  104. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +36 -0
  105. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +43 -0
  106. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +42 -0
  107. simtools/schemas/model_parameters/camera_depth.schema.yml +42 -0
  108. simtools/schemas/model_parameters/camera_filter.schema.yml +45 -0
  109. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +29 -0
  110. simtools/schemas/model_parameters/camera_pixels.schema.yml +36 -0
  111. simtools/schemas/model_parameters/camera_transmission.schema.yml +41 -0
  112. simtools/schemas/model_parameters/channels_per_chip.schema.yml +36 -0
  113. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +35 -0
  114. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +27 -0
  115. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +38 -0
  116. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +28 -0
  117. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +23 -0
  118. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +27 -0
  119. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +28 -0
  120. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +27 -0
  121. simtools/schemas/model_parameters/corsika_observation_level.schema.yml +38 -0
  122. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +52 -0
  123. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +27 -0
  124. simtools/schemas/model_parameters/dark_events.schema.yml +32 -0
  125. simtools/schemas/model_parameters/default_trigger.schema.yml +35 -0
  126. simtools/schemas/model_parameters/design_model.schema.yml +31 -0
  127. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +32 -0
  128. simtools/schemas/model_parameters/disc_bins.schema.yml +39 -0
  129. simtools/schemas/model_parameters/disc_start.schema.yml +41 -0
  130. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +42 -0
  131. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +41 -0
  132. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +41 -0
  133. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +39 -0
  134. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +40 -0
  135. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +41 -0
  136. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +33 -0
  137. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +42 -0
  138. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +37 -0
  139. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +44 -0
  140. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +36 -0
  141. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +45 -0
  142. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +40 -0
  143. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +41 -0
  144. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +38 -0
  145. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +38 -0
  146. simtools/schemas/model_parameters/dish_shape_length.schema.yml +41 -0
  147. simtools/schemas/model_parameters/dsum_clipping.schema.yml +38 -0
  148. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +38 -0
  149. simtools/schemas/model_parameters/dsum_offset.schema.yml +37 -0
  150. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +33 -0
  151. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +39 -0
  152. simtools/schemas/model_parameters/dsum_prescale.schema.yml +44 -0
  153. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +38 -0
  154. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +45 -0
  155. simtools/schemas/model_parameters/dsum_shaping.schema.yml +44 -0
  156. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +32 -0
  157. simtools/schemas/model_parameters/dsum_threshold.schema.yml +43 -0
  158. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +42 -0
  159. simtools/schemas/model_parameters/effective_focal_length.schema.yml +61 -0
  160. simtools/schemas/model_parameters/epsg_code.schema.yml +37 -0
  161. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +35 -0
  162. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +46 -0
  163. simtools/schemas/model_parameters/fadc_bins.schema.yml +40 -0
  164. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +50 -0
  165. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +38 -0
  166. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +42 -0
  167. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +49 -0
  168. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +47 -0
  169. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +51 -0
  170. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +37 -0
  171. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +43 -0
  172. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +49 -0
  173. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +43 -0
  174. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +39 -0
  175. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +42 -0
  176. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +40 -0
  177. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +50 -0
  178. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +42 -0
  179. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +41 -0
  180. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +42 -0
  181. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +43 -0
  182. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +39 -0
  183. simtools/schemas/model_parameters/fadc_mhz.schema.yml +31 -0
  184. simtools/schemas/model_parameters/fadc_noise.schema.yml +41 -0
  185. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +40 -0
  186. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +39 -0
  187. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +50 -0
  188. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +43 -0
  189. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +43 -0
  190. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +42 -0
  191. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +41 -0
  192. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +42 -0
  193. simtools/schemas/model_parameters/flatfielding.schema.yml +37 -0
  194. simtools/schemas/model_parameters/focal_length.schema.yml +45 -0
  195. simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +158 -0
  196. simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +29 -0
  197. simtools/schemas/model_parameters/focus_offset.schema.yml +66 -0
  198. simtools/schemas/model_parameters/gain_variation.schema.yml +43 -0
  199. simtools/schemas/model_parameters/geomag_horizontal.schema.yml +34 -0
  200. simtools/schemas/model_parameters/geomag_rotation.schema.yml +37 -0
  201. simtools/schemas/model_parameters/geomag_vertical.schema.yml +34 -0
  202. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +36 -0
  203. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +34 -0
  204. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +34 -0
  205. simtools/schemas/model_parameters/laser_events.schema.yml +36 -0
  206. simtools/schemas/model_parameters/laser_external_trigger.schema.yml +35 -0
  207. simtools/schemas/model_parameters/laser_photons.schema.yml +32 -0
  208. simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +34 -0
  209. simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +34 -0
  210. simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +33 -0
  211. simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +33 -0
  212. simtools/schemas/model_parameters/laser_var_photons.schema.yml +33 -0
  213. simtools/schemas/model_parameters/laser_wavelength.schema.yml +33 -0
  214. simtools/schemas/model_parameters/led_events.schema.yml +34 -0
  215. simtools/schemas/model_parameters/led_photons.schema.yml +34 -0
  216. simtools/schemas/model_parameters/led_pulse_offset.schema.yml +32 -0
  217. simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +33 -0
  218. simtools/schemas/model_parameters/led_var_photons.schema.yml +34 -0
  219. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +41 -0
  220. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +43 -0
  221. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +35 -0
  222. simtools/schemas/model_parameters/min_photons.schema.yml +32 -0
  223. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +36 -0
  224. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +64 -0
  225. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +64 -0
  226. simtools/schemas/model_parameters/mirror_class.schema.yml +41 -0
  227. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +51 -0
  228. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +42 -0
  229. simtools/schemas/model_parameters/mirror_list.schema.yml +38 -0
  230. simtools/schemas/model_parameters/mirror_offset.schema.yml +41 -0
  231. simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +39 -0
  232. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +61 -0
  233. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +40 -0
  234. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +46 -0
  235. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +51 -0
  236. simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +37 -0
  237. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +79 -0
  238. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +47 -0
  239. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +34 -0
  240. simtools/schemas/model_parameters/nsb_reference_value.schema.yml +33 -0
  241. simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +35 -0
  242. simtools/schemas/model_parameters/nsb_skymap.schema.yml +39 -0
  243. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +50 -0
  244. simtools/schemas/model_parameters/num_gains.schema.yml +34 -0
  245. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +33 -0
  246. simtools/schemas/model_parameters/optics_properties.schema.yml +31 -0
  247. simtools/schemas/model_parameters/parabolic_dish.schema.yml +32 -0
  248. simtools/schemas/model_parameters/pedestal_events.schema.yml +32 -0
  249. simtools/schemas/model_parameters/photon_delay.schema.yml +38 -0
  250. simtools/schemas/model_parameters/photons_per_run.schema.yml +33 -0
  251. simtools/schemas/model_parameters/pixel_cells.schema.yml +35 -0
  252. simtools/schemas/model_parameters/pixels_parallel.schema.yml +54 -0
  253. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +40 -0
  254. simtools/schemas/model_parameters/pm_average_gain.schema.yml +34 -0
  255. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +40 -0
  256. simtools/schemas/model_parameters/pm_gain_index.schema.yml +36 -0
  257. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +41 -0
  258. simtools/schemas/model_parameters/pm_transit_time.schema.yml +63 -0
  259. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +39 -0
  260. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +42 -0
  261. simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +33 -0
  262. simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +33 -0
  263. simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +29 -0
  264. simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +168 -0
  265. simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +36 -0
  266. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +34 -0
  267. simtools/schemas/model_parameters/qe_variation.schema.yml +43 -0
  268. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +42 -0
  269. simtools/schemas/model_parameters/random_focal_length.schema.yml +45 -0
  270. simtools/schemas/model_parameters/random_generator.schema.yml +36 -0
  271. simtools/schemas/model_parameters/reference_point_altitude.schema.yml +35 -0
  272. simtools/schemas/model_parameters/reference_point_latitude.schema.yml +36 -0
  273. simtools/schemas/model_parameters/reference_point_longitude.schema.yml +36 -0
  274. simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +34 -0
  275. simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +34 -0
  276. simtools/schemas/model_parameters/sampled_output.schema.yml +31 -0
  277. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +34 -0
  278. simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +79 -0
  279. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +42 -0
  280. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +41 -0
  281. simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +33 -0
  282. simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +36 -0
  283. simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +29 -0
  284. simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +168 -0
  285. simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +36 -0
  286. simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +35 -0
  287. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +37 -0
  288. simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +40 -0
  289. simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +40 -0
  290. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +41 -0
  291. simtools/schemas/model_parameters/tailcut_scale.schema.yml +40 -0
  292. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +31 -0
  293. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +35 -0
  294. simtools/schemas/model_parameters/telescope_random_error.schema.yml +34 -0
  295. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +37 -0
  296. simtools/schemas/model_parameters/telescope_transmission.schema.yml +113 -0
  297. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +41 -0
  298. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +36 -0
  299. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +36 -0
  300. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +37 -0
  301. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +38 -0
  302. simtools/schemas/model_parameters/transit_time_error.schema.yml +45 -0
  303. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +36 -0
  304. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +32 -0
  305. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +53 -0
  306. simtools/schemas/model_parameters/trigger_pixels.schema.yml +40 -0
  307. simtools/simtel/simtel_config_reader.py +353 -0
  308. simtools/simtel/simtel_config_writer.py +244 -63
  309. simtools/simtel/{simtel_events.py → simtel_io_events.py} +26 -25
  310. simtools/simtel/simtel_io_histogram.py +661 -0
  311. simtools/simtel/simtel_io_histograms.py +569 -0
  312. simtools/simtel/simulator_array.py +145 -0
  313. simtools/simtel/{simtel_runner_camera_efficiency.py → simulator_camera_efficiency.py} +76 -52
  314. simtools/simtel/simulator_light_emission.py +473 -0
  315. simtools/simtel/simulator_ray_tracing.py +262 -0
  316. simtools/simulator.py +220 -446
  317. simtools/testing/__init__.py +0 -0
  318. simtools/testing/assertions.py +151 -0
  319. simtools/testing/configuration.py +226 -0
  320. simtools/testing/helpers.py +42 -0
  321. simtools/testing/validate_output.py +240 -0
  322. simtools/utils/general.py +340 -437
  323. simtools/utils/geometry.py +12 -12
  324. simtools/utils/names.py +258 -644
  325. simtools/utils/value_conversion.py +176 -0
  326. simtools/version.py +2 -0
  327. simtools/visualization/legend_handlers.py +135 -152
  328. simtools/visualization/plot_camera.py +379 -0
  329. simtools/visualization/visualize.py +346 -167
  330. gammasimtools-0.6.1.dist-info/METADATA +0 -180
  331. gammasimtools-0.6.1.dist-info/RECORD +0 -91
  332. gammasimtools-0.6.1.dist-info/entry_points.txt +0 -23
  333. simtools/applications/db_development_tools/add_new_parameter_to_db.py +0 -81
  334. simtools/applications/db_development_tools/add_unit_to_parameter_in_db.py +0 -59
  335. simtools/applications/db_development_tools/mark_non_optics_parameters_non_applicable.py +0 -102
  336. simtools/applications/get_parameter.py +0 -92
  337. simtools/applications/make_regular_arrays.py +0 -160
  338. simtools/applications/produce_array_config.py +0 -136
  339. simtools/applications/production.py +0 -313
  340. simtools/applications/sim_showers_for_trigger_rates.py +0 -187
  341. simtools/applications/tune_psf.py +0 -334
  342. simtools/corsika/corsika_default_config.py +0 -282
  343. simtools/corsika/corsika_runner.py +0 -450
  344. simtools/corsika_simtel/corsika_simtel_runner.py +0 -197
  345. simtools/db_handler.py +0 -1480
  346. simtools/ray_tracing.py +0 -525
  347. simtools/simtel/simtel_histograms.py +0 -414
  348. simtools/simtel/simtel_runner.py +0 -244
  349. simtools/simtel/simtel_runner_array.py +0 -293
  350. simtools/simtel/simtel_runner_ray_tracing.py +0 -277
  351. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/LICENSE +0 -0
  352. {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/top_level.txt +0 -0
  353. /simtools/{corsika_simtel → db}/__init__.py +0 -0
@@ -1,44 +1,36 @@
1
+ """MC model of a telescope."""
2
+
1
3
  import logging
2
- import shutil
3
- from copy import copy
4
- from pydoc import locate
5
4
 
6
5
  import astropy.io.ascii
7
6
  import numpy as np
8
- from astropy import units as u
9
7
  from astropy.table import Table
10
8
 
11
9
  import simtools.utils.general as gen
12
- from simtools import db_handler
13
- from simtools.io_operations import io_handler
14
10
  from simtools.model.camera import Camera
15
11
  from simtools.model.mirrors import Mirrors
16
- from simtools.simtel.simtel_config_writer import SimtelConfigWriter
12
+ from simtools.model.model_parameter import InvalidModelParameterError, ModelParameter
17
13
  from simtools.utils import names
18
14
 
19
- __all__ = ["InvalidParameter", "TelescopeModel"]
20
-
21
-
22
- class InvalidParameter(Exception):
23
- """Exception for invalid parameter."""
15
+ __all__ = ["TelescopeModel"]
24
16
 
25
17
 
26
- class TelescopeModel:
18
+ class TelescopeModel(ModelParameter):
27
19
  """
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).
20
+ TelescopeModel represents the MC model of an individual telescope.
21
+
22
+ TelescopeModel contains parameter names and values for a specific telescope model.
31
23
 
32
24
  Parameters
33
25
  ----------
34
26
  site: str
35
- South or North.
36
- telescope_model_name: str
37
- Telescope name (ex. LST-1, ...).
27
+ Site name (e.g., South or North).
28
+ telescope_name: str
29
+ Telescope name (ex. LSTN-01, LSTN-design, ...).
38
30
  mongo_db_config: dict
39
31
  MongoDB configuration.
40
32
  model_version: str
41
- Version of the model (ex. prod5).
33
+ Model version.
42
34
  label: str
43
35
  Instance label. Important for output file naming.
44
36
  """
@@ -46,561 +38,42 @@ class TelescopeModel:
46
38
  def __init__(
47
39
  self,
48
40
  site,
49
- telescope_model_name,
50
- mongo_db_config=None,
51
- model_version="Released",
52
- db=None,
41
+ telescope_name,
42
+ mongo_db_config,
43
+ model_version,
53
44
  label=None,
54
45
  ):
55
- """
56
- Initialize TelescopeModel.
57
- """
46
+ """Initialize TelescopeModel."""
58
47
  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
48
+ self._logger.debug("Init TelescopeModel %s %s", site, telescope_name)
49
+ ModelParameter.__init__(
50
+ self,
51
+ site=site,
52
+ array_element_name=telescope_name,
53
+ mongo_db_config=mongo_db_config,
54
+ model_version=model_version,
55
+ db=None,
56
+ label=label,
57
+ )
58
+
67
59
  self._single_mirror_list_file_paths = None
68
- self.simtel_config_writer = None
69
60
  self._mirrors = None
70
- self._reference_data = None
71
- self._derived = None
72
61
  self._camera = None
73
62
 
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
63
  @property
91
64
  def mirrors(self):
92
- """
93
- Load the mirror information if the class instance hasn't done it yet.
94
- """
65
+ """Load the mirror information if the class instance hasn't done it yet."""
95
66
  if self._mirrors is None:
96
67
  self._load_mirrors()
97
68
  return self._mirrors
98
69
 
99
70
  @property
100
71
  def camera(self):
101
- """
102
- Load the camera information if the class instance hasn't done it yet.
103
- """
72
+ """Load the camera information if the class instance hasn't done it yet."""
104
73
  if self._camera is None:
105
74
  self._load_camera()
106
75
  return self._camera
107
76
 
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
77
  def export_single_mirror_list_file(self, mirror_number, set_focal_length_to_zero):
605
78
  """
606
79
  Export a mirror list file with a single mirror in it.
@@ -621,7 +94,7 @@ class TelescopeModel:
621
94
  )
622
95
  if self._single_mirror_list_file_paths is None:
623
96
  self._single_mirror_list_file_paths = {}
624
- self._single_mirror_list_file_paths[mirror_number] = self._config_file_directory.joinpath(
97
+ self._single_mirror_list_file_paths[mirror_number] = self.config_file_directory.joinpath(
625
98
  file_name
626
99
  )
627
100
 
@@ -655,46 +128,69 @@ class TelescopeModel:
655
128
 
656
129
  def _load_mirrors(self):
657
130
  """Load the attribute mirrors by creating a Mirrors object with the mirror list file."""
658
- mirror_list_file_name = self._parameters["mirror_list"]["Value"]
131
+ mirror_list_file_name = self.get_parameter_value("mirror_list")
132
+ self._logger.debug(f"Reading mirror list from {mirror_list_file_name}")
659
133
  try:
660
- mirror_list_file = gen.find_file(mirror_list_file_name, self._config_file_directory)
134
+ mirror_list_file = gen.find_file(mirror_list_file_name, self.config_file_directory)
661
135
  except FileNotFoundError:
662
136
  mirror_list_file = gen.find_file(mirror_list_file_name, self.io_handler.model_path)
663
137
  self._logger.warning(
664
138
  "Mirror_list_file was not found in the config directory - "
665
139
  "Using the one found in the model_path"
666
140
  )
141
+ except TypeError as exc:
142
+ raise TypeError("Undefined mirror list") from exc
143
+
667
144
  self._mirrors = Mirrors(mirror_list_file, parameters=self._parameters)
668
145
 
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
- )
146
+ def get_telescope_effective_focal_length(self, unit="m", return_focal_length_if_zero=False):
147
+ """
148
+ Return effective focal length.
675
149
 
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
- )
150
+ The function ensures backwards compatibility with older sim-telarray versions.
151
+
152
+ Parameters
153
+ ----------
154
+ unit: str
155
+ Unit of the effective focal length. Default is 'm'.
156
+ return_focal_length_if_zero: bool
157
+ If True, return the focal length if the effective focal length is 0.
158
+
159
+ Returns
160
+ -------
161
+ float:
162
+ Effective focal length.
163
+
164
+ """
165
+ try:
166
+ eff_focal_length = self.get_parameter_value_with_unit("effective_focal_length")[0]
167
+ except TypeError:
168
+ eff_focal_length = self.get_parameter_value_with_unit("effective_focal_length")
169
+ try:
170
+ eff_focal_length = eff_focal_length.to(unit).value
171
+ except AttributeError:
172
+ eff_focal_length = 0.0
173
+ if return_focal_length_if_zero and (eff_focal_length is None or eff_focal_length == 0.0):
174
+ self._logger.warning("Using focal_length because effective_focal_length is 0")
175
+ return self.get_parameter_value_with_unit("focal_length").to(unit).value
176
+ return eff_focal_length
684
177
 
685
178
  def _load_camera(self):
686
- """Loading camera attribute by creating a Camera object with the camera config file."""
179
+ """Load camera attribute by creating a Camera object with the camera config file."""
687
180
  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")
181
+ focal_length = self.get_telescope_effective_focal_length("cm", True)
692
182
  try:
693
- camera_config_file_path = gen.find_file(camera_config_file, self._config_file_directory)
183
+ camera_config_file_path = gen.find_file(camera_config_file, self.config_file_directory)
184
+ except TypeError as exc:
185
+ self._logger.error(
186
+ f"Camera config file {camera_config_file} or "
187
+ f"config file directory ({self.config_file_directory}) is None"
188
+ )
189
+ raise TypeError from exc
694
190
  except FileNotFoundError:
695
191
  self._logger.warning(
696
- "The camera_config_file was not found in the config directory - "
697
- "Using the one found in the model_path"
192
+ f"Camera config file {camera_config_file} not found in the config directory "
193
+ f"{self.config_file_directory}. Using the one found in the model_path"
698
194
  )
699
195
  camera_config_file_path = gen.find_file(camera_config_file, self.io_handler.model_path)
700
196
 
@@ -704,19 +200,6 @@ class TelescopeModel:
704
200
  focal_length=focal_length,
705
201
  )
706
202
 
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
203
  def is_file_2d(self, par):
721
204
  """
722
205
  Check if the file referenced by par is a 2D table.
@@ -731,21 +214,22 @@ class TelescopeModel:
731
214
  bool:
732
215
  True if the file is a 2D map type, False otherwise.
733
216
  """
734
- if not self.has_parameter(par):
217
+ try:
218
+ file_name = self.get_parameter_value(par)
219
+ except KeyError:
735
220
  logging.error(f"Parameter {par} does not exist")
736
221
  return False
737
222
 
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
223
+ file = self.config_file_directory.joinpath(file_name)
224
+ with open(file, encoding="utf-8") as f:
225
+ return "@RPOL@" in f.read()
743
226
 
744
227
  def read_two_dim_wavelength_angle(self, file_name):
745
228
  """
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.)
229
+ Read a two dimensional distribution of wavelength and angle (z-axis can be anything).
230
+
231
+ Return a dictionary with three arrays, wavelength, angles, z (can be transmission,
232
+ reflectivity, etc.)
749
233
 
750
234
  Parameters
751
235
  ----------
@@ -757,10 +241,10 @@ class TelescopeModel:
757
241
  dict:
758
242
  dict of three arrays, wavelength, degrees, z.
759
243
  """
760
-
761
- _file = self.get_config_directory().joinpath(file_name)
244
+ _file = self.config_file_directory.joinpath(file_name)
245
+ self._logger.debug("Reading two dimensional distribution from %s", _file)
762
246
  line_to_start_from = 0
763
- with open(_file, "r", encoding="utf-8") as f:
247
+ with open(_file, encoding="utf-8") as f:
764
248
  for i_line, line in enumerate(f):
765
249
  if line.startswith("ANGLE"):
766
250
  degrees = np.array(line.strip().split("=")[1].split(), dtype=np.float16)
@@ -777,14 +261,13 @@ class TelescopeModel:
777
261
 
778
262
  def get_on_axis_eff_optical_area(self):
779
263
  """Return the on-axis effective optical area (derived previously for this telescope)."""
780
-
781
264
  ray_tracing_data = astropy.io.ascii.read(
782
- self.get_derived_directory().joinpath(self.derived["ray_tracing"]["Value"])
265
+ self.config_file_directory.joinpath(self.get_parameter_value("optics_properties"))
783
266
  )
784
267
  if not np.isclose(ray_tracing_data["Off-axis angle"][0], 0):
785
268
  self._logger.error(
786
269
  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]}"
270
+ f" The minimum off-axis angle is {ray_tracing_data['Off-axis angle'][0]}"
788
271
  )
789
272
  raise ValueError
790
273
  return ray_tracing_data["eff_area"][0]
@@ -803,17 +286,19 @@ class TelescopeModel:
803
286
  incidence_angle_dist: astropy.table.Table
804
287
  Instance of astropy.table.Table with the incidence angle distribution.
805
288
  """
806
-
807
- incidence_angle_dist = astropy.io.ascii.read(
808
- self.get_derived_directory().joinpath(incidence_angle_dist_file)
289
+ self._logger.debug(
290
+ "Reading incidence angle distribution from %s",
291
+ self.config_file_directory.joinpath(incidence_angle_dist_file),
809
292
  )
810
- return incidence_angle_dist
293
+ return astropy.io.ascii.read(self.config_file_directory.joinpath(incidence_angle_dist_file))
811
294
 
812
295
  @staticmethod
813
296
  def calc_average_curve(curves, incidence_angle_dist):
814
297
  """
815
- Calculate an average curve from a set of curves, using as weights the distribution of \
816
- incidence angles provided in incidence_angle_dist.
298
+ Calculate an average curve from a set of curves.
299
+
300
+ The calculation uses weights the distribution of incidence angles provided in
301
+ incidence_angle_dist.
817
302
 
818
303
  Parameters
819
304
  ----------
@@ -830,7 +315,6 @@ class TelescopeModel:
830
315
  average_curve: astropy.table.Table
831
316
  Instance of astropy.table.Table with the averaged curve.
832
317
  """
833
-
834
318
  weights = []
835
319
  for angle_now in curves["Angle"]:
836
320
  weights.append(
@@ -839,13 +323,11 @@ class TelescopeModel:
839
323
  ]
840
324
  )
841
325
 
842
- average_curve = Table(
326
+ return Table(
843
327
  [curves["Wavelength"], np.average(curves["z"], weights=weights, axis=0)],
844
328
  names=("Wavelength", "z"),
845
329
  )
846
330
 
847
- return average_curve
848
-
849
331
  def export_table_to_model_directory(self, file_name, table):
850
332
  """
851
333
  Write out a file with the provided table to the model directory.
@@ -862,7 +344,31 @@ class TelescopeModel:
862
344
  Path:
863
345
  Path to the file exported.
864
346
  """
865
-
866
- file_to_write_to = self._config_file_directory.joinpath(file_name)
347
+ file_to_write_to = self.config_file_directory.joinpath(file_name)
867
348
  table.write(file_to_write_to, format="ascii.commented_header", overwrite=True)
868
349
  return file_to_write_to.absolute()
350
+
351
+ def position(self, coordinate_system="ground"):
352
+ """
353
+ Get coordinates in the given system.
354
+
355
+ Parameters
356
+ ----------
357
+ coordinate_system: str
358
+ Coordinates system. Default is 'ground'.
359
+
360
+ Returns
361
+ -------
362
+ list :
363
+ List of telescope position in the requested coordinate system.
364
+
365
+ Raises
366
+ ------
367
+ KeyError
368
+ If the coordinate system is not found.
369
+ """
370
+ try:
371
+ return self.get_parameter_value_with_unit(f"array_element_position_{coordinate_system}")
372
+ except InvalidModelParameterError as exc:
373
+ self._logger.error(f"Coordinate system {coordinate_system} not found.")
374
+ raise exc