gammasimtools 0.15.0__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/METADATA +2 -32
  2. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/RECORD +222 -214
  3. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/entry_points.txt +5 -2
  5. simtools/_version.py +2 -2
  6. simtools/applications/calculate_trigger_rate.py +10 -10
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +16 -16
  8. simtools/applications/convert_model_parameter_from_simtel.py +1 -1
  9. simtools/applications/derive_psf_parameters.py +12 -9
  10. simtools/applications/docs_produce_array_element_report.py +3 -3
  11. simtools/applications/docs_produce_calibration_reports.py +49 -0
  12. simtools/applications/docs_produce_simulation_configuration_report.py +50 -0
  13. simtools/applications/{generate_simtel_array_histograms.py → generate_sim_telarray_histograms.py} +2 -2
  14. simtools/applications/production_derive_corsika_limits.py +63 -10
  15. simtools/applications/production_derive_statistics.py +125 -0
  16. simtools/applications/production_generate_grid.py +197 -0
  17. simtools/applications/production_generate_simulation_config.py +0 -10
  18. simtools/applications/simulate_light_emission.py +5 -13
  19. simtools/applications/simulate_prod.py +16 -4
  20. simtools/applications/validate_cumulative_psf.py +6 -4
  21. simtools/applications/validate_file_using_schema.py +7 -3
  22. simtools/applications/validate_optics.py +5 -4
  23. simtools/camera/camera_efficiency.py +14 -39
  24. simtools/configuration/commandline_parser.py +4 -3
  25. simtools/configuration/configurator.py +10 -0
  26. simtools/corsika/corsika_config.py +103 -5
  27. simtools/data_model/format_checkers.py +9 -0
  28. simtools/data_model/model_data_writer.py +3 -0
  29. simtools/data_model/schema.py +27 -16
  30. simtools/data_model/validate_data.py +27 -7
  31. simtools/db/db_handler.py +10 -4
  32. simtools/layout/array_layout.py +1 -0
  33. simtools/model/array_model.py +63 -29
  34. simtools/model/model_parameter.py +76 -51
  35. simtools/model/model_utils.py +43 -1
  36. simtools/model/site_model.py +3 -2
  37. simtools/model/telescope_model.py +4 -4
  38. simtools/production_configuration/calculate_statistical_errors_grid_point.py +0 -4
  39. simtools/production_configuration/{event_scaler.py → derive_production_statistics.py} +24 -20
  40. simtools/production_configuration/derive_production_statistics_handler.py +119 -0
  41. simtools/production_configuration/generate_production_grid.py +364 -0
  42. simtools/production_configuration/generate_simulation_config.py +9 -9
  43. simtools/production_configuration/interpolation_handler.py +16 -11
  44. simtools/ray_tracing/mirror_panel_psf.py +16 -20
  45. simtools/ray_tracing/psf_analysis.py +2 -2
  46. simtools/ray_tracing/ray_tracing.py +5 -1
  47. simtools/reporting/docs_read_parameters.py +361 -58
  48. simtools/runners/corsika_runner.py +11 -1
  49. simtools/runners/corsika_simtel_runner.py +80 -89
  50. simtools/runners/runner_services.py +17 -4
  51. simtools/runners/simtel_runner.py +27 -10
  52. simtools/schemas/model_parameter.metaschema.yml +4 -0
  53. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +1 -0
  54. simtools/schemas/model_parameters/adjust_gain.schema.yml +2 -2
  55. simtools/schemas/model_parameters/array_element_position_ground.schema.yml +2 -2
  56. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +2 -2
  57. simtools/schemas/model_parameters/array_window.schema.yml +2 -2
  58. simtools/schemas/model_parameters/asum_offset.schema.yml +2 -2
  59. simtools/schemas/model_parameters/asum_shaping.schema.yml +2 -2
  60. simtools/schemas/model_parameters/asum_threshold.schema.yml +2 -2
  61. simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
  62. simtools/schemas/model_parameters/camera_body_diameter.schema.yml +2 -2
  63. simtools/schemas/model_parameters/camera_body_shape.schema.yml +2 -2
  64. simtools/schemas/model_parameters/camera_config_file.schema.yml +2 -2
  65. simtools/schemas/model_parameters/camera_config_rotate.schema.yml +2 -2
  66. simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +2 -2
  67. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +2 -2
  68. simtools/schemas/model_parameters/camera_depth.schema.yml +2 -2
  69. simtools/schemas/model_parameters/camera_filter.schema.yml +2 -2
  70. simtools/schemas/model_parameters/camera_pixels.schema.yml +2 -2
  71. simtools/schemas/model_parameters/camera_transmission.schema.yml +2 -2
  72. simtools/schemas/model_parameters/channels_per_chip.schema.yml +2 -2
  73. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +2 -2
  74. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +90 -1
  75. simtools/schemas/model_parameters/default_trigger.schema.yml +2 -2
  76. simtools/schemas/model_parameters/design_model.schema.yml +2 -2
  77. simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +2 -2
  78. simtools/schemas/model_parameters/disc_bins.schema.yml +2 -2
  79. simtools/schemas/model_parameters/disc_start.schema.yml +2 -2
  80. simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +2 -2
  81. simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +2 -2
  82. simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +2 -2
  83. simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +2 -2
  84. simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +2 -2
  85. simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +2 -2
  86. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +2 -2
  87. simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +2 -2
  88. simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +2 -2
  89. simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +2 -2
  90. simtools/schemas/model_parameters/discriminator_threshold.schema.yml +2 -2
  91. simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +2 -2
  92. simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +2 -2
  93. simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +2 -2
  94. simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +2 -2
  95. simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +2 -2
  96. simtools/schemas/model_parameters/dish_shape_length.schema.yml +2 -2
  97. simtools/schemas/model_parameters/dsum_clipping.schema.yml +2 -2
  98. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +2 -2
  99. simtools/schemas/model_parameters/dsum_offset.schema.yml +2 -2
  100. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +2 -2
  101. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +2 -2
  102. simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
  103. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +2 -2
  104. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +2 -2
  105. simtools/schemas/model_parameters/dsum_shaping.schema.yml +2 -2
  106. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +2 -2
  107. simtools/schemas/model_parameters/dsum_threshold.schema.yml +3 -3
  108. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +2 -2
  109. simtools/schemas/model_parameters/effective_focal_length.schema.yml +2 -2
  110. simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +2 -2
  111. simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -2
  112. simtools/schemas/model_parameters/fadc_bins.schema.yml +2 -2
  113. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +2 -2
  114. simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +2 -2
  115. simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +2 -2
  116. simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -2
  117. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +2 -2
  118. simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +2 -2
  119. simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +2 -2
  120. simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +2 -2
  121. simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +2 -2
  122. simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +2 -2
  123. simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +2 -2
  124. simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +2 -2
  125. simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +2 -2
  126. simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +2 -2
  127. simtools/schemas/model_parameters/fadc_max_signal.schema.yml +2 -2
  128. simtools/schemas/model_parameters/fadc_mhz.schema.yml +2 -2
  129. simtools/schemas/model_parameters/fadc_noise.schema.yml +2 -2
  130. simtools/schemas/model_parameters/fadc_pedestal.schema.yml +2 -2
  131. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +2 -2
  132. simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +2 -2
  133. simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +2 -2
  134. simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +2 -2
  135. simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +2 -2
  136. simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +2 -2
  137. simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +2 -2
  138. simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
  139. simtools/schemas/model_parameters/flatfielding.schema.yml +2 -2
  140. simtools/schemas/model_parameters/focal_length.schema.yml +2 -2
  141. simtools/schemas/model_parameters/focus_offset.schema.yml +2 -2
  142. simtools/schemas/model_parameters/gain_variation.schema.yml +2 -2
  143. simtools/schemas/model_parameters/hg_lg_variation.schema.yml +2 -2
  144. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +2 -2
  145. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +2 -2
  146. simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
  147. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +2 -2
  148. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +2 -2
  149. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +2 -2
  150. simtools/schemas/model_parameters/min_photons.schema.yml +2 -2
  151. simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +2 -2
  152. simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +2 -2
  153. simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +2 -2
  154. simtools/schemas/model_parameters/mirror_class.schema.yml +2 -2
  155. simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +2 -2
  156. simtools/schemas/model_parameters/mirror_focal_length.schema.yml +2 -2
  157. simtools/schemas/model_parameters/mirror_list.schema.yml +2 -2
  158. simtools/schemas/model_parameters/mirror_offset.schema.yml +2 -2
  159. simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +2 -2
  160. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +2 -2
  161. simtools/schemas/model_parameters/multiplicity_offset.schema.yml +2 -2
  162. simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +2 -2
  163. simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
  164. simtools/schemas/model_parameters/nsb_offaxis.schema.yml +2 -2
  165. simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +2 -2
  166. simtools/schemas/model_parameters/num_gains.schema.yml +2 -2
  167. simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +2 -2
  168. simtools/schemas/model_parameters/optics_properties.schema.yml +2 -2
  169. simtools/schemas/model_parameters/pedestal_events.schema.yml +7 -3
  170. simtools/schemas/model_parameters/photon_delay.schema.yml +2 -2
  171. simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +2 -2
  172. simtools/schemas/model_parameters/pm_average_gain.schema.yml +2 -2
  173. simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +2 -2
  174. simtools/schemas/model_parameters/pm_gain_index.schema.yml +2 -2
  175. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +2 -2
  176. simtools/schemas/model_parameters/pm_transit_time.schema.yml +2 -2
  177. simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +2 -2
  178. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +2 -2
  179. simtools/schemas/model_parameters/qe_variation.schema.yml +2 -2
  180. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +2 -2
  181. simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
  182. simtools/schemas/model_parameters/random_generator.schema.yml +2 -2
  183. simtools/schemas/model_parameters/random_mono_probability.schema.yml +2 -2
  184. simtools/schemas/model_parameters/sampled_output.schema.yml +2 -2
  185. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +2 -2
  186. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +2 -2
  187. simtools/schemas/model_parameters/tailcut_scale.schema.yml +2 -2
  188. simtools/schemas/model_parameters/telescope_axis_height.schema.yml +2 -2
  189. simtools/schemas/model_parameters/telescope_random_angle.schema.yml +2 -2
  190. simtools/schemas/model_parameters/telescope_random_error.schema.yml +2 -2
  191. simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +2 -2
  192. simtools/schemas/model_parameters/telescope_transmission.schema.yml +2 -2
  193. simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +2 -2
  194. simtools/schemas/model_parameters/teltrig_min_time.schema.yml +2 -2
  195. simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +2 -2
  196. simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +2 -2
  197. simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +2 -2
  198. simtools/schemas/model_parameters/transit_time_error.schema.yml +2 -2
  199. simtools/schemas/model_parameters/transit_time_jitter.schema.yml +2 -2
  200. simtools/schemas/model_parameters/trigger_current_limit.schema.yml +2 -2
  201. simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +2 -2
  202. simtools/schemas/model_parameters/trigger_pixels.schema.yml +2 -2
  203. simtools/simtel/simtel_config_reader.py +21 -17
  204. simtools/simtel/simtel_config_writer.py +237 -65
  205. simtools/simtel/simtel_io_file_info.py +57 -0
  206. simtools/simtel/simtel_io_histogram.py +10 -14
  207. simtools/simtel/simtel_io_histograms.py +2 -2
  208. simtools/simtel/simtel_io_metadata.py +91 -0
  209. simtools/simtel/simulator_array.py +26 -12
  210. simtools/simtel/simulator_camera_efficiency.py +12 -6
  211. simtools/simtel/simulator_light_emission.py +6 -11
  212. simtools/simtel/simulator_ray_tracing.py +14 -4
  213. simtools/simulator.py +230 -66
  214. simtools/testing/configuration.py +5 -0
  215. simtools/testing/helpers.py +18 -0
  216. simtools/testing/sim_telarray_metadata.py +212 -0
  217. simtools/testing/validate_output.py +12 -5
  218. simtools/utils/general.py +18 -27
  219. simtools/utils/names.py +27 -5
  220. simtools/visualization/visualize.py +2 -2
  221. simtools/applications/production_scale_events.py +0 -185
  222. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/licenses/LICENSE +0 -0
  223. {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/top_level.txt +0 -0
@@ -24,7 +24,8 @@ class ModelParameter:
24
24
  """
25
25
  Base class for simulation model parameters.
26
26
 
27
- Provides methods to read and manipulate parameters from DB.
27
+ Provides methods to read and manipulate parameters from DB and to write
28
+ sim_telarray configuration files.
28
29
 
29
30
  Parameters
30
31
  ----------
@@ -64,7 +65,7 @@ class ModelParameter:
64
65
  )
65
66
 
66
67
  self._parameters = {}
67
- self._simulation_config_parameters = {"corsika": {}, "simtel": {}}
68
+ self._simulation_config_parameters = {sw: {} for sw in names.simulation_software()}
68
69
  self.collection = collection
69
70
  self.label = label
70
71
  self.model_version = model_version
@@ -86,6 +87,34 @@ class ModelParameter:
86
87
  self._is_config_file_up_to_date = False
87
88
  self._is_exported_model_files_up_to_date = False
88
89
 
90
+ @property
91
+ def model_version(self):
92
+ """Model version."""
93
+ return self._model_version
94
+
95
+ @model_version.setter
96
+ def model_version(self, model_version):
97
+ """
98
+ Set model version.
99
+
100
+ Parameters
101
+ ----------
102
+ model_version: str or list
103
+ Model version (e.g., "6.0.0").
104
+ If a list is passed, it must contain exactly one element,
105
+ and only that element will be used.
106
+
107
+ Raises
108
+ ------
109
+ ValueError
110
+ If more than one model version is passed.
111
+ """
112
+ if isinstance(model_version, list):
113
+ raise ValueError(
114
+ f"Only one model version can be passed to {self.__class__.__name__}, not a list."
115
+ )
116
+ self._model_version = model_version
117
+
89
118
  @property
90
119
  def parameters(self):
91
120
  """
@@ -279,7 +308,7 @@ class ModelParameter:
279
308
  return
280
309
 
281
310
  self._config_file_directory = self.io_handler.get_output_directory(
282
- label=self.label, sub_dir="model"
311
+ label=self.label, sub_dir=f"model/{self.model_version}"
283
312
  )
284
313
 
285
314
  # Setting file name and the location
@@ -322,32 +351,19 @@ class ModelParameter:
322
351
  simulation_software=simulation_software,
323
352
  )
