gammasimtools 0.25.0__py3-none-any.whl → 0.27.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 (138) hide show
  1. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/METADATA +6 -1
  2. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/RECORD +135 -130
  3. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/entry_points.txt +3 -2
  5. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/licenses/LICENSE +1 -1
  6. simtools/_version.py +2 -2
  7. simtools/application_control.py +35 -7
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +3 -3
  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 +3 -7
  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/{calculate_incident_angles.py → derive_incident_angle.py} +16 -18
  20. simtools/applications/derive_mirror_rnda.py +112 -180
  21. simtools/applications/derive_psf_parameters.py +0 -1
  22. simtools/applications/derive_pulse_shape_parameters.py +0 -1
  23. simtools/applications/derive_trigger_rates.py +1 -1
  24. simtools/applications/docs_produce_array_element_report.py +2 -8
  25. simtools/applications/docs_produce_calibration_reports.py +1 -3
  26. simtools/applications/docs_produce_model_parameter_reports.py +0 -2
  27. simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
  28. simtools/applications/generate_array_config.py +0 -1
  29. simtools/applications/generate_corsika_histograms.py +79 -229
  30. simtools/applications/generate_regular_arrays.py +76 -69
  31. simtools/applications/generate_simtel_event_data.py +2 -2
  32. simtools/applications/maintain_simulation_model_add_production.py +2 -2
  33. simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
  34. simtools/applications/plot_array_layout.py +5 -111
  35. simtools/applications/plot_simulated_event_distributions.py +57 -0
  36. simtools/applications/plot_tabular_data.py +0 -1
  37. simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
  38. simtools/applications/production_derive_corsika_limits.py +1 -1
  39. simtools/applications/production_generate_grid.py +0 -1
  40. simtools/applications/run_application.py +1 -1
  41. simtools/applications/simulate_flasher.py +3 -15
  42. simtools/applications/simulate_illuminator.py +2 -11
  43. simtools/applications/simulate_pedestals.py +1 -5
  44. simtools/applications/simulate_prod.py +8 -11
  45. simtools/applications/simulate_prod_htcondor_generator.py +1 -1
  46. simtools/applications/submit_array_layouts.py +2 -4
  47. simtools/applications/submit_data_from_external.py +2 -1
  48. simtools/applications/submit_model_parameter_from_external.py +1 -3
  49. simtools/applications/validate_camera_efficiency.py +28 -28
  50. simtools/applications/validate_camera_fov.py +0 -1
  51. simtools/applications/validate_cumulative_psf.py +1 -5
  52. simtools/applications/validate_optics.py +2 -14
  53. simtools/atmosphere.py +83 -0
  54. simtools/camera/camera_efficiency.py +171 -53
  55. simtools/camera/single_photon_electron_spectrum.py +8 -7
  56. simtools/configuration/commandline_parser.py +82 -11
  57. simtools/configuration/configurator.py +6 -11
  58. simtools/constants.py +5 -0
  59. simtools/corsika/corsika_config.py +100 -202
  60. simtools/corsika/corsika_histograms.py +561 -1708
  61. simtools/corsika/primary_particle.py +1 -1
  62. simtools/data_model/metadata_collector.py +5 -2
  63. simtools/data_model/metadata_model.py +0 -4
  64. simtools/data_model/model_data_writer.py +59 -64
  65. simtools/data_model/schema.py +2 -0
  66. simtools/data_model/validate_data.py +1 -3
  67. simtools/db/db_handler.py +23 -10
  68. simtools/db/mongo_db.py +2 -2
  69. simtools/dependencies.py +81 -38
  70. simtools/io/ascii_handler.py +55 -5
  71. simtools/io/io_handler.py +23 -12
  72. simtools/io/table_handler.py +1 -1
  73. simtools/job_execution/job_manager.py +154 -79
  74. simtools/job_execution/process_pool.py +137 -0
  75. simtools/layout/array_layout.py +4 -13
  76. simtools/layout/array_layout_utils.py +348 -57
  77. simtools/model/array_model.py +23 -63
  78. simtools/model/calibration_model.py +4 -8
  79. simtools/model/legacy_model_parameter.py +134 -0
  80. simtools/model/model_parameter.py +147 -86
  81. simtools/model/model_utils.py +40 -6
  82. simtools/model/site_model.py +4 -8
  83. simtools/model/telescope_model.py +10 -16
  84. simtools/production_configuration/derive_corsika_limits.py +6 -11
  85. simtools/production_configuration/interpolation_handler.py +16 -16
  86. simtools/ray_tracing/incident_angles.py +92 -17
  87. simtools/ray_tracing/mirror_panel_psf.py +338 -222
  88. simtools/ray_tracing/psf_analysis.py +62 -48
  89. simtools/ray_tracing/psf_parameter_optimisation.py +3 -3
  90. simtools/ray_tracing/ray_tracing.py +43 -25
  91. simtools/reporting/docs_auto_report_generator.py +8 -13
  92. simtools/reporting/docs_read_parameters.py +2 -8
  93. simtools/runners/corsika_runner.py +52 -195
  94. simtools/runners/corsika_simtel_runner.py +77 -108
  95. simtools/runners/runner_services.py +214 -213
  96. simtools/runners/simtel_runner.py +27 -160
  97. simtools/runners/simtools_runner.py +11 -73
  98. simtools/schemas/application_workflow.metaschema.yml +8 -0
  99. simtools/settings.py +173 -0
  100. simtools/{io/eventio_handler.py → sim_events/file_info.py} +3 -3
  101. simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
  102. simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
  103. simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
  104. simtools/simtel/pulse_shapes.py +7 -2
  105. simtools/simtel/simtel_config_writer.py +79 -91
  106. simtools/simtel/simtel_seeds.py +184 -0
  107. simtools/simtel/simtel_table_reader.py +6 -4
  108. simtools/simtel/simulator_array.py +114 -109
  109. simtools/simtel/simulator_camera_efficiency.py +68 -46
  110. simtools/simtel/simulator_light_emission.py +164 -132
  111. simtools/simtel/simulator_ray_tracing.py +80 -71
  112. simtools/simulator.py +137 -355
  113. simtools/telescope_trigger_rates.py +3 -4
  114. simtools/testing/assertions.py +84 -33
  115. simtools/testing/configuration.py +1 -2
  116. simtools/testing/helpers.py +2 -3
  117. simtools/testing/log_inspector.py +1 -0
  118. simtools/testing/sim_telarray_metadata.py +14 -12
  119. simtools/testing/validate_output.py +121 -42
  120. simtools/utils/general.py +43 -17
  121. simtools/utils/geometry.py +0 -77
  122. simtools/utils/names.py +5 -5
  123. simtools/utils/random.py +36 -0
  124. simtools/visualization/legend_handlers.py +7 -6
  125. simtools/visualization/plot_array_layout.py +91 -16
  126. simtools/visualization/plot_corsika_histograms.py +145 -605
  127. simtools/visualization/plot_incident_angles.py +48 -1
  128. simtools/visualization/plot_mirrors.py +1 -4
  129. simtools/visualization/plot_pixels.py +2 -4
  130. simtools/visualization/plot_psf.py +160 -19
  131. simtools/visualization/plot_simtel_event_histograms.py +4 -4
  132. simtools/visualization/plot_simtel_events.py +6 -11
  133. simtools/visualization/plot_tables.py +8 -19
  134. simtools/visualization/visualize.py +22 -2
  135. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
  136. simtools/applications/print_version.py +0 -53
  137. simtools/io/hdf5_handler.py +0 -139
  138. {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/top_level.txt +0 -0
@@ -4,13 +4,15 @@
4
4
  import logging
5
5
  import shutil
6
6
  from copy import copy, deepcopy
7
+ from pathlib import Path
7
8
 
8
9
  import astropy.units as u
9
10
 
10
11
  import simtools.utils.general as gen
11
12
  from simtools.data_model import schema
12
13
  from simtools.db import db_handler
13
- from simtools.io import ascii_handler, io_handler
14
+ from simtools.io import io_handler
15
+ from simtools.model import legacy_model_parameter
14
16
  from simtools.simtel.simtel_config_writer import SimtelConfigWriter
15
17
  from simtools.utils import names, value_conversion
16
18
 
@@ -28,8 +30,6 @@ class ModelParameter:
28
30
 
29
31
  Parameters
30
32
  ----------
31
- db_config:
32
- Database configuration dictionary.
33
33
  model_version: str
34
34
  Version of the model (ex. 5.0.0).
35
35
  site: str
@@ -41,8 +41,8 @@ class ModelParameter:
41
41
  as stored under collection in the DB.
42
42
  label: str
43
43
  Instance label. Used for output file naming.
44
- overwrite_model_parameters: str, optional
45
- File name to overwrite model parameters from DB with provided values.
44
+ overwrite_model_parameter_dict: dict, optional
45
+ Dictionary to overwrite model parameters from DB with provided values.
46
46
  Instance label. Important for output file naming.
47
47
  ignore_software_version: bool
48
48
  If True, ignore software version checks for deprecated parameters.
@@ -51,18 +51,19 @@ class ModelParameter:
51
51
 
52
52
  def __init__(
53
53
  self,
54
- db_config,
55
54
  model_version,
56
55
  site=None,
57
56
  array_element_name=None,
58
57
  collection="telescopes",
59
58
  label=None,
60
- overwrite_model_parameters=None,
59
+ overwrite_model_parameter_dict=None,
61
60
  ignore_software_version=False,
62
61
  ):
63
62
  self._logger = logging.getLogger(__name__)
64
63
  self.io_handler = io_handler.IOHandler()
65
- self.db = db_handler.DatabaseHandler(db_config=db_config)
64
+ self.db = db_handler.DatabaseHandler()
65
+ if not self.db.is_configured():
66
+ raise RuntimeError("Database is not configured.")
66
67
 
67
68
  self.parameters = {}
68
69
  self._simulation_config_parameters = {sw: {} for sw in names.simulation_software()}
@@ -81,7 +82,7 @@ class ModelParameter:
81
82
  )
