gammasimtools 0.25.0__py3-none-any.whl → 0.26.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 (125) hide show
  1. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/METADATA +2 -1
  2. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +122 -121
  3. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +2 -1
  4. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
  5. simtools/_version.py +2 -2
  6. simtools/application_control.py +35 -7
  7. simtools/applications/calculate_incident_angles.py +0 -2
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -2
  9. simtools/applications/db_add_file_to_db.py +1 -1
  10. simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
  11. simtools/applications/db_add_value_from_json_to_db.py +1 -1
  12. simtools/applications/db_generate_compound_indexes.py +1 -1
  13. simtools/applications/db_get_array_layouts_from_db.py +2 -6
  14. simtools/applications/db_get_file_from_db.py +1 -1
  15. simtools/applications/db_get_parameter_from_db.py +1 -1
  16. simtools/applications/db_inspect_databases.py +1 -1
  17. simtools/applications/db_upload_model_repository.py +1 -1
  18. simtools/applications/derive_ctao_array_layouts.py +1 -2
  19. simtools/applications/derive_mirror_rnda.py +1 -3
  20. simtools/applications/derive_psf_parameters.py +0 -1
  21. simtools/applications/derive_pulse_shape_parameters.py +0 -1
  22. simtools/applications/derive_trigger_rates.py +1 -1
  23. simtools/applications/docs_produce_array_element_report.py +2 -8
  24. simtools/applications/docs_produce_calibration_reports.py +1 -3
  25. simtools/applications/docs_produce_model_parameter_reports.py +0 -2
  26. simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
  27. simtools/applications/generate_array_config.py +0 -1
  28. simtools/applications/generate_corsika_histograms.py +48 -235
  29. simtools/applications/generate_regular_arrays.py +5 -35
  30. simtools/applications/generate_simtel_event_data.py +2 -2
  31. simtools/applications/maintain_simulation_model_add_production.py +2 -2
  32. simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
  33. simtools/applications/plot_array_layout.py +5 -111
  34. simtools/applications/plot_simulated_event_distributions.py +57 -0
  35. simtools/applications/plot_tabular_data.py +0 -1
  36. simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
  37. simtools/applications/production_derive_corsika_limits.py +1 -1
  38. simtools/applications/production_generate_grid.py +0 -1
  39. simtools/applications/run_application.py +1 -1
  40. simtools/applications/simulate_flasher.py +0 -2
  41. simtools/applications/simulate_illuminator.py +0 -1
  42. simtools/applications/simulate_pedestals.py +1 -5
  43. simtools/applications/simulate_prod.py +1 -5
  44. simtools/applications/simulate_prod_htcondor_generator.py +1 -1
  45. simtools/applications/submit_array_layouts.py +2 -4
  46. simtools/applications/submit_model_parameter_from_external.py +1 -3
  47. simtools/applications/validate_camera_efficiency.py +0 -1
  48. simtools/applications/validate_camera_fov.py +0 -1
  49. simtools/applications/validate_cumulative_psf.py +0 -2
  50. simtools/applications/validate_optics.py +0 -13
  51. simtools/camera/camera_efficiency.py +1 -6
  52. simtools/camera/single_photon_electron_spectrum.py +2 -1
  53. simtools/configuration/commandline_parser.py +35 -2
  54. simtools/configuration/configurator.py +6 -11
  55. simtools/corsika/corsika_config.py +16 -21
  56. simtools/corsika/corsika_histograms.py +411 -1735
  57. simtools/corsika/primary_particle.py +1 -1
  58. simtools/data_model/metadata_collector.py +5 -2
  59. simtools/data_model/metadata_model.py +0 -4
  60. simtools/data_model/model_data_writer.py +13 -15
  61. simtools/data_model/validate_data.py +1 -3
  62. simtools/db/db_handler.py +19 -8
  63. simtools/dependencies.py +81 -38
  64. simtools/io/ascii_handler.py +4 -2
  65. simtools/io/table_handler.py +1 -1
  66. simtools/layout/array_layout.py +4 -12
  67. simtools/layout/array_layout_utils.py +226 -57
  68. simtools/model/array_model.py +1 -13
  69. simtools/model/calibration_model.py +0 -4
  70. simtools/model/legacy_model_parameter.py +134 -0
  71. simtools/model/model_parameter.py +24 -13
  72. simtools/model/model_utils.py +1 -6
  73. simtools/model/site_model.py +0 -4
  74. simtools/model/telescope_model.py +6 -11
  75. simtools/production_configuration/derive_corsika_limits.py +6 -11
  76. simtools/production_configuration/interpolation_handler.py +16 -16
  77. simtools/ray_tracing/incident_angles.py +5 -11
  78. simtools/ray_tracing/mirror_panel_psf.py +3 -7
  79. simtools/ray_tracing/psf_analysis.py +18 -19
  80. simtools/ray_tracing/psf_parameter_optimisation.py +0 -1
  81. simtools/ray_tracing/ray_tracing.py +6 -15
  82. simtools/reporting/docs_auto_report_generator.py +8 -13
  83. simtools/reporting/docs_read_parameters.py +2 -8
  84. simtools/runners/corsika_runner.py +5 -9
  85. simtools/runners/corsika_simtel_runner.py +3 -8
  86. simtools/runners/simtel_runner.py +0 -5
  87. simtools/runners/simtools_runner.py +2 -4
  88. simtools/settings.py +154 -0
  89. simtools/{io/eventio_handler.py → sim_events/file_info.py} +3 -3
  90. simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
  91. simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
  92. simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
  93. simtools/simtel/pulse_shapes.py +7 -2
  94. simtools/simtel/simtel_config_writer.py +79 -36
  95. simtools/simtel/simtel_table_reader.py +6 -4
  96. simtools/simtel/simulator_array.py +4 -11
  97. simtools/simtel/simulator_camera_efficiency.py +4 -6
  98. simtools/simtel/simulator_light_emission.py +69 -24
  99. simtools/simtel/simulator_ray_tracing.py +4 -10
  100. simtools/simulator.py +7 -14
  101. simtools/telescope_trigger_rates.py +3 -4
  102. simtools/testing/assertions.py +84 -33
  103. simtools/testing/configuration.py +1 -2
  104. simtools/testing/helpers.py +2 -3
  105. simtools/testing/log_inspector.py +1 -0
  106. simtools/testing/sim_telarray_metadata.py +1 -1
  107. simtools/testing/validate_output.py +34 -23
  108. simtools/utils/general.py +37 -0
  109. simtools/utils/geometry.py +0 -77
  110. simtools/utils/names.py +5 -5
  111. simtools/visualization/legend_handlers.py +7 -6
  112. simtools/visualization/plot_array_layout.py +91 -16
  113. simtools/visualization/plot_corsika_histograms.py +143 -605
  114. simtools/visualization/plot_mirrors.py +1 -4
  115. simtools/visualization/plot_pixels.py +2 -4
  116. simtools/visualization/plot_psf.py +0 -1
  117. simtools/visualization/plot_simtel_event_histograms.py +4 -4
  118. simtools/visualization/plot_simtel_events.py +6 -11
  119. simtools/visualization/plot_tables.py +8 -19
  120. simtools/visualization/visualize.py +22 -2
  121. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
  122. simtools/applications/print_version.py +0 -53
  123. simtools/io/hdf5_handler.py +0 -139
  124. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/WHEEL +0 -0
  125. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
