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
@@ -0,0 +1,661 @@
1
+ """
2
+ Reads the content of either a single histogram (.hdata) or a single simtel_array output (.simtel).
3
+
4
+ Files can be zst compressed.
5
+ """
6
+
7
+ import copy
8
+ import logging
9
+ from pathlib import Path
10
+
11
+ import numpy as np
12
+ from astropy import units as u
13
+ from astropy.table import QTable
14
+ from ctao_cr_spectra.definitions import IRFDOC_PROTON_SPECTRUM
15
+ from ctao_cr_spectra.spectral import cone_solid_angle
16
+ from eventio import EventIOFile, Histograms
17
+ from eventio.search_utils import yield_toplevel_of_type
18
+ from eventio.simtel import MCRunHeader
19
+
20
+ __all__ = [
21
+ "HistogramIdNotFoundError",
22
+ "InconsistentHistogramFormatError",
23
+ "SimtelIOHistogram",
24
+ ]
25
+
26
+
27
+ class InconsistentHistogramFormatError(Exception):
28
+ """Exception for bad histogram format."""
29
+
30
+
31
+ class HistogramIdNotFoundError(Exception):
32
+ """Exception for histogram ID not found."""
33
+
34
+
35
+ class SimtelIOHistogram:
36
+ """
37
+ Reads and generates histograms from sim_telarray output.
38
+
39
+ Read the content of either a single histogram (.hdata, or .hdata.zst) or a single simtel_array
40
+ output file (.simtel or .simtel.zst).
41
+
42
+ Parameters
43
+ ----------
44
+ histogram_file: str
45
+ The histogram (.hdata.zst) or simtel_array (.simtel.zst) file.
46
+ area_from_distribution: bool
47
+ If true, the area thrown (the area in which the simulated events are distributed)
48
+ in the trigger rate calculation is estimated based on the event distribution.
49
+ The expected shape of the distribution of events as function of the core distance is
50
+ triangular up to the maximum distance. The weighted mean radius of the triangular
51
+ distribution is 2/3 times the upper edge. Therefore, when using the
52
+ ``area_from_distribution`` flag, the mean distance times 3/2, returns just the position of
53
+ the upper edge in the triangle distribution with little impact of the binning and little
54
+ dependence on the scatter area defined in the simulation. This is special useful when
55
+ calculating trigger rate for individual telescopes.
56
+ If false, the area thrown is estimated based on the maximum distance as given in
57
+ the simulation configuration.
58
+ energy_range: list
59
+ The energy range used in the simulation. It must be passed as a list of floats and the
60
+ energy must be in TeV.
61
+ This argument is only needed and used if histogram_file is a .hdata file, in which case the
62
+ energy range cannot be retrieved directly from the file.
63
+ view_cone: list
64
+ The view cone used in the simulation. It must be passed as a list of floats and the
65
+ view cone must be in deg.
66
+ This argument is only needed and used if histogram_file is a .hdata file, in which case the
67
+ view cone cannot be retrieved directly from the file.
68
+ """
69
+
70
+ def __init__(
71
+ self, histogram_file, area_from_distribution=False, energy_range=None, view_cone=None
72
+ ):
73
+ """Initialize SimtelIOHistogram class."""
74
+ self._logger = logging.getLogger(__name__)
75
+ self.histogram_file = histogram_file
76
+ if not Path(histogram_file).exists():
77
+ msg = f"File {histogram_file} does not exist."
78
+ self._logger.error(msg)
79
+ raise FileNotFoundError
80
+
81
+ self._config = None
82
+ self._total_area = None
83
+ self._solid_angle = None
84
+ self._total_num_simulated_events = None
85
+ self._total_num_triggered_events = None
86
+ self._histogram = None
87
+ self._initialize_histogram()
88
+ self.trigger_rate = None
89
+ self.trigger_rate_uncertainty = None
90
+ self.trigger_rate_per_energy_bin = None
91
+ self.energy_axis = None
92
+ self.radius_axis = None
93
+ self.area_from_distribution = area_from_distribution
94
+
95
+ self._set_view_cone(view_cone)
96
+ self._set_energy_range(energy_range)
97
+
98
+ def _initialize_histogram(self):
99
+ """
100
+ Initialize lists of histograms and files.
101
+
102
+ Returns
103
+ -------
104
+ list:
105
+ List of histograms.
106
+ """
107
+ with EventIOFile(self.histogram_file) as f:
108
+ for obj in yield_toplevel_of_type(f, Histograms):
109
+ self.histogram = obj.parse()
110
+
111
+ @property
112
+ def number_of_histogram_types(self):
113
+ """Return number of histograms."""
114
+ return len(self.histogram)
115
+
116
+ def get_histogram_type_title(self, histogram_index):
117
+ """
118
+ Return the title of the histogram with index histogram_index.
119
+
120
+ Parameters
121
+ ----------
122
+ histogram_index: int
123
+ Histogram index.
124
+
125
+ Returns
126
+ -------
127
+ str
128
+ Histogram title.
129
+ """
130
+ return self.histogram[histogram_index]["title"]
131
+
132
+ @property
133
+ def config(self):
134
+ """
135
+ Return information about the input parameters for the simulation.
136
+
137
+ Returns
138
+ -------
139
+ dict:
140
+ dictionary with information about the simulation (pyeventio MCRunHeader object).
141
+ """
142
+ if self._config is None:
143
+ # If the file is a .hdata or .hdata.zst, config will continue to be None.
144
+ with EventIOFile(self.histogram_file) as f:
145
+ # Try to find configuration from .simtel file. If .hdata, config will be None
146
+ for obj in f:
147
+ if isinstance(obj, MCRunHeader):
148
+ self._config = obj.parse()
149
+
150
+ return self._config
151
+
152
+ @property
153
+ def total_num_simulated_events(self):
154
+ """
155
+ Return the total number of simulated events the histograms.
156
+
157
+ Returns
158
+ -------
159
+ int:
160
+ total number of simulated events.
161
+ """
162
+ if self._total_num_simulated_events is None:
163
+ events_histogram, _ = self.fill_event_histogram_dicts()
164
+ self._total_num_simulated_events = np.sum(events_histogram["data"])
165
+ logging.debug(f"Number of total simulated showers: {self._total_num_simulated_events}")
166
+ return self._total_num_simulated_events
167
+
168
+ @property
169
+ def total_num_triggered_events(self):
170
+ """
171
+ Returns the total number of triggered events.
172
+
173
+ Please note that this value is not supposed to match the trigger rate x estimated
174
+ observation time, as the simulation is optimized for computational time and the energy
175
+ distribution assumed is not necessarily the reference cosmic-ray spectra.
176
+
177
+ Returns
178
+ -------
179
+ int:
180
+ total number of simulated events.
181
+ """
182
+ if self._total_num_triggered_events is None:
183
+ _, trigger_histogram = self.fill_event_histogram_dicts()
184
+ self._total_num_triggered_events = np.sum(trigger_histogram["data"])
185
+ logging.debug(f"Number of total triggered showers: {self._total_num_triggered_events}")
186
+ return self._total_num_triggered_events
187
+
188
+ def fill_event_histogram_dicts(self):
189
+ """
190
+ Get data from the total simulated event and the triggered event histograms.
191
+
192
+ Returns
193
+ -------
194
+ dict:
195
+ Information about the histograms with simulated events.
196
+ dict:
197
+ Information about the histograms with triggered events.
198
+
199
+ Raises
200
+ ------
201
+ HistogramIdNotFoundError:
202
+ if histogram ids not found. Problem with the file.
203
+ """
204
+ # Save the appropriate histograms to variables
205
+ found_simulated_events_hist = False
206
+ found_triggered_events_hist = False
207
+ events_histogram = None
208
+ triggered_events_histogram = None
209
+ for hist in self.histogram:
210
+ if hist["id"] == 1:
211
+ events_histogram = hist
212
+ found_simulated_events_hist = True
213
+ elif hist["id"] == 2:
214
+ triggered_events_histogram = hist
215
+ found_triggered_events_hist = True
216
+ if found_simulated_events_hist * found_triggered_events_hist:
217
+ if "triggered_events_histogram" in locals():
218
+ return events_histogram, triggered_events_histogram
219
+ msg = "Histograms ids not found. Please check your files."
220
+
221
+ self._logger.error(msg)
222
+ raise HistogramIdNotFoundError
223
+
224
+ def _set_view_cone(self, view_cone):
225
+ """
226
+ View cone used in the simulation.
227
+
228
+ Parameters
229
+ ----------
230
+ view_cone: list
231
+ The view cone used in the simulation. It must be passed as a list of floats and the
232
+ view cone must be in deg (as in the CORSIKA configuration).
233
+
234
+ Raises
235
+ ------
236
+ ValueError:
237
+ if input parameter is missing.
238
+ """
239
+ if view_cone is None:
240
+ try:
241
+ self.view_cone = self.config["viewcone"] * u.deg
242
+ except TypeError as exc:
243
+ msg = (
244
+ "view_cone needs to be passed as argument (minimum and maximum of the "
245
+ "view cone radius in deg)."
246
+ )
247
+ self._logger.error(msg)
248
+ raise ValueError(msg) from exc
249
+ else:
250
+ if isinstance(view_cone, u.Quantity):
251
+ self.view_cone = view_cone.to(u.deg)
252
+ else:
253
+ self.view_cone = view_cone * u.deg
254
+
255
+ @property
256
+ def solid_angle(self):
257
+ """
258
+ Solid angle corresponding to the view cone.
259
+
260
+ Returns
261
+ -------
262
+ astropy.Quantity[u.sr]:
263
+ Solid angle corresponding to the view cone.
264
+ """
265
+ if self._solid_angle is None:
266
+ self._solid_angle = cone_solid_angle(self.view_cone[1]) - cone_solid_angle(
267
+ self.view_cone[0]
268
+ )
269
+ return self._solid_angle
270
+
271
+ @property
272
+ def total_area(self):
273
+ """
274
+ Total area covered by the simulated events (original CORSIKA CSCAT), i.e., area thrown.
275
+
276
+ Returns
277
+ -------
278
+ astropy.Quantity[area]:
279
+ Total area covered on the ground covered by the simulation.
280
+ """
281
+ if self._total_area is None:
282
+ events_histogram, _ = self.fill_event_histogram_dicts()
283
+ self._initialize_histogram_axes(events_histogram)
284
+
285
+ if self.area_from_distribution is True:
286
+ area_from_distribution_max_radius = 1.5 * np.average(
287
+ self.radius_axis[:-1], weights=np.sum(events_histogram["data"], axis=0)
288
+ )
289
+ self._total_area = (np.pi * (area_from_distribution_max_radius * u.m) ** 2).to(
290
+ u.cm**2
291
+ )
292
+ else:
293
+ # The max of the core range is always half the upper edge:
294
+ # self.radius_axis[-1]/2 is equal to self.config["core_range"][1]
295
+ self._total_area = (
296
+ np.pi * (((self.radius_axis[-1] / 2 - self.radius_axis[0]) * u.m).to(u.cm)) ** 2
297
+ )
298
+ return self._total_area
299
+
300
+ def _set_energy_range(self, energy_range):
301
+ """
302
+ Set energy range to be used in the simulations.
303
+
304
+ Parameters
305
+ ----------
306
+ energy_range: list
307
+ The energy range used in the simulation. It must be passed as a list of floats and the
308
+ energy must be in TeV.
309
+
310
+ Raises
311
+ ------
312
+ ValueError:
313
+ if input parameter is missing.
314
+ """
315
+ if energy_range is None:
316
+ try:
317
+ self.energy_range = [
318
+ self.config["E_range"][0] * u.TeV,
319
+ self.config["E_range"][1] * u.TeV,
320
+ ]
321
+ except TypeError as exc: # E_range not in self.config
322
+ msg = (
323
+ "energy_range needs to be passed as argument (minimum and maximum"
324
+ " energies in TeV)."
325
+ )
326
+ self._logger.error(msg)
327
+ raise ValueError(msg) from exc
328
+ else:
329
+ if isinstance(energy_range, u.Quantity):
330
+ self.energy_range = energy_range.to(u.TeV)
331
+ else:
332
+ self.energy_range = energy_range * u.TeV
333
+
334
+ @staticmethod
335
+ def _produce_triggered_to_sim_fraction_hist(events_histogram, triggered_events_histogram):
336
+ """
337
+ Produce a new histogram with the fraction of triggered events over the simulated events.
338
+
339
+ The dimension of the histogram is reduced, as the rates are summed for all the bins in
340
+ impact distance.
341
+
342
+ Parameters
343
+ ----------
344
+ events_histogram:
345
+ A dictionary with "data" corresponding to a 2D histogram (impact distance x energy)
346
+ for the simulated events.
347
+ triggered_events_histogram:
348
+ A dictionary with "data" corresponding to a 2D histogram (impact distance x energy)
349
+ for the triggered events.
350
+
351
+ Returns
352
+ -------
353
+ event_ratio_histogram:
354
+ The new histogram with the fraction of triggered over simulated events.
355
+ """
356
+ simulated_events_per_energy_bin = np.sum(events_histogram["data"], axis=1)
357
+
358
+ triggered_events_per_energy_bin = np.sum(triggered_events_histogram["data"], axis=1)
359
+ ratio_per_energy_bin = np.zeros_like(triggered_events_per_energy_bin, dtype=float)
360
+
361
+ non_zero_indices = np.nonzero(simulated_events_per_energy_bin)[0]
362
+ ratio_per_energy_bin[non_zero_indices] = (
363
+ triggered_events_per_energy_bin[non_zero_indices]
364
+ / simulated_events_per_energy_bin[non_zero_indices]
365
+ )
366
+ return ratio_per_energy_bin
367
+
368
+ def compute_system_trigger_rate(self, events_histogram=None, triggered_events_histogram=None):
369
+ """
370
+ Compute the system trigger rate and its uncertainty, which are saved as class attributes.
371
+
372
+ If events_histogram and triggered_events_histogram are passed, they are used to calculate
373
+ the trigger rate and trigger rate uncertainty, instead of the histograms from the file.
374
+ This is specially useful when calculating the trigger rate for stacked files, in which case
375
+ one can pass the histograms resulted from stacking the files to this function.
376
+ Default is filling from the file.
377
+
378
+ Parameters
379
+ ----------
380
+ events_histogram:
381
+ A dictionary with "data" corresponding to a 2D histogram (core distance x energy)
382
+ for the simulated events.
383
+ triggered_events_histogram:
384
+ A dictionary with "data" corresponding to a 2D histogram (core distance x energy)
385
+ for the triggered events.
386
+ """
387
+ if self.trigger_rate is None:
388
+ # Get the simulated and triggered 2D histograms from the simtel_array output file
389
+ if events_histogram is None and triggered_events_histogram is None:
390
+ events_histogram, triggered_events_histogram = self.fill_event_histogram_dicts()
391
+ # Calculate triggered/simulated event 1D histogram (energy dependent)
392
+ triggered_to_sim_fraction_hist = self._produce_triggered_to_sim_fraction_hist(
393
+ events_histogram, triggered_events_histogram
394
+ )
395
+ self._initialize_histogram_axes(triggered_events_histogram)
396
+
397
+ # Getting the particle distribution function according to the reference
398
+ particle_distribution_function = self.get_particle_distribution_function(
399
+ label="reference"
400
+ )
401
+
402
+ # Integrating the flux between the consecutive energy bins. The result given in
403
+ # cm-2s-1sr-1
404
+ flux_per_energy_bin = self._integrate_in_energy_bin(
405
+ particle_distribution_function, self.energy_axis
406
+ )
407
+
408
+ # Derive the trigger rate per energy bin
409
+ self.trigger_rate_per_energy_bin = (
410
+ triggered_to_sim_fraction_hist
411
+ * flux_per_energy_bin
412
+ * self.total_area
413
+ * self.solid_angle
414
+ ).decompose()
415
+
416
+ # Derive the system trigger rate
417
+ self.trigger_rate = np.sum(self.trigger_rate_per_energy_bin)
418
+
419
+ # Derive the uncertainty in the system trigger rate estimate
420
+ self.trigger_rate_uncertainty = self.estimate_trigger_rate_uncertainty(
421
+ self.trigger_rate,
422
+ np.sum(events_histogram["data"]),
423
+ np.sum(triggered_events_histogram["data"]),
424
+ )
425
+
426
+ return self.trigger_rate, self.trigger_rate_uncertainty
427
+
428
+ def trigger_info_in_table(self):
429
+ """
430
+ Provide the trigger rate per energy bin in tabulated form.
431
+
432
+ Returns
433
+ -------
434
+ astropy.QTable:
435
+ The QTable instance with the trigger rate per energy bin.
436
+ """
437
+ meta = self.produce_trigger_meta_data()
438
+ return QTable(
439
+ [self.energy_axis[:-1] * u.TeV, (self.trigger_rate_per_energy_bin.to(u.Hz))],
440
+ names=("Energy (TeV)", "Trigger rate (Hz)"),
441
+ meta=meta,
442
+ )
443
+
444
+ def produce_trigger_meta_data(self):
445
+ """
446
+ Produce the meta data to include in the tabulated form of the trigger rate per energy bin.
447
+
448
+ It shows some information from the input file (simtel_array file) and the final estimate
449
+ system trigger rate.
450
+
451
+ Returns
452
+ -------
453
+ dict:
454
+ dictionary with the metadata.
455
+ """
456
+ return {
457
+ "simtel_array_file": self.histogram_file,
458
+ "simulation_input": self.print_info(mode="silent"),
459
+ # pylint: disable=E1101
460
+ "system_trigger_rate (Hz)": self.trigger_rate.value,
461
+ }
462
+
463
+ def _integrate_in_energy_bin(self, particle_distribution_function, energy_axis):
464
+ """
465
+ Integrate the particle distribution.
466
+
467
+ The function integrates between the consecutive energy bins given by the energy_axis array.
468
+
469
+ Parameters
470
+ ----------
471
+ particle_distribution_function: ctao_cr_spectra.spectral.PowerLaw
472
+ The function describing the spectral distribution.
473
+ energy_axis: numpy.array
474
+ The array with the simulated particle energies.
475
+
476
+ Returns
477
+ -------
478
+ astropy.Quantity:
479
+ astropy.Quantity of a numpy array with the energy integrated flux.
480
+ """
481
+ unit = None
482
+ flux_per_energy_bin = []
483
+ for i_energy, _ in enumerate(energy_axis[:-1]):
484
+ integrated_flux = particle_distribution_function.integrate_energy(
485
+ energy_axis[i_energy] * u.TeV, energy_axis[i_energy + 1] * u.TeV
486
+ ).decompose(bases=[u.s, u.cm, u.sr])
487
+ if unit is None:
488
+ unit = integrated_flux.unit
489
+
490
+ flux_per_energy_bin.append(integrated_flux.value)
491
+
492
+ return np.array(flux_per_energy_bin) * unit
493
+
494
+ def _initialize_histogram_axes(self, events_histogram):
495
+ """
496
+ Initialize the two axes of a histogram.
497
+
498
+ The two axes are: the array with the edges of the bins in core
499
+ distance and the edges of the array with the energy bins.
500
+
501
+ Parameters
502
+ ----------
503
+ events_histogram:
504
+ A single histogram from where to extract axis information.
505
+ """
506
+ self.radius_axis = np.linspace(
507
+ events_histogram["lower_x"],
508
+ events_histogram["upper_x"],
509
+ events_histogram["n_bins_x"] + 1,
510
+ endpoint=True,
511
+ )
512
+
513
+ self.energy_axis = np.logspace(
514
+ events_histogram["lower_y"],
515
+ events_histogram["upper_y"],
516
+ events_histogram["n_bins_y"] + 1,
517
+ endpoint=True,
518
+ )
519
+
520
+ def get_particle_distribution_function(self, label="reference"):
521
+ """
522
+ Get the particle distribution function.
523
+
524
+ This depends on whether one wants the reference CR distribution or the distribution
525
+ used in the simulation. This is controlled by label.
526
+ By using label="reference", one gets the distribution function according to a pre-defined CR
527
+ distribution, while by using label="simulation", the spectral index of the distribution
528
+ function from the simulation is used. Naturally, label="simulation" only works when the
529
+ input file is a .simtel file and not a .hdata file.
530
+
531
+ Parameters
532
+ ----------
533
+ label: str
534
+ label defining which distribution function. Possible values are: "reference", or
535
+ "simulation".
536
+
537
+ Returns
538
+ -------
539
+ ctao_cr_spectra.spectral.PowerLaw
540
+ The function describing the spectral distribution.
541
+ """
542
+ if label == "reference":
543
+ particle_distribution_function = copy.copy(IRFDOC_PROTON_SPECTRUM)
544
+ elif label == "simulation":
545
+ particle_distribution_function = self._get_simulation_spectral_distribution_function()
546
+ else:
547
+ msg = f"label {label} is not valid. Please use either 'reference' or 'simulation'."
548
+ self._logger.error(msg)
549
+ raise ValueError(msg)
550
+ return particle_distribution_function
551
+
552
+ def _get_simulation_spectral_distribution_function(self):
553
+ """
554
+ Get the simulation particle energy distribution according to its configuration.
555
+
556
+ Returns
557
+ -------
558
+ ctao_cr_spectra.spectral.PowerLaw
559
+ The function describing the spectral distribution.
560
+
561
+ Raises
562
+ ------
563
+ ValueError:
564
+ if input parameter is missing.
565
+ """
566
+ spectral_distribution = copy.copy(IRFDOC_PROTON_SPECTRUM)
567
+ try:
568
+ spectral_distribution.index = self.config["spectral_index"]
569
+ except TypeError as exc:
570
+ msg = (
571
+ "spectral_index not found in the configuration of the file. "
572
+ "Consider using a .simtel file instead."
573
+ )
574
+ self._logger.error(msg)
575
+ raise ValueError(msg) from exc
576
+ return spectral_distribution
577
+
578
+ def estimate_observation_time(self, stacked_num_simulated_events=None):
579
+ """
580
+ Estimates the observation time corresponding to the simulated number of events.
581
+
582
+ It uses the CTAO reference cosmic-ray spectra, the total number of particles simulated,
583
+ and other information from the simulation configuration self.config.
584
+ If stacked_num_simulated_events is given, the observation time is estimated from it instead
585
+ of from the simulation configuration (useful for the stacked trigger rate estimate).
586
+
587
+ Parameters
588
+ ----------
589
+ stacked_num_simulated_events: int
590
+ total number of simulated events for the stacked dataset.
591
+
592
+ Returns
593
+ -------
594
+ astropy.Quantity[time]
595
+ Estimated observation time based on the total number of particles simulated.
596
+ """
597
+ first_estimate = IRFDOC_PROTON_SPECTRUM.compute_number_events(
598
+ self.view_cone[0],
599
+ self.view_cone[1],
600
+ 1 * u.s,
601
+ self.total_area,
602
+ self.energy_range[0],
603
+ self.energy_range[1],
604
+ )
605
+ if stacked_num_simulated_events is None:
606
+ return (self.total_num_simulated_events / first_estimate) * u.s
607
+ return (stacked_num_simulated_events / first_estimate) * u.s
608
+
609
+ def estimate_trigger_rate_uncertainty(
610
+ self, trigger_rate_estimate, num_simulated_events, num_triggered_events
611
+ ):
612
+ """
613
+ Estimate the trigger rate uncertainty.
614
+
615
+ The calculation is based on the number of simulated and triggered events.
616
+ Poisson statistics are assumed. The uncertainty is calculated based on propagation
617
+ of the individual uncertainties.
618
+ If stacked_num_simulated_events is passed, the uncertainty is estimated based on it instead
619
+ of based on the total number of trigger events from the simulation configuration
620
+ (useful for the stacked trigger rate estimate).
621
+
622
+ Parameters
623
+ ----------
624
+ trigger_rate_estimate: astropy.Quantity[1/time]
625
+ The already estimated the trigger rate.
626
+ num_simulated_events: int
627
+ Total number of simulated events.
628
+ num_triggered_events: int
629
+ Total number of triggered events.
630
+
631
+ Returns
632
+ -------
633
+ astropy.Quantity[1/time]
634
+ Uncertainty in the trigger rate estimate.
635
+ """
636
+ # pylint: disable=E1101
637
+ return (
638
+ trigger_rate_estimate.value
639
+ * np.sqrt(1 / num_triggered_events + 1 / num_simulated_events)
640
+ ) * trigger_rate_estimate.unit
641
+
642
+ def print_info(self, mode=None):
643
+ """
644
+ Print information on the geometry and input parameters.
645
+
646
+ Returns
647
+ -------
648
+ dict:
649
+ Dictionary with the information, e.g., view angle, energy range, etc.
650
+ """
651
+ info_dict = {
652
+ "view_cone": self.view_cone,
653
+ "solid_angle": self.solid_angle,
654
+ "total_area": self.total_area,
655
+ "energy_range": self.energy_range,
656
+ "total_num_simulated_events": self.total_num_simulated_events,
657
+ "total_num_triggered_events": self.total_num_triggered_events,
658
+ }
659
+ if mode != "silent":
660
+ print(info_dict)
661
+ return info_dict