82
83
  self._config_file_directory = None
83
84
  self._config_file_path = None
84
- self.overwrite_model_parameters = overwrite_model_parameters
85
+ self.overwrite_model_parameter_dict = overwrite_model_parameter_dict
85
86
  self._added_parameter_files = None
86
87
  self._is_exported_model_files_up_to_date = False
87
88
 
@@ -276,8 +277,6 @@ class ModelParameter:
276
277
  )
277
278
  self._config_file_path = self.config_file_directory.joinpath(config_file_name)
278
279
 
279
- self._logger.debug(f"Config file path: {self._config_file_path}")
280
-
281
280
  def get_simulation_software_parameters(self, simulation_software):
282
281
  """
283
282
  Get simulation software parameters.
@@ -325,37 +324,47 @@ class ModelParameter:
325
324
  self.site, self.name, self.collection, self.model_version
326
325
  )
327
326
  )
328
- if self.overwrite_model_parameters:
329
- self.overwrite_parameters_from_file(self.overwrite_model_parameters)
330
- self._check_model_parameter_software_versions(self.parameters.keys())
327
+ self.overwrite_parameters(self.overwrite_model_parameter_dict)
328
+ self._check_model_parameter_versions(self.parameters)
331
329
 
332
330
  self._load_simulation_software_parameter()
333
331
  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
- )
332
+ self._check_model_parameter_versions(parameters, software_name=software_name)
337
333
 
338
- def _check_model_parameter_software_versions(self, parameter_list, software_name=None):
334
+ def _check_model_parameter_versions(self, parameters, software_name=None):
339
335
  """
340
- Ensure that model parameters are compatible with the installed software versions.
336
+ Ensure parameters follow the latest schema and are compatible with installed software.
341
337
 
342
338
  Compares software versions listed in schema files with the installed software versions
343
339
  (e.g., sim_telarray, CORSIKA).
344
340
 
341
+ For outdated model parameter schemas, legacy update functions are called to update
342
+ the parameters to the latest schema version.
343
+
345
344
  Parameters
346
345
  ----------
347
- parameter_list: list
348
- List containing model parameter names.
346
+ parameters: dict
347
+ Dictionary containing model parameters.
349
348
  software_name: str
350
349
  Name of the software for which the parameters are checked.
351
350
  """
352
- for par_name in parameter_list:
351
+ _legacy_updates = {}
352
+ for par_name, par_data in parameters.items():
353
353
  if par_name in (parameter_schema := names.model_parameters()):
354
354
  schema.validate_deprecation_and_version(
355
355
  data=parameter_schema[par_name],
356
356
  software_name=software_name,
357
357
  ignore_software_version=self.ignore_software_version,
358
358
  )
359
+ _latest_schema_version = parameter_schema[par_name]["schema_version"]
360
+ if par_data["model_parameter_schema_version"] != _latest_schema_version:
361
+ _legacy_updates.update(
362
+ legacy_model_parameter.update_parameter(
363
+ par_name, parameters, _latest_schema_version
364
+ )
365
+ )
366
+
367
+ legacy_model_parameter.apply_legacy_updates_to_parameters(parameters, _legacy_updates)
359
368
 
360
369
  def overwrite_model_parameter(self, par_name, value, parameter_version=None):
361
370
  """
@@ -385,22 +394,20 @@ class ModelParameter:
385
394
  raise InvalidModelParameterError(f"Parameter {par_name} not in the model")
386
395
 
387
396
  if value is None and parameter_version:
388
- _para_dict = self.db.get_model_parameter(
389
- parameter=par_name,
390
- site=self.site,
391
- array_element_name=self.name,
392
- parameter_version=parameter_version,
393
- )
394
- if _para_dict:
395
- self.parameters[par_name] = _para_dict.get(par_name)
396
- self._logger.debug(
397
- f"Changing parameter {par_name} to version {parameter_version} with value "
398
- f"{self.parameters[par_name]['value']}"
399
- )
397
+ self._overwrite_model_parameter_from_db(par_name, parameter_version)
400
398
  else:
401
- value = gen.convert_string_to_list(value) if isinstance(value, str) else value
399
+ self._overwrite_model_parameter_from_value(par_name, value, parameter_version)
400
+
401
+ # In case parameter is a file, the model files will be outdated
402
+ if self.get_parameter_file_flag(par_name):
403
+ self._is_exported_model_files_up_to_date = False
404
+
405
+ def _overwrite_model_parameter_from_value(self, par_name, value, parameter_version=None):
406
+ """Overwrite model parameter from provided value only."""
407
+ value = gen.convert_string_to_list(value) if isinstance(value, str) else value
408
+ par_type = self.get_parameter_type(par_name)
402
409
 
403
- par_type = self.get_parameter_type(par_name)
410
+ if par_type in ("list", "dict"):
404
411
  if not gen.validate_data_type(
405
412
  reference_dtype=par_type,
406
413
  value=value,
@@ -408,40 +415,40 @@ class ModelParameter:
408
415
  allow_subtypes=True,
409
416
  ):
410
417
  raise ValueError(f"Could not cast {value} of type {type(value)} to {par_type}.")
418
+ else:
419
+ for value_element in gen.ensure_iterable(value):
420
+ if not gen.validate_data_type(
421
+ reference_dtype=par_type,
422
+ value=value_element,
423
+ dtype=None,
424
+ allow_subtypes=True,
425
+ ):
426
+ raise ValueError(
427
+ f"Could not cast {value_element} of type "
428
+ f"{type(value_element)} to {par_type}."
429
+ )
411
430
 
412
- self._logger.debug(
413
- f"Changing parameter {par_name} from {self.get_parameter_value(par_name)} "
414
- f"to {value}"
415
- )
416
- self.parameters[par_name]["value"] = value
417
- if parameter_version:
418
- self.parameters[par_name]["parameter_version"] = parameter_version
419
-
420
- # In case parameter is a file, the model files will be outdated
421
- if self.get_parameter_file_flag(par_name):
422
- self._is_exported_model_files_up_to_date = False
423
-
424
- def overwrite_parameters_from_file(self, file_name):
425
- """
426
- Overwrite parameters from a file.
427
-
428
- File is expected to follow the format described in 'simulation_models_info.schema.yml'.
429
-
430
- This function does not modify the DB, it affects only the current instance.
431
- This feature is intended for developers and lacks validation.
432
-
433
- Parameters
434
- ----------
435
- file_name: str
436
- File containing the parameters to be changed.
437
- """
438
- changes_data = schema.validate_dict_using_schema(
439
- data=ascii_handler.collect_data_from_file(file_name=file_name),
440
- schema_file="simulation_models_info.schema.yml",
441
- ).get("changes", {})
442
-
443
- key_for_changes = self._get_key_for_parameter_changes(self.site, self.name, changes_data)
444
- self.overwrite_parameters(changes_data.get(key_for_changes, {}) if key_for_changes else {})
431
+ self._logger.debug(
432
+ f"Changing parameter {par_name} from {self.get_parameter_value(par_name)} to {value}"
433
+ )
434
+ self.parameters[par_name]["value"] = value
435
+ if parameter_version:
436
+ self.parameters[par_name]["parameter_version"] = parameter_version
437
+
438
+ def _overwrite_model_parameter_from_db(self, par_name, parameter_version):
439
+ """Overwrite model parameter from DB for a specific version."""
440
+ _para_dict = self.db.get_model_parameter(
441
+ parameter=par_name,
442
+ site=self.site,
443
+ array_element_name=self.name,
444
+ parameter_version=parameter_version,
445
+ )
446
+ if _para_dict:
447
+ self.parameters[par_name] = _para_dict.get(par_name)
448
+ self._logger.debug(
449
+ f"Changing parameter {par_name} to version {parameter_version} with value "
450
+ f"{self.parameters[par_name]['value']}"
451
+ )
445
452
 
446
453
  def _get_key_for_parameter_changes(self, site, array_element_name, changes_data):
447
454
  """
@@ -483,7 +490,7 @@ class ModelParameter:
483
490
 
484
491
  return None
485
492
 
486
- def overwrite_parameters(self, changes):
493
+ def overwrite_parameters(self, changes, flat_dict=False):
487
494
  """
488
495
  Change the value of multiple existing parameters in the model.
489
496
 
@@ -491,23 +498,43 @@ class ModelParameter:
491
498
 
492
499
  Allows for two types of 'changes' dictionary:
493
500
 
494
- - simple: '{parameter_name: new_value, ...}'
495
- - model repository style:
496
- '{parameter_name: {"value": new_value, "version": new_version}, ...}'
501
+ - simple (flat_dict=True): '{parameter_name: new_value, ...}'
502
+ - model repository style (flat_dict=False):
503
+ '{array_element: {parameter_name: {"value": new_value, "version": new_version}, ...}}'
497
504
 
498
505
  Parameters
499
506
  ----------
500
507
  changes: dict
501
508
  Parameters to be changed.
502
509
  """
510
+ if not changes:
511
+ return
512
+ if not flat_dict:
513
+ key_for_changes = self._get_key_for_parameter_changes(self.site, self.name, changes)
514
+ changes = changes.get(key_for_changes, {})
515
+ if not changes:
516
+ return
517
+
518
+ if flat_dict:
519
+ self._logger.debug(f"Overwriting parameters with changes: {changes}")
520
+ else:
521
+ self._logger.debug(
522
+ f"Overwriting parameters for {key_for_changes} with changes: {changes}"
523
+ )
524
+
503
525
  for par_name, par_value in changes.items():
504
- if par_name in self.parameters:
505
- if isinstance(par_value, dict) and ("value" in par_value or "version" in par_value):
506
- self.overwrite_model_parameter(
507
- par_name, par_value.get("value"), par_value.get("version")
508
- )
509
- else:
510
- self.overwrite_model_parameter(par_name, par_value)
526
+ if par_name not in self.parameters:
527
+ self._logger.warning(
528
+ f"Parameter {par_name} not found in model {self.name}, cannot overwrite it."
529
+ )
530
+ continue
531
+
532
+ if isinstance(par_value, dict) and ("value" in par_value or "version" in par_value):
533
+ self.overwrite_model_parameter(
534
+ par_name, par_value.get("value"), par_value.get("version")
535
+ )
536
+ else:
537
+ self.overwrite_model_parameter(par_name, par_value)
511
538
 
512
539
  def overwrite_model_file(self, par_name, file_path):
513
540
  """
@@ -555,7 +582,29 @@ class ModelParameter:
555
582
  )
556
583
  self._is_exported_model_files_up_to_date = True
557
584
 
558
- def write_sim_telarray_config_file(self, additional_models=None):
585
+ def get_config_file_path(self, label=None):
586
+ """Return config file path for a given label.
587
+
588
+ Parameters
589
+ ----------
590
+ label : str or None
591
+ Label used for output file naming. If None, use this model's label.
592
+
593
+ Returns
594
+ -------
595
+ pathlib.Path
596
+ Path to the sim_telarray configuration file.
597
+ """
598
+ config_file_name = names.simtel_config_file_name(
599
+ self.site,
600
+ telescope_model_name=self.name,
601
+ label=self.label if label is None else label,
602
+ )
603
+ return self.config_file_directory.joinpath(config_file_name)
604
+
605
+ def write_sim_telarray_config_file(
606
+ self, additional_models=None, label=None, config_file_path=None
607
+ ):
559
608
  """
560
609
  Write the sim_telarray configuration file.
561
610
 
@@ -563,15 +612,26 @@ class ModelParameter:
563
612
  ----------
564
613
  additional_models: TelescopeModel or SiteModel
565
614
  Model object for additional parameter to be written to the config file.
615
+ label: str or None
616
+ Optional label override used for output file naming.
617
+ config_file_path: pathlib.Path or str or None
618
+ Optional explicit path of the config file. If not given, it is derived from ``label``.
566
619
  """
567
620
  self.parameters.update(self._simulation_config_parameters.get("sim_telarray", {}))
568
621
  self.export_model_files(update_if_necessary=True)
569
622
 
570
623
  self._add_additional_models(additional_models)
571
624
 
572
- self._load_simtel_config_writer()
625
+ config_file_path = (
626
+ Path(config_file_path)
627
+ if config_file_path is not None
628
+ else self.get_config_file_path(label=label)
629
+ )
630
+
631
+ # Ensure the writer label matches the config file naming label.
632
+ self._load_simtel_config_writer(label=label)
573
633
  self.simtel_config_writer.write_telescope_config_file(
574
- config_file_path=self.config_file_path,
634
+ config_file_path=config_file_path,
575
635
  parameters=self.parameters,
576
636
  )
577
637
 
@@ -602,15 +662,16 @@ class ModelParameter:
602
662
  self._set_config_file_directory_and_name()
603
663
  return self._config_file_path
604
664
 
605
- def _load_simtel_config_writer(self):
665
+ def _load_simtel_config_writer(self, label=None):
606
666
  """Load the SimtelConfigWriter object."""
607
- if self.simtel_config_writer is None:
667
+ desired_label = self.label if label is None else label
668
+ if label is not None or self.simtel_config_writer is None:
608
669
  self.simtel_config_writer = SimtelConfigWriter(
609
670
  site=self.site,
610
671
  telescope_model_name=self.name,
611
672
  telescope_design_model=self.design_model,
612
673
  model_version=self.model_version,
613
- label=self.label,
674
+ label=desired_label,
614
675
  )
615
676
 
616
677
  def export_nsb_spectrum_to_telescope_altitude_correction_file(self, model_directory):
@@ -3,6 +3,9 @@
3
3
 
4
4
  import math
5
5
 
6
+ from simtools import settings
7
+ from simtools.data_model import schema
8
+ from simtools.io import ascii_handler
6
9
  from simtools.model.calibration_model import CalibrationModel
7
10
  from simtools.model.site_model import SiteModel
8
11
  from simtools.model.telescope_model import TelescopeModel
@@ -10,7 +13,11 @@ from simtools.utils import names
10
13
 
11
14
 
12
15
  def initialize_simulation_models(
13
- label, db_config, model_version, site, telescope_name, calibration_device_name=None
16
+ label,
17
+ model_version,
18
+ site,
19
+ telescope_name,
20
+ calibration_device_name=None,
14
21
  ):
15
22
  """
16
23
  Initialize simulation models for a single telescope, site, and calibration device model.
@@ -19,8 +26,6 @@ def initialize_simulation_models(
19
26
  ----------
20
27
  label: str
21
28
  Label for the simulation.
22
- db_config: dict
23
- Database configuration.
24
29
  model_version: str
25
30
  Version of the simulation model
26
31
  site: str
@@ -35,26 +40,28 @@ def initialize_simulation_models(
35
40
  Tuple
36
41
  Tuple containing the telescope site, (optional) calibration device model.
37
42
  """
43
+ overwrite_model_parameter_dict = read_overwrite_model_parameter_dict()
44
+
38
45
  tel_model = TelescopeModel(
39
46
  site=site,
40
47
  telescope_name=telescope_name,
41
- db_config=db_config,
42
48
  model_version=model_version,
43
49
  label=label,
50
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
44
51
  )
45
52
  site_model = SiteModel(
46
53
  site=site,
47
54
  model_version=model_version,
48
- db_config=db_config,
49
55
  label=label,
56
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
50
57
  )
51
58
  if calibration_device_name is not None:
52
59
  calibration_model = CalibrationModel(
53
60
  site=site,
54
61
  calibration_device_model_name=calibration_device_name,
55
- db_config=db_config,
56
62
  model_version=model_version,
57
63
  label=label,
64
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
58
65
  )
59
66
  else:
60
67
  calibration_model = None
@@ -63,6 +70,33 @@ def initialize_simulation_models(
63
70
  return tel_model, site_model, calibration_model
64
71
 
65
72
 
73
+ def read_overwrite_model_parameter_dict(overwrite_model_parameters=None):
74
+ """
75
+ Read overwrite model parameters dictionary from file.
76
+
77
+ Parameters
78
+ ----------
79
+ overwrite_model_parameters: str, optional
80
+ File name with overwrite model parameters.
81
+
82
+ Returns
83
+ -------
84
+ dict
85
+ Dictionary with model parameters to overwrite.
86
+ """
87
+ overwrite_model_parameter_dict = {}
88
+ overwrite_model_parameters = overwrite_model_parameters or settings.config.args.get(
89
+ "overwrite_model_parameters"
90
+ )
91
+ if overwrite_model_parameters is not None:
92
+ overwrite_model_parameter_dict = schema.validate_dict_using_schema(
93
+ data=ascii_handler.collect_data_from_file(file_name=overwrite_model_parameters),
94
+ schema_file="simulation_models_info.schema.yml",
95
+ ).get("changes", {})
96
+
97
+ return overwrite_model_parameter_dict
98
+
99
+
66
100
  def compute_telescope_transmission(pars: list[float], off_axis: float) -> float:
67
101
  """
68
102
  Compute telescope transmission (0 < T < 1) for a given off-axis angle.
@@ -26,14 +26,12 @@ 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
34
32
  Instance label.
35
- overwrite_model_parameters: str, optional
36
- File name to overwrite model parameters from DB with provided values.
33
+ overwrite_model_parameter_dict: dict, optional
34
+ Dictionary to overwrite model parameters from DB with provided values.
37
35
  ignore_software_version: bool, optional
38
36
  If True, ignore software version checks for deprecated parameters.
39
37
  """
@@ -41,10 +39,9 @@ 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
- overwrite_model_parameters=None,
44
+ overwrite_model_parameter_dict=None,
48
45
  ignore_software_version=False,
49
46
  ):
50
47
  """Initialize SiteModel."""
@@ -52,11 +49,10 @@ 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",
59
- overwrite_model_parameters=overwrite_model_parameters,
55
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
60
56
  ignore_software_version=ignore_software_version,
61
57
  )
62
58
 
@@ -26,14 +26,12 @@ 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
34
32
  Instance label.
35
- overwrite_model_parameters: str, optional
36
- File name to overwrite model parameters from DB with provided values.
33
+ overwrite_model_parameter_dict: dict, optional
34
+ Dictionary to overwrite model parameters from DB with provided values.
37
35
  ignore_software_version: bool, optional
38
36
  If True, ignore software version checks for deprecated parameters.
39
37
  """
@@ -42,25 +40,22 @@ 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
- overwrite_model_parameters=None,
45
+ overwrite_model_parameter_dict=None,
49
46
  ignore_software_version=False,
50
47
  ):
51
48
  """Initialize TelescopeModel."""
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
- overwrite_model_parameters=overwrite_model_parameters,
54
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
59
55
  ignore_software_version=ignore_software_version,
60
56
  )
61
57
 
62
58
  self._logger = logging.getLogger(__name__)
63
- self._logger.debug("Init TelescopeModel %s %s", site, telescope_name)
64
59
 
65
60
  self._single_mirror_list_file_paths = None
66
61
  self._mirrors = None
@@ -326,13 +321,12 @@ class TelescopeModel(ModelParameter):
326
321
  average_curve: astropy.table.Table
327
322
  Instance of astropy.table.Table with the averaged curve.
328
323
  """
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
- )
324
+ weights = [
325
+ incidence_angle_dist["Fraction"][
326
+ np.nanargmin(np.abs(angle_now - incidence_angle_dist["Incidence angle"].value))
327
+ ]
328
+ for angle_now in curves["Angle"]
329
+ ]
336
330
 
337
331
  return Table(
338
332
  [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.