@@ -11,6 +11,7 @@ import simtools.utils.general as gen
11
11
  from simtools.data_model import schema
12
12
  from simtools.db import db_handler
13
13
  from simtools.io import ascii_handler, io_handler
14
+ from simtools.model import legacy_model_parameter
14
15
  from simtools.simtel.simtel_config_writer import SimtelConfigWriter
15
16
  from simtools.utils import names, value_conversion
16
17
 
@@ -28,8 +29,6 @@ class ModelParameter:
28
29
 
29
30
  Parameters
30
31
  ----------
31
- db_config:
32
- Database configuration dictionary.
33
32
  model_version: str
34
33
  Version of the model (ex. 5.0.0).
35
34
  site: str
@@ -51,7 +50,6 @@ class ModelParameter:
51
50
 
52
51
  def __init__(
53
52
  self,
54
- db_config,
55
53
  model_version,
56
54
  site=None,
57
55
  array_element_name=None,
@@ -62,7 +60,9 @@ class ModelParameter:
62
60
  ):
63
61
  self._logger = logging.getLogger(__name__)
64
62
  self.io_handler = io_handler.IOHandler()
65
- self.db = db_handler.DatabaseHandler(db_config=db_config)
63
+ self.db = db_handler.DatabaseHandler()
64
+ if not self.db.is_configured():
65
+ raise RuntimeError("Database is not configured.")
66
66
 
67
67
  self.parameters = {}
68
68
  self._simulation_config_parameters = {sw: {} for sw in names.simulation_software()}
@@ -327,35 +327,46 @@ class ModelParameter:
327
327
  )
328
328
  if self.overwrite_model_parameters:
329
329
  self.overwrite_parameters_from_file(self.overwrite_model_parameters)
330
- self._check_model_parameter_software_versions(self.parameters.keys())
330
+ self._check_model_parameter_versions(self.parameters)
331
331
 
332
332
  self._load_simulation_software_parameter()
333
333
  for software_name, parameters in self._simulation_config_parameters.items():
334
- self._check_model_parameter_software_versions(
335
- parameters.keys(), software_name=software_name
336
- )
334
+ self._check_model_parameter_versions(parameters, software_name=software_name)
337
335
 
338
- def _check_model_parameter_software_versions(self, parameter_list, software_name=None):
336
+ def _check_model_parameter_versions(self, parameters, software_name=None):
339
337
  """
340
- Ensure that model parameters are compatible with the installed software versions.
338
+ Ensure parameters follow the latest schema and are compatible with installed software.
341
339
 
342
340
  Compares software versions listed in schema files with the installed software versions
343
341
  (e.g., sim_telarray, CORSIKA).
344
342
 
343
+ For outdated model parameter schemas, legacy update functions are called to update
344
+ the parameters to the latest schema version.
345
+
345
346
  Parameters
346
347
  ----------
347
- parameter_list: list
348
- List containing model parameter names.
348
+ parameters: dict
349
+ Dictionary containing model parameters.
349
350
  software_name: str
350
351
  Name of the software for which the parameters are checked.
351
352
  """
352
- for par_name in parameter_list:
353
+ _legacy_updates = {}
354
+ for par_name, par_data in parameters.items():
353
355
  if par_name in (parameter_schema := names.model_parameters()):
354
356
  schema.validate_deprecation_and_version(
355
357
  data=parameter_schema[par_name],
356
358
  software_name=software_name,
357
359
  ignore_software_version=self.ignore_software_version,
358
360
  )
361
+ _latest_schema_version = parameter_schema[par_name]["schema_version"]
362
+ if par_data["model_parameter_schema_version"] != _latest_schema_version:
363
+ _legacy_updates.update(
364
+ legacy_model_parameter.update_parameter(
365
+ par_name, parameters, _latest_schema_version
366
+ )
367
+ )
368
+
369
+ legacy_model_parameter.apply_legacy_updates_to_parameters(parameters, _legacy_updates)
359
370
 
360
371
  def overwrite_model_parameter(self, par_name, value, parameter_version=None):
361
372
  """
@@ -10,7 +10,7 @@ from simtools.utils import names
10
10
 
11
11
 
12
12
  def initialize_simulation_models(
13
- label, db_config, model_version, site, telescope_name, calibration_device_name=None
13
+ label, model_version, site, telescope_name, calibration_device_name=None
14
14
  ):
15
15
  """
16
16
  Initialize simulation models for a single telescope, site, and calibration device model.