324
353
  )
325
- except ValueError as exc:
326
- self._logger.warning(
327
- f"No {simulation_software} parameters found for "
328
- f"{self.site}, {self.name} (model version {self.model_version}). "
329
- f" (Query {exc})"
330
- )
354
+ except ValueError:
355
+ pass
331
356
 
332
357
  def _load_parameters_from_db(self):
333
358
  """Read parameters from DB and store them in _parameters."""
334
359
  if self.db is None:
335
360
  return
336
361
 
337
- if self.name:
362
+ if self.name or self.site:
338
363
  self._parameters = self.db.get_model_parameters(
339
364
  self.site, self.name, self.collection, self.model_version
340
365
  )
341
366
 
342
- if self.site:
343
- self._parameters.update(
344
- self.db.get_model_parameters(
345
- self.site,
346
- None,
347
- "sites",
348
- self.model_version,
349
- )
350
- )
351
367
  self._load_simulation_software_parameter()
352
368
 
353
369
  @property
@@ -446,37 +462,66 @@ class ModelParameter:
446
462
  file_path: str
447
463
  Path of the file to be added to the config file directory.
448
464
  """
449
- if self._added_parameter_files is None:
450
- self._added_parameter_files = []
465
+ self._added_parameter_files = self._added_parameter_files or []
451
466
  self._added_parameter_files.append(par_name)
452
467
  shutil.copy(file_path, self.config_file_directory)
453
468
 
454
- def export_model_files(self):
455
- """Export the model files into the config file directory."""
469
+ def export_model_files(self, destination_path=None, update_if_necessary=False):
470
+ """
471
+ Export the model files into the config file directory.
472
+
473
+ Parameters
474
+ ----------
475
+ destination_path: str
476
+ Path to the directory where the model files should be exported.
477
+ If None, the config file directory is used.
478
+ update_if_necessary: bool
479
+ If True, the model files are only exported if they are not up to date.
480
+ """
481
+ if self._is_exported_model_files_up_to_date and update_if_necessary:
482
+ self._logger.debug(
483
+ f"Model files for {self.name} are already exported to {self.config_file_directory}"
484
+ )
485
+ return
456
486
  # Removing parameter files added manually (which are not in DB)
457
487
  pars_from_db = copy(self.parameters)
458
488
  if self._added_parameter_files is not None:
459
489
  for par in self._added_parameter_files:
460
490
  pars_from_db.pop(par)
461
491
 
462
- self.db.export_model_files(parameters=pars_from_db, dest=self.config_file_directory)
492
+ self.db.export_model_files(
493
+ parameters=pars_from_db,
494
+ dest=destination_path or self.config_file_directory,
495
+ )
463
496
  self._is_exported_model_files_up_to_date = True
464
497
 
465
- def export_config_file(self):
466
- """Export the config file used by sim_telarray."""
467
- if not self._is_exported_model_files_up_to_date:
468
- self.export_model_files()
498
+ def write_sim_telarray_config_file(self, additional_model=None):
499
+ """
500
+ Write the sim_telarray configuration file.
501
+
502
+ Parameters
503
+ ----------
504
+ additional_model: TelescopeModel or SiteModel
505
+ Model object for additional parameter to be written to the config file.
506
+ """
507
+ self.parameters.update(self._simulation_config_parameters.get("sim_telarray", {}))
508
+ self.export_model_files(update_if_necessary=True)
509
+
510
+ if additional_model:
511
+ self.parameters.update(additional_model.parameters)
512
+ additional_model.export_model_files(
513
+ self.config_file_directory, update_if_necessary=True
514
+ )
469
515
 
470
516
  self._load_simtel_config_writer()
471
517
  self.simtel_config_writer.write_telescope_config_file(
472
518
  config_file_path=self.config_file_path,
473
519
  parameters=self.parameters,
474
- config_parameters=self._simulation_config_parameters["simtel"],
475
520
  )
476
521
 
477
522
  @property
478
523
  def config_file_directory(self):
479
- """Directory for configure files. Configure, if necessary."""
524
+ """Directory for configuration files. Configure if not yet set."""
480
525
  if self._config_file_directory is None:
481
526
  self._set_config_file_directory_and_name()
482
527
  return self._config_file_directory
@@ -488,26 +533,6 @@ class ModelParameter:
488
533
  self._set_config_file_directory_and_name()
489
534
  return self._config_file_path
490
535
 
491
- def get_config_file(self, no_export=False):
492
- """
493
- Get the path of the config file for sim_telarray.
494
-
495
- The config file is produced if the file is not up to date.
496
-
497
- Parameters
498
- ----------
499
- no_export: bool
500
- Turn it on if you do not want the file to be exported.
501
-
502
- Returns
503
- -------
504
- Path
505
- Path of the exported config file for sim_telarray.
506
- """
507
- if not self._is_config_file_up_to_date and not no_export:
508
- self.export_config_file()
509
- return self.config_file_path
510
-
511
536
  def _load_simtel_config_writer(self):
512
537
  """Load the SimtelConfigWriter object."""
513
538
  if self.simtel_config_writer is None:
@@ -535,7 +560,7 @@ class ModelParameter:
535
560
  self.db.export_model_files(
536
561
  parameters={
537
562
  "nsb_spectrum_at_2200m": {
538
- "value": self._simulation_config_parameters["simtel"][
563
+ "value": self._simulation_config_parameters["sim_telarray"][
539
564
  "correct_nsb_spectrum_to_telescope_altitude"
540
565
  ]["value"],
541
566
  "file": True,
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/python3
2
- """Helper functions calculations related to model parameters."""
2
+ """Helper functions related to model parameters."""
3
3
 
4
4
  import math
5
5
 
6
+ from simtools.model.site_model import SiteModel
7
+ from simtools.model.telescope_model import TelescopeModel
6
8
  from simtools.utils import names
7
9
 
8
10
  __all__ = [
@@ -11,6 +13,46 @@ __all__ = [
11
13
  ]
12
14
 
13
15
 
16
+ def initialize_simulation_models(label, db_config, site, telescope_name, model_version):
17
+ """
18
+ Initialize simulation models for a single telescope and site model.
19
+
20
+ Parameters
21
+ ----------
22
+ label: str
23
+ Label for the simulation.
24
+ db_config: dict
25
+ Database configuration.
26
+ site: str
27
+ Name of the site.
28
+ telescope_name: str
29
+ Name of the telescope.
30
+ model_version: str
31
+ Version of the simulation model
32
+
33
+ Returns
34
+ -------
35
+ Tuple
36
+ Tuple containing the telescope model and site model.
37
+ """
38
+ tel_model = TelescopeModel(
39
+ site=site,
40
+ telescope_name=telescope_name,
41
+ mongo_db_config=db_config,
42
+ model_version=model_version,
43
+ label=label,
44
+ )
45
+ site_model = SiteModel(
46
+ site=site,
47
+ model_version=model_version,
48
+ mongo_db_config=db_config,
49
+ label=label,
50
+ )
51
+ for model in tel_model, site_model:
52
+ model.export_model_files()
53
+ return tel_model, site_model
54
+
55
+
14
56
  def compute_telescope_transmission(pars: list[float], off_axis: float) -> float:
15
57
  """
16
58
  Compute telescope transmission (0 < T < 1) for a given off-axis angle.
@@ -19,8 +19,8 @@ class SiteModel(ModelParameter):
19
19
  Site name (e.g., South or North).
20
20
  mongo_db_config: dict
21
21
  MongoDB configuration.
22
- model_version: str
23
- Model version.
22
+ model_version: str or list
23
+ Model version or list of model versions (in which case only the first one is used).
24
24
  label: str, optional
25
25
  Instance label. Important for output file naming.
26
26
  """
@@ -41,6 +41,7 @@ class SiteModel(ModelParameter):
41
41
  model_version=model_version,
42
42
  db=None,
43
43
  label=label,
44
+ collection="sites",
44
45
  )
45
46
 
46
47
  def get_reference_point(self) -> dict:
@@ -220,8 +220,8 @@ class TelescopeModel(ModelParameter):
220
220
  """
221
221
  try:
222
222
  file_name = self.get_parameter_value(par)
223
- except KeyError:
224
- logging.error(f"Parameter {par} does not exist")
223
+ except InvalidModelParameterError:
224
+ logging.warning(f"Parameter {par} does not exist")
225
225
  return False
226
226
 
227
227
  file = self.config_file_directory.joinpath(file_name)
@@ -269,11 +269,11 @@ class TelescopeModel(ModelParameter):
269
269
  self.config_file_directory.joinpath(self.get_parameter_value("optics_properties"))
270
270
  )
271
271
  if not np.isclose(ray_tracing_data["Off-axis angle"][0], 0):
272
- self._logger.error(
272
+ msg = (
273
273
  f"No value for the on-axis effective optical area exists."
274
274
  f" The minimum off-axis angle is {ray_tracing_data['Off-axis angle'][0]}"
275
275
  )
276
- raise ValueError
276
+ raise ValueError(msg)
277
277
  return ray_tracing_data["eff_area"][0]
278
278
 
279
279
  def read_incidence_angle_distribution(self, incidence_angle_dist_file: str) -> Table:
@@ -17,8 +17,6 @@ class StatisticalErrorEvaluator:
17
17
  ----------
18
18
  file_path : str
19
19
  Path to the DL2 MC event file.
20
- file_type : str
21
- Type of the file, either 'point-like' or 'cone'.
22
20
  metrics : dict, optional
23
21
  Dictionary of metrics to evaluate. Default is None.
24
22
  grid_point : tuple, optional
@@ -28,13 +26,11 @@ class StatisticalErrorEvaluator:
28
26
  def __init__(
29
27
  self,
30
28
  file_path: str,
31
- file_type: str,
32
29
  metrics: dict[str, float],
33
30
  grid_point: tuple[float, float, float, float, float] | None = None,
34
31
  ):
35
32
  """Init the evaluator with a DL2 MC event file, its type, and metrics to calculate."""
36
33
  self._logger = logging.getLogger(__name__)
37
- self.file_type = file_type
38
34
  self.metrics = metrics
39
35
  self.grid_point = grid_point
40
36
 
@@ -1,27 +1,29 @@
1
1
  """
2
- Calculate the scaled number of events based on metrics.
2
+ Calculate the event production statistics based on metrics.
3
3
 
4
- Module for scaling events based on statistical error metrics. Contains the `EventScaler` class,
5
- which scales the number of events for both the entire dataset and specific grid points.
6
- Scaling factors are calculated using error metrics and the evaluator's results.
4
+ Module for calculating the production event statistics based on statistical error metrics.
5
+ Contains the `ProductionStatisticsDerivator` class, which derives the number of events for
6
+ both the entire dataset and specific grid points. Event statistic is calculated using error
7
+ metrics and the evaluator's results.
7
8
  """
8
9
 
9
10
  import astropy.units as u
10
11
  import numpy as np
11
12
 
12
- __all__ = ["EventScaler"]
13
+ __all__ = ["ProductionStatisticsDerivator"]
13
14
 
14
15
 
15
- class EventScaler:
16
+ class ProductionStatisticsDerivator:
16
17
  """
17
- Scales the number of events based on statistical error metrics.
18
+ Derives the production statistics based on statistical error metrics.
18
19
 
19
- Supports scaling both the entire dataset and specific grid points like energy values.
20
+ Supports deriving statistics for both the entire dataset and
21
+ specific grid points like energy values.
20
22
  """
21
23
 
22
24
  def __init__(self, evaluator, metrics: dict):
23
25
  """
24
- Initialize the EventScaler with the evaluator and metrics.
26
+ Initialize the ProductionStatisticsDerivator with the evaluator and metrics.
25
27
 
26
28
  Parameters
27
29
  ----------
@@ -33,22 +35,24 @@ class EventScaler:
33
35
  self.evaluator = evaluator
34
36
  self.metrics = metrics
35
37
 
36
- def scale_events(self, return_sum: bool = True) -> u.Quantity:
38
+ def derive_statistics(self, return_sum: bool = True) -> u.Quantity:
37
39
  """
38
- Calculate the scaled number of events based on statistical error metrics.
40
+ Derive the production statistics based on statistical error metrics.
39
41
 
40
42
  Parameters
41
43
  ----------
42
44
  return_sum : bool, optional
43
- If True, returns the sum of scaled events for the entire set of MC events. If False,
44
- returns the scaled events for each grid point along the energy axis. Default is True.
45
+ If True, returns the sum of production statistics for the entire set of MC events.
46
+ If False, returns the production statistics for each grid point along the energy axis.
47
+ Default is True.
45
48
 
46
49
  Returns
47
50
  -------
48
51
  u.Quantity
49
- If 'return_sum' is True, returns the total scaled number of events as a u.Quantity.
50
- If 'return_sum' is False, returns an array of scaled events along the energy axis as
51
- a u.Quantity.
52
+ If 'return_sum' is True, returns the total
53
+ derived production statistics as a u.Quantity.
54
+ If 'return_sum' is False, returns an array of production statistics along the energy
55
+ axis as a u.Quantity.
52
56
  """
53
57
  scaling_factor = self._compute_scaling_factor()
54
58
 
@@ -87,12 +91,12 @@ class EventScaler:
87
91
  """
88
92
  return self.evaluator.data.get("simulated_event_histogram")
89
93
 
90
- def calculate_scaled_events_at_grid_point(
94
+ def calculate_production_statistics_at_grid_point(
91
95
  self,
92
96
  grid_point: tuple,
93
97
  ) -> u.Quantity:
94
98
  """
95
- Calculate the scaled number of events for a specific energy grid point.
99
+ Derive the production statistics for a specific energy grid point.
96
100
 
97
101
  Parameters
98
102
  ----------
@@ -102,7 +106,7 @@ class EventScaler:
102
106
  Returns
103
107
  -------
104
108
  float
105
- The scaled number of events at the specified grid point (energy).
109
+ The derived production statistics at the specified grid point (energy).
106
110
  """
107
111
  energy = grid_point[0]
108
112
  bin_edges = self.evaluator.create_bin_edges()
@@ -113,7 +117,7 @@ class EventScaler:
113
117
  simulated_event_histogram = self.evaluator.data.get("simulated_event_histogram", [])
114
118
 
115
119
  if bin_idx < 0 or bin_idx >= len(simulated_event_histogram):
116
- raise ValueError(f"Energy {energy} is outside the range of the simulated events data.")
120
+ raise ValueError(f"Energy {energy} is outside therange of the simulated events data.")
117
121
 
118
122
  base_events = self._number_of_simulated_events()
119
123
  base_event_at_energy = base_events[bin_idx]
@@ -0,0 +1,119 @@
1
+ """
2
+ Module to run the StatisticalErrorEvaluator and interpolate results.
3
+
4
+ This module provides the `ProductionStatisticsHandler` class, which manages the workflow for
5
+ derivation of required number of events for a simulation production using pre-defined metrics.
6
+
7
+ The module includes functionality to:
8
+ - Initialize evaluators for statistical error calculations based on input parameters.
9
+ - Perform interpolation using the initialized evaluators to estimate production statistics at a
10
+ query point.
11
+ - Write the results of the interpolation to an output file.
12
+ """
13
+
14
+ import itertools
15
+ import json
16
+ import logging
17
+ from pathlib import Path
18
+
19
+ import astropy.units as u
20
+ import numpy as np
21
+
22
+ from simtools.production_configuration.calculate_statistical_errors_grid_point import (
23
+ StatisticalErrorEvaluator,
24
+ )
25
+ from simtools.production_configuration.interpolation_handler import InterpolationHandler
26
+ from simtools.utils.general import collect_data_from_file
27
+
28
+
29
+ class ProductionStatisticsHandler:
30
+ """
31
+ Handles the workflow for deriving production statistics.
32
+
33
+ This class manages the evaluation of statistical uncertainties from DL2 MC event files
34
+ and performs interpolation to estimate the required number of events for a simulation
35
+ production at a specified query point.
36
+ """
37
+
38
+ def __init__(self, args_dict):
39
+ """
40
+ Initialize the manager with the provided arguments.
41
+
42
+ Parameters
43
+ ----------
44
+ args_dict : dict
45
+ Dictionary of command-line arguments.
46
+ """
47
+ self.args = args_dict
48
+ self.logger = logging.getLogger(__name__)
49
+ self.output_path = Path(self.args.get("output_path", "."))
50
+ self.output_filepath = self.output_path.joinpath(f"{self.args['output_file']}")
51
+ self.metrics = collect_data_from_file(self.args["metrics_file"])
52
+ self.evaluator_instances = []
53
+
54
+ def initialize_evaluators(self):
55
+ """Initialize StatisticalErrorEvaluator instances for the given zeniths and offsets."""
56
+ if not (self.args["base_path"] and self.args["zeniths"] and self.args["camera_offsets"]):
57
+ self.logger.warning("No files read")
58
+ self.logger.warning(f"Base Path: {self.args['base_path']}")
59
+ self.logger.warning(f"Zeniths: {self.args['zeniths']}")
60
+ self.logger.warning(f"Camera offsets: {self.args['camera_offsets']}")
61
+ return
62
+
63
+ for zenith, offset in itertools.product(self.args["zeniths"], self.args["camera_offsets"]):
64
+ file_name = self.args["file_name_template"].format(zenith=int(zenith))
65
+ file_path = Path(self.args["base_path"]).joinpath(file_name)
66
+
67
+ if not file_path.exists():
68
+ self.logger.warning(f"File not found: {file_path}. Skipping.")
69
+ continue
70
+
71
+ evaluator = StatisticalErrorEvaluator(
72
+ file_path,
73
+ metrics=self.metrics,
74
+ grid_point=(None, None, zenith, None, offset * u.deg),
75
+ )
76
+ evaluator.calculate_metrics()
77
+ self.evaluator_instances.append(evaluator)
78
+
79
+ def perform_interpolation(self):
80
+ """Perform interpolation for the query point."""
81
+ if not self.evaluator_instances:
82
+ self.logger.error("No evaluators initialized. Cannot perform interpolation.")
83
+ return None
84
+
85
+ interpolation_handler = InterpolationHandler(self.evaluator_instances, metrics=self.metrics)
86
+ query_point = self.args.get("query_point")
87
+ if not query_point or len(query_point) != 5:
88
+ raise ValueError(
89
+ "Invalid query point format. "
90
+ f"Expected 5 values, got {len(query_point) if query_point else 'None'}."
91
+ )
92
+ query_points = np.array([self.args["query_point"]])
93
+ return interpolation_handler.interpolate(query_points)
94
+
95
+ def write_output(self, production_statistics):
96
+ """Write the derived event statistics to a file."""
97
+ output_data = {
98
+ "query_point": self.args["query_point"],
99
+ "production_statistics": production_statistics.tolist(),
100
+ }
101
+ self.output_filepath.parent.mkdir(parents=True, exist_ok=True)
102
+ with open(self.output_filepath, "w", encoding="utf-8") as f:
103
+ json.dump(output_data, f, indent=4)
104
+ self.logger.info(f"Output saved to {self.output_filepath}")
105
+ self.logger.info(
106
+ f"production statistics for grid point "
107
+ f"{self.args['query_point']}: {production_statistics}"
108
+ )
109
+
110
+ def run(self):
111
+ """Run the scaling and interpolation workflow."""
112
+ self.logger.info(f"Zeniths: {self.args['zeniths']}")
113
+ self.logger.info(f"Camera offsets: {self.args['camera_offsets']}")
114
+ self.logger.info(f"Query Point: {self.args['query_point']}")
115
+ self.logger.info(f"Metrics File: {self.args['metrics_file']}")
116
+
117
+ self.initialize_evaluators()
118
+ production_statistics = self.perform_interpolation()
119
+ self.write_output(production_statistics)