@@ -19,8 +19,6 @@ def initialize_simulation_models(
19
19
  ----------
20
20
  label: str
21
21
  Label for the simulation.
22
- db_config: dict
23
- Database configuration.
24
22
  model_version: str
25
23
  Version of the simulation model
26
24
  site: str
@@ -38,21 +36,18 @@ def initialize_simulation_models(
38
36
  tel_model = TelescopeModel(
39
37
  site=site,
40
38
  telescope_name=telescope_name,
41
- db_config=db_config,
42
39
  model_version=model_version,
43
40
  label=label,
44
41
  )
45
42
  site_model = SiteModel(
46
43
  site=site,
47
44
  model_version=model_version,
48
- db_config=db_config,
49
45
  label=label,
50
46
  )
51
47
  if calibration_device_name is not None:
52
48
  calibration_model = CalibrationModel(
53
49
  site=site,
54
50
  calibration_device_model_name=calibration_device_name,
55
- db_config=db_config,
56
51
  model_version=model_version,
57
52
  label=label,
58
53
  )
@@ -26,8 +26,6 @@ class SiteModel(ModelParameter):
26
26
  ----------
27
27
  site: str
28
28
  Site name (e.g., South or North).
29
- db_config: dict
30
- Database configuration.
31
29
  model_version: str or list
32
30
  Model version or list of model versions (in which case only the first one is used).
33
31
  label: str, optional
@@ -41,7 +39,6 @@ class SiteModel(ModelParameter):
41
39
  def __init__(
42
40
  self,
43
41
  site,
44
- db_config,
45
42
  model_version,
46
43
  label=None,
47
44
  overwrite_model_parameters=None,
@@ -52,7 +49,6 @@ class SiteModel(ModelParameter):
52
49
  self._logger.debug("Init SiteModel for site %s", site)
53
50
  super().__init__(
54
51
  site=site,
55
- db_config=db_config,
56
52
  model_version=model_version,
57
53
  label=label,
58
54
  collection="sites",
@@ -26,8 +26,6 @@ class TelescopeModel(ModelParameter):
26
26
  Site name (e.g., South or North).
27
27
  telescope_name: str
28
28
  Telescope name (ex. LSTN-01, LSTN-design, ...).
29
- db_config: dict
30
- Database configuration.
31
29
  model_version: str
32
30
  Model version.
33
31
  label: str, optional
@@ -42,7 +40,6 @@ class TelescopeModel(ModelParameter):
42
40
  self,
43
41
  site,
44
42
  telescope_name,
45
- db_config,
46
43
  model_version,
47
44
  label=None,
48
45
  overwrite_model_parameters=None,
@@ -52,7 +49,6 @@ class TelescopeModel(ModelParameter):
52
49
  super().__init__(
53
50
  site=site,
54
51
  array_element_name=telescope_name,
55
- db_config=db_config,
56
52
  model_version=model_version,
57
53
  label=label,
58
54
  overwrite_model_parameters=overwrite_model_parameters,
@@ -326,13 +322,12 @@ class TelescopeModel(ModelParameter):
326
322
  average_curve: astropy.table.Table
327
323
  Instance of astropy.table.Table with the averaged curve.
328
324
  """
329
- weights = []
330
- for angle_now in curves["Angle"]:
331
- weights.append(
332
- incidence_angle_dist["Fraction"][
333
- np.nanargmin(np.abs(angle_now - incidence_angle_dist["Incidence angle"].value))
334
- ]
335
- )
325
+ weights = [
326
+ incidence_angle_dist["Fraction"][
327
+ np.nanargmin(np.abs(angle_now - incidence_angle_dist["Incidence angle"].value))
328
+ ]
329
+ for angle_now in curves["Angle"]
330
+ ]
336
331
 
337
332
  return Table(
338
333
  [curves["Wavelength"], np.average(curves["z"], weights=weights, axis=0)],
@@ -10,13 +10,13 @@ from astropy.table import Column, Table
10
10
  from simtools.data_model.metadata_collector import MetadataCollector
11
11
  from simtools.io import ascii_handler, io_handler
12
12
  from simtools.layout.array_layout_utils import get_array_elements_from_db_for_layouts
13
- from simtools.simtel.simtel_io_event_histograms import SimtelIOEventHistograms
13
+ from simtools.sim_events.histograms import EventDataHistograms
14
14
  from simtools.visualization import plot_simtel_event_histograms
15
15
 
16
16
  _logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
- def generate_corsika_limits_grid(args_dict, db_config=None):
19
+ def generate_corsika_limits_grid(args_dict):
20
20
  """
21
21
  Generate CORSIKA limits.
22
22
 
@@ -24,15 +24,12 @@ def generate_corsika_limits_grid(args_dict, db_config=None):
24
24
  ----------
25
25
  args_dict : dict
26
26
  Dictionary containing command line arguments.
27
- db_config : dict, optional
28
- Database configuration dictionary.
29
27
  """
30
28
  if args_dict.get("array_layout_name"):
31
29
  telescope_configs = get_array_elements_from_db_for_layouts(
32
30
  args_dict["array_layout_name"],
33
31
  args_dict.get("site"),
34
32
  args_dict.get("model_version"),
35
- db_config,
36
33
  )
37
34
  else:
38
35
  telescope_configs = ascii_handler.collect_data_from_file(args_dict["telescope_ids"])[
@@ -81,9 +78,7 @@ def _process_file(file_path, array_name, telescope_ids, loss_fraction, plot_hist
81
78
  dict
82
79
  Dictionary containing the computed limits and metadata.
83
80
  """
84
- histograms = SimtelIOEventHistograms(
85
- file_path, array_name=array_name, telescope_list=telescope_ids
86
- )
81
+ histograms = EventDataHistograms(file_path, array_name=array_name, telescope_list=telescope_ids)
87
82
  histograms.fill()
88
83
 
89
84
  limits = {
@@ -257,7 +252,7 @@ def compute_lower_energy_limit(histograms, loss_fraction):
257
252
 
258
253
  Parameters
259
254
  ----------
260
- histograms : SimtelIOEventHistograms
255
+ histograms : EventDataHistograms
261
256
  Histograms.
262
257
  loss_fraction : float
263
258
  Fraction of events to be lost.
@@ -299,7 +294,7 @@ def compute_upper_radius_limit(histograms, loss_fraction):
299
294
 
300
295
  Parameters
301
296
  ----------
302
- histograms : SimtelIOEventHistograms
297
+ histograms : EventDataHistograms
303
298
  Histograms.
304
299
  loss_fraction : float
305
300
  Fraction of events to be lost.
@@ -337,7 +332,7 @@ def compute_viewcone(histograms, loss_fraction):
337
332
 
338
333
  Parameters
339
334
  ----------
340
- histograms : SimtelIOEventHistograms
335
+ histograms : EventDataHistograms
341
336
  Histograms.
342
337
  loss_fraction : float
343
338
  Fraction of events to be lost.
@@ -214,17 +214,15 @@ class InterpolationHandler:
214
214
  np.ndarray
215
215
  Reduced production grid points.
216
216
  """
217
- production_grid_points = []
218
-
219
- for point in self.grid_points_production:
220
- production_grid_points.append(
221
- [
222
- point["azimuth"]["value"],
223
- point["zenith_angle"]["value"],
224
- point["nsb"]["value"],
225
- point["offset"]["value"],
226
- ]
227
- )
217
+ production_grid_points = [
218
+ [
219
+ point["azimuth"]["value"],
220
+ point["zenith_angle"]["value"],
221
+ point["nsb"]["value"],
222
+ point["offset"]["value"],
223
+ ]
224
+ for point in self.grid_points_production
225
+ ]
228
226
 
229
227
  production_grid_points = np.array(production_grid_points)
230
228
 
@@ -280,11 +278,13 @@ class InterpolationHandler:
280
278
  reduced_production_grid_points = self._prepare_production_grid_points()
281
279
  energy_grid = self.energy_grids[0] if self.energy_grids else []
282
280
 
283
- energy_query_grid = []
284
- for energy in energy_grid:
285
- for grid_point in reduced_production_grid_points:
286
- energy_query_grid.append(np.hstack([energy.to(u.TeV).value, grid_point]))
287
-
281
+ energy_query_grid = [
282
+ [
283
+ np.hstack([energy.to(u.TeV).value, grid_point])
284
+ for energy in energy_grid
285
+ for grid_point in reduced_production_grid_points
286
+ ]
287
+ ]
288
288
  energy_query_grid = np.array(energy_query_grid)
289
289
 
290
290
  self._logger.debug(f"Grid points with energy shape: {grid_points_energy.shape}")
@@ -15,6 +15,7 @@ from pathlib import Path
15
15
  import astropy.units as u
16
16
  from astropy.table import QTable
17
17
 
18
+ from simtools import settings
18
19
  from simtools.data_model.metadata_collector import MetadataCollector
19
20
  from simtools.model.model_utils import initialize_simulation_models
20
21
 
@@ -24,10 +25,6 @@ class IncidentAnglesCalculator:
24
25
 
25
26
  Parameters
26
27
  ----------
27
- simtel_path : str or pathlib.Path
28
- Path to the sim_telarray installation directory (containing ``sim_telarray/bin``).
29
- db_config : dict
30
- Database configuration passed to ``initialize_simulation_models``.
31
28
  config_data : dict
32
29
  Simulation configuration (e.g. ``site``, ``telescope``, ``model_version``,
33
30
  ``off_axis_angle``, ``source_distance``, ``number_of_photons``).
@@ -48,15 +45,12 @@ class IncidentAnglesCalculator:
48
45
 
49
46
  def __init__(
50
47
  self,
51
- simtel_path,
52
- db_config,
53
48
  config_data,
54
49
  output_dir,
55
50
  label=None,
56
51
  ):
57
52
  self.logger = logging.getLogger(__name__)
58
53
 
59
- self._simtel_path = Path(simtel_path)
60
54
  self.config_data = config_data
61
55
  self.output_dir = Path(output_dir)
62
56
  self.label = label or f"incident_angles_{config_data['telescope']}"
@@ -82,7 +76,6 @@ class IncidentAnglesCalculator:
82
76
  )
83
77
  self.telescope_model, self.site_model, _ = initialize_simulation_models(
84
78
  label=self.label,
85
- db_config=db_config,
86
79
  site=config_data["site"],
87
80
  telescope_name=config_data["telescope"],
88
81
  model_version=config_data["model_version"],
@@ -216,8 +209,6 @@ class IncidentAnglesCalculator:
216
209
  Path to the generated shell script.
217
210
  """
218
211
  script_path = self.scripts_dir / f"run_incident_angles_{self._label_suffix()}.sh"
219
- simtel_bin = self._simtel_path / "sim_telarray/bin/sim_telarray_debug_trace"
220
- corsika_dummy = self._simtel_path / "sim_telarray/run9991.corsika.gz"
221
212
 
222
213
  theta = self.ZENITH_ANGLE_DEG
223
214
  off = float(self.config_data["off_axis_angle"].to_value(u.deg))
@@ -258,7 +249,10 @@ class IncidentAnglesCalculator:
258
249
  cfg("camera_filter", "none"),
259
250
  ]
260
251
 
261
- command = f"{simtel_bin} {' '.join(opts)} {corsika_dummy}"
252
+ command = (
253
+ f"{settings.config.sim_telarray_exe_debug_trace} {' '.join(opts)} "
254
+ f"{settings.config.corsika_dummy_file}"
255
+ )
262
256
  with script_path.open("w", encoding="utf-8") as sh:
263
257
  sh.write("#!/usr/bin/env bash\n\n")
264
258
  sh.write("set -e\nset -o pipefail\n\n")
@@ -28,17 +28,15 @@ class MirrorPanelPSF:
28
28
  Application label.
29
29
  args_dict: dict
30
30
  Dictionary with input arguments.
31
- db_config:
32
- Dictionary with database configuration.
33
31
  """
34
32
 
35
- def __init__(self, label, args_dict, db_config):
33
+ def __init__(self, label, args_dict):
36
34
  """Initialize the MirrorPanelPSF class."""
37
35
  self._logger = logging.getLogger(__name__)
38
36
  self._logger.debug("Initializing MirrorPanelPSF")
39
37
 
40
38
  self.args_dict = args_dict
41
- self.telescope_model, self.site_model = self._define_telescope_model(label, db_config)
39
+ self.telescope_model, self.site_model = self._define_telescope_model(label)
42
40
 
43
41
  if self.args_dict["test"]:
44
42
  self.args_dict["number_of_mirrors_to_test"] = 2
@@ -56,7 +54,7 @@ class MirrorPanelPSF:
56
54
  self.results_mean = []
57
55
  self.results_sig = []
58
56
 
59
- def _define_telescope_model(self, label, db_config):
57
+ def _define_telescope_model(self, label):
60
58
  """
61
59
  Define telescope model.
62
60
 
@@ -72,7 +70,6 @@ class MirrorPanelPSF:
72
70
  """
73
71
  tel_model, site_model, _ = initialize_simulation_models(
74
72
  label=label,
75
- db_config=db_config,
76
73
  site=self.args_dict["site"],
77
74
  telescope_name=self.args_dict["telescope"],
78
75
  model_version=self.args_dict["model_version"],
@@ -225,7 +222,6 @@ class MirrorPanelPSF:
225
222
  ray = RayTracing(
226
223
  telescope_model=self.telescope_model,
227
224
  site_model=self.site_model,
228
- simtel_path=self.args_dict.get("simtel_path", None),
229
225
  single_mirror_mode=True,
230
226
  mirror_numbers=(
231
227
  list(range(1, self.args_dict["number_of_mirrors_to_test"] + 1))
@@ -17,6 +17,7 @@ import astropy.units as u
17
17
  import matplotlib.pyplot as plt
18
18
  import numpy as np
19
19
 
20
+ from simtools import settings
20
21
  from simtools.utils.general import collect_kwargs, set_default_kwargs
21
22
 
22
23
 
@@ -36,8 +37,6 @@ class PSFImage:
36
37
  Scatter area of all photons in cm^2. If not given, effective area cannot be computed.
37
38
  containment_fraction: float
38
39
  Containment fraction for PSF calculation.
39
- simtel_path: str
40
- Path to sim_telarray installation.
41
40
  """
42
41
 
43
42
  __PSF_RADIUS = "Radius [cm]"
@@ -48,11 +47,9 @@ class PSFImage:
48
47
  focal_length=None,
49
48
  total_scattered_area=None,
50
49
  containment_fraction=None,
51
- simtel_path=None,
52
50
  ):
53
51
  """Initialize PSFImage class."""
54
52
  self._logger = logging.getLogger(__name__)
55
- self.simtel_path = simtel_path
56
53
 
57
54
  self._total_photons = None
58
55
  self._number_of_detected_photons = None
@@ -97,20 +94,23 @@ class PSFImage:
97
94
  Name of sim_telarray file with photon list.
98
95
  """
99
96
  try:
100
- rx_output = subprocess.Popen( # pylint: disable=consider-using-with
97
+ with subprocess.Popen(
101
98
  shlex.split(
102
- f"{self.simtel_path}/sim_telarray/bin/rx -f {self._containment_fraction:.2f} -v"
99
+ f"{settings.config.sim_telarray_path}/bin/rx "
100
+ f"-f {self._containment_fraction:.2f} -v"
103
101
  ),
104
102
  stdin=subprocess.PIPE,
105
103
  stdout=subprocess.PIPE,
106
- )
107
- with gzip.open(photon_file, "rb") as _stdin:
108
- with rx_output.stdin:
109
- shutil.copyfileobj(_stdin, rx_output.stdin)
110
- try:
111
- rx_output = rx_output.communicate()[0].splitlines()[-1:][0].split()
112
- except IndexError as e:
113
- raise IndexError(f"Unexpected output format from rx: {rx_output}") from e
104
+ ) as rx_process:
105
+ with gzip.open(photon_file, "rb") as _stdin:
106
+ with rx_process.stdin:
107
+ shutil.copyfileobj(_stdin, rx_process.stdin)
108
+ try:
109
+ rx_output = rx_process.communicate()[0].splitlines()[-1:][0].split()
110
+ except IndexError as e:
111
+ raise IndexError(
112
+ f"Unexpected output format from rx: {rx_process}"
113
+ ) from e
114
114
  except FileNotFoundError as e:
115
115
  raise FileNotFoundError(f"Photon list file not found: {photon_file}") from e
116
116
 
@@ -384,7 +384,6 @@ class PSFImage:
384
384
  if radius is not found (found_radius is False)
385
385
  """
386
386
  r0, r1 = rad_min, rad_min + dr
387
- s0, s1 = 0, 0
388
387
  found_radius = False
389
388
  while not found_radius:
390
389
  s0, s1 = self._sum_photons_in_radius(r0), self._sum_photons_in_radius(r1)
@@ -497,10 +496,10 @@ class PSFImage:
497
496
  radius_all = radius.to(u.cm).value if isinstance(radius, u.Quantity) else radius
498
497
  else:
499
498
  radius_all = list(np.linspace(0, 1.6 * self.get_psf(0.8), 30))
500
-
501
- intensity = []
502
- for rad in radius_all:
503
- intensity.append(self._sum_photons_in_radius(rad) / self._number_of_detected_photons)
499
+ intensity = [
500
+ self._sum_photons_in_radius(rad) / self._number_of_detected_photons
501
+ for rad in radius_all
502
+ ]
504
503
  d_type = {
505
504
  "names": (self.__PSF_RADIUS, self.__PSF_CUMULATIVE),
506
505
  "formats": ("f8", "f8"),
@@ -861,7 +861,6 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars):
861
861
  ray = RayTracing(
862
862
  telescope_model=tel_model,
863
863
  site_model=site_model,
864
- simtel_path=args_dict["simtel_path"],
865
864
  zenith_angle=args_dict["zenith"] * u.deg,
866
865
  source_distance=args_dict["src_distance"] * u.km,
867
866
  off_axis_angle=[0.0] * u.deg,
@@ -5,7 +5,6 @@ import logging
5
5
  import shutil
6
6
  from copy import copy
7
7
  from math import pi, tan
8
- from pathlib import Path
9
8
 
10
9
  import astropy.io.ascii
11
10
  import astropy.units as u
@@ -33,8 +32,6 @@ class RayTracing:
33
32
  telescope model
34
33
  site_model: SiteModel
35
34
  site model
36
- simtel_path: str (or Path)
37
- Location of sim_telarray installation.
38
35
  label: str
39
36
  label used for output file naming.
40
37
  zenith_angle: astropy.units.Quantity
@@ -64,7 +61,6 @@ class RayTracing:
64
61
  self,
65
62
  telescope_model,
66
63
  site_model,
67
- simtel_path,
68
64
  label=None,
69
65
  zenith_angle=20.0 * u.deg,
70
66
  off_axis_angle=[0.0] * u.deg,
@@ -78,7 +74,6 @@ class RayTracing:
78
74
  self._logger = logging.getLogger(__name__)
79
75
  self._logger.debug(f"Initializing RayTracing class {single_mirror_mode}")
80
76
 
81
- self.simtel_path = Path(simtel_path)
82
77
  self._io_handler = io_handler.IOHandler()
83
78
 
84
79
  self.telescope_model, self.site_model = telescope_model, site_model
@@ -212,7 +207,6 @@ class RayTracing:
212
207
  f"Simulating RayTracing for off_axis={this_off_axis}, mirror={mirror_number}"
213
208
  )
214
209
  simtel = SimulatorRayTracing(
215
- simtel_path=self.simtel_path,
216
210
  telescope_model=self.telescope_model,
217
211
  site_model=self.site_model,
218
212
  test=test,
@@ -408,11 +402,7 @@ class RayTracing:
408
402
  PSFImage
409
403
  PSF image object.
410
404
  """
411
- image = PSFImage(
412
- focal_length=focal_length,
413
- containment_fraction=containment_fraction,
414
- simtel_path=self.simtel_path,
415
- )
405
+ image = PSFImage(focal_length=focal_length, containment_fraction=containment_fraction)
416
406
  image.process_photon_list(photons_file, use_rx)
417
407
  self._psf_images[this_off_axis] = copy(image)
418
408
  return image
@@ -623,10 +613,11 @@ class RayTracing:
623
613
  -------
624
614
  List of PSFImages
625
615
  """
626
- images = []
627
- for this_off_axis in self.off_axis_angle:
628
- if self._psf_images and this_off_axis in self._psf_images:
629
- images.append(self._psf_images[this_off_axis])
616
+ images = [
617
+ self._psf_images[this_off_axis]
618
+ for this_off_axis in self.off_axis_angle
619
+ if self._psf_images and this_off_axis in self._psf_images
620
+ ]
630
621
  if len(images) == 0:
631
622
  self._logger.warning("No image found")
632
623
  return None
@@ -16,11 +16,10 @@ logger = logging.getLogger()
16
16
  class ReportGenerator:
17
17
  """Automate report generation."""
18
18
 
19
- def __init__(self, db_config, args, output_path):
19
+ def __init__(self, args, output_path):
20
20
  """Initialise class."""
21
21
  self._logger = logging.getLogger(__name__)
22
- self.db = db_handler.DatabaseHandler(db_config=db_config)
23
- self.db_config = db_config
22
+ self.db = db_handler.DatabaseHandler()
24
23
  self.args = args
25
24
  self.output_path = output_path
26
25
 
@@ -99,7 +98,7 @@ class ReportGenerator:
99
98
  )
100
99
 
101
100
  output_path = Path(self.output_path) / str(model_version)
102
- ReadParameters(self.db_config, self.args, output_path).produce_array_element_report()
101
+ ReadParameters(self.args, output_path).produce_array_element_report()
103
102
 
104
103
  logger.info(
105
104
  f"Markdown report generated for {site} "
@@ -167,9 +166,7 @@ class ReportGenerator:
167
166
  }
168
167
  )
169
168
 
170
- ReadParameters(
171
- self.db_config, self.args, self.output_path
172
- ).produce_model_parameter_reports()
169
+ ReadParameters(self.args, self.output_path).produce_model_parameter_reports()
173
170
 
174
171
  logger.info(
175
172
  f"Markdown report generated for {site} Telescope {telescope}: {self.output_path}"
@@ -211,7 +208,7 @@ class ReportGenerator:
211
208
  )
212
209
 
213
210
  output_path = Path(self.output_path) / str(model_version)
214
- ReadParameters(self.db_config, self.args, output_path).produce_observatory_report()
211
+ ReadParameters(self.args, output_path).produce_observatory_report()
215
212
 
216
213
  logger.info(f"Observatory report generated for {site} (v{model_version}): {output_path}")
217
214
 
@@ -237,9 +234,7 @@ class ReportGenerator:
237
234
  self.args.update({"model_version": version})
238
235
  output_path = Path(self.output_path) / str(version)
239
236
 
240
- ReadParameters(
241
- self.db_config, self.args, output_path
242
- ).produce_simulation_configuration_report()
237
+ ReadParameters(self.args, output_path).produce_simulation_configuration_report()
243
238
 
244
239
  logger.info(f"Configuration reports for (v{version}) produced: {output_path}")
245
240
 
@@ -262,7 +257,7 @@ class ReportGenerator:
262
257
  output_path = Path(self.output_path) / str(version)
263
258
 
264
259
  try:
265
- ReadParameters(self.db_config, self.args, output_path).produce_calibration_reports()
260
+ ReadParameters(self.args, output_path).produce_calibration_reports()
266
261
  logger.info(f"Calibration reports for (v{version}) produced: {output_path}")
267
262
  except ValueError as err:
268
263
  # Some model versions do not have calibration_devices in the DB;
@@ -305,7 +300,7 @@ class ReportGenerator:
305
300
 
306
301
  # Generate parameter comparison reports for calibration devices
307
302
  ReadParameters(
308
- self.db_config, version_args, self.output_path
303
+ version_args, self.output_path
309
304
  ).generate_model_parameter_reports_for_devices(array_elements)
310
305
 
311
306
  logger.info(