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
@@ -1,4 +1,4 @@
1
- """Definition of the ArrayModel class."""
1
+ """Array model represents an observatory consisting of site, telescopes, and further devices."""
2
2
 
3
3
  import logging
4
4
  from pathlib import Path
@@ -9,9 +9,10 @@ from astropy.table import QTable
9
9
  from simtools.data_model import data_reader, schema
10
10
  from simtools.io import io_handler
11
11
  from simtools.model.calibration_model import CalibrationModel
12
+ from simtools.model.model_utils import read_overwrite_model_parameter_dict
12
13
  from simtools.model.site_model import SiteModel
13
14
  from simtools.model.telescope_model import TelescopeModel
14
- from simtools.simtel.simtel_config_writer import SimtelConfigWriter
15
+ from simtools.simtel import simtel_config_writer, simtel_seeds
15
16
  from simtools.utils import general, names
16
17
 
17
18
 
@@ -21,8 +22,6 @@ class ArrayModel:
21
22
 
22
23
  Parameters
23
24
  ----------
24
- db_config: dict
25
- Database configuration.
26
25
  model_version: str
27
26
  Model version.
28
27
  label: str, optional
@@ -36,28 +35,22 @@ class ArrayModel:
36
35
  the array element positions).
37
36
  calibration_device_types: List[str], optional
38
37
  List of calibration device types (e.g., 'flat_fielding') attached to each telescope.
39
- simtel_path: str, Path, optional
40
- Path to the sim_telarray installation directory.
41
38
  overwrite_model_parameters: str, optional
42
39
  File name to overwrite model parameters from DB with provided values.
43
40
  """
44
41
 
45
42
  def __init__(
46
43
  self,
47
- db_config,
48
44
  model_version,
49
45
  label=None,
50
46
  site=None,
51
47
  layout_name=None,
52
48
  array_elements=None,
53
49
  calibration_device_types=None,
54
- simtel_path=None,
55
50
  overwrite_model_parameters=None,
56
51
  ):
57
52
  """Initialize ArrayModel."""
58
53
  self._logger = logging.getLogger(__name__)
59
- self._logger.debug("Init ArrayModel")
60
- self.db_config = db_config
61
54
  self.model_version = model_version
62
55
  self.label = label
63
56
  self.layout_name = (
@@ -69,7 +62,9 @@ class ArrayModel:
69
62
  self._config_file_directory = None
70
63
  self.io_handler = io_handler.IOHandler()
71
64
 
72
- self.overwrite_model_parameters = overwrite_model_parameters
65
+ self.overwrite_model_parameter_dict = read_overwrite_model_parameter_dict(
66
+ overwrite_model_parameters
67
+ )
73
68
 
74
69
  self.array_elements, self.site_model, self.telescope_models, self.calibration_models = (
75
70
  self._initialize(site, array_elements, calibration_device_types)
@@ -77,8 +72,7 @@ class ArrayModel:
77
72
 
78
73
  self._telescope_model_files_exported = False
79
74
  self._array_model_file_exported = False
80
- self._sim_telarray_seeds = None
81
- self.simtel_path = simtel_path
75
+ self.sim_telarray_seed = None
82
76
 
83
77
  def _initialize(self, site, array_elements_config, calibration_device_types):
84
78
  """
@@ -105,10 +99,9 @@ class ArrayModel:
105
99
  self._logger.debug(f"Getting site parameters from DB ({site})")
106
100
  site_model = SiteModel(
107
101
  site=names.validate_site_name(site),
108
- db_config=self.db_config,
109
102
  model_version=self.model_version,
110
103
  label=self.label,
111
- overwrite_model_parameters=self.overwrite_model_parameters,
104
+ overwrite_model_parameter_dict=self.overwrite_model_parameter_dict,
112
105
  )
113
106
 
114
107
  # Case 1: array_elements is a file name
@@ -136,41 +129,6 @@ class ArrayModel:
136
129
 
137
130
  return array_elements, site_model, telescope_models, calibration_models
138
131
 
139
- @property
140
- def sim_telarray_seeds(self):
141
- """
142
- Return sim_telarray seeds.
143
-
144
- Returns
145
- -------
146
- dict
147
- Dictionary with sim_telarray seeds.
148
- """
149
- return self._sim_telarray_seeds
150
-
151
- @sim_telarray_seeds.setter
152
- def sim_telarray_seeds(self, value):
153
- """
154
- Set sim_telarray seeds.
155
-
156
- Parameters
157
- ----------
158
- value: dict
159
- Dictionary with sim_telarray seeds.
160
- """
161
- if isinstance(value, dict):
162
- required_keys = {
163
- "seed",
164
- "random_instrument_instances",
165
- "seed_file_name",
166
- }
167
- if not required_keys.issubset(value):
168
- raise ValueError(
169
- "sim_telarray_seeds dictionary must contain the following keys: "
170
- f"{required_keys}"
171
- )
172
- self._sim_telarray_seeds = value
173
-
174
132
  @property
175
133
  def config_file_path(self):
176
134
  """
@@ -250,9 +208,8 @@ class ArrayModel:
250
208
  site=site_model.site,
251
209
  telescope_name=element_name,
252
210
  model_version=self.model_version,
253
- db_config=self.db_config,
254
211
  label=self.label,
255
- overwrite_model_parameters=self.overwrite_model_parameters,
212
+ overwrite_model_parameter_dict=self.overwrite_model_parameter_dict,
256
213
  )
257
214
  calibration_models[element_name] = self._build_calibration_models(
258
215
  telescope_models[element_name],
@@ -282,10 +239,9 @@ class ArrayModel:
282
239
  calibration_models[device_name] = CalibrationModel(
283
240
  site=site_model.site,
284
241
  calibration_device_model_name=device_name,
285
- db_config=self.db_config,
286
242
  model_version=self.model_version,
287
243
  label=self.label,
288
- overwrite_model_parameters=self.overwrite_model_parameters,
244
+ overwrite_model_parameter_dict=self.overwrite_model_parameter_dict,
289
245
  )
290
246
  return calibration_models
291
247
 
@@ -300,7 +256,6 @@ class ArrayModel:
300
256
  for tel_model in self.telescope_models.values():
301
257
  name = tel_model.name
302
258
  if name not in exported_models:
303
- self._logger.debug(f"Exporting configuration file for telescope {name}")
304
259
  tel_model.write_sim_telarray_config_file(
305
260
  additional_models=self.calibration_models.get(tel_model.name)
306
261
  )
@@ -317,12 +272,11 @@ class ArrayModel:
317
272
  self.site_model.export_model_files()
318
273
 
319
274
  self._logger.info(f"Writing array configuration file into {self.config_file_path}")
320
- simtel_writer = SimtelConfigWriter(
275
+ simtel_writer = simtel_config_writer.SimtelConfigWriter(
321
276
  site=self.site_model.site,
322
277
  layout_name=self.layout_name,
323
278
  model_version=self.model_version,
324
279
  label=self.label,
325
- simtel_path=self.simtel_path,
326
280
  )
327
281
  simtel_writer.write_array_config_file(
328
282
  config_file_path=self.config_file_path,
@@ -543,10 +497,16 @@ class ArrayModel:
543
497
  dict
544
498
  Dictionary with additional metadata.
545
499
  """
546
- metadata = {}
547
- if self.sim_telarray_seeds is not None:
548
- metadata.update(self.sim_telarray_seeds)
549
-
550
- metadata["nsb_integrated_flux"] = self.site_model.get_nsb_integrated_flux()
500
+ return {
501
+ "nsb_integrated_flux": self.site_model.get_nsb_integrated_flux(),
502
+ }
551
503
 
552
- return metadata
504
+ def initialize_seeds(self, zenith_angle=None, azimuth_angle=None):
505
+ """Initialize sim_telarray seeds for instrument and shower simulations."""
506
+ self.sim_telarray_seed = simtel_seeds.SimtelSeeds(
507
+ output_path=self.get_config_directory(),
508
+ site=self.site_model.site,
509
+ model_version=self.model_version,
510
+ zenith_angle=zenith_angle,
511
+ azimuth_angle=azimuth_angle,
512
+ )
@@ -17,34 +17,30 @@ class CalibrationModel(ModelParameter):
17
17
  Site name (e.g., South or North).
18
18
  calibration_device_model_name: str
19
19
  Calibration device model name (ex. ILLS-01, ILLN-01, ...).
20
- db_config: dict
21
- Database configuration.
22
20
  model_version: str
23
21
  Model version.
24
22
  label: str, optional
25
23
  Instance label. Important for output file naming.
26
- overwrite_model_parameters: str, optional
27
- File name to overwrite model parameters from DB with provided values.
24
+ overwrite_model_parameter_dict: dict, optional
25
+ Dictionary to overwrite model parameters from DB with provided values.
28
26
  """
29
27
 
30
28
  def __init__(
31
29
  self,
32
30
  site,
33
31
  calibration_device_model_name,
34
- db_config,
35
32
  model_version,
36
33
  label=None,
37
- overwrite_model_parameters=None,
34
+ overwrite_model_parameter_dict=None,
38
35
  ):
39
36
  """Initialize CalibrationModel."""
40
37
  super().__init__(
41
38
  site=site,
42
39
  array_element_name=calibration_device_model_name,
43
40
  collection="calibration_devices",
44
- db_config=db_config,
45
41
  model_version=model_version,
46
42
  label=label,
47
- overwrite_model_parameters=overwrite_model_parameters,
43
+ overwrite_model_parameter_dict=overwrite_model_parameter_dict,
48
44
  )
49
45
 
50
46
  self._logger = logging.getLogger(__name__)
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/python3
2
+ """
3
+ Handling of legacy model parameters for backward compatibility.
4
+
5
+ Collects routines to convert legacy model parameters to more recent
6
+ formats. This is a fine-tuned process and requires to hard wire the
7
+ changes. All code related to legacy model parameters should go into
8
+ this module.
9
+
10
+ """
11
+
12
+ import logging
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ UPDATE_HANDLERS = {}
18
+
19
+
20
+ def register_update(name):
21
+ """Register update handler for legacy model parameter."""
22
+
23
+ def deco(func):
24
+ UPDATE_HANDLERS[name] = func
25
+ return func
26
+
27
+ return deco
28
+
29
+
30
+ def apply_legacy_updates_to_parameters(parameters, legacy_updates):
31
+ """Apply legacy updates to model parameters.
32
+
33
+ Modifies the parameters dictionary in-place.
34
+
35
+ Parameters
36
+ ----------
37
+ parameters: dict
38
+ Dictionary of model parameters (all parameters).
39
+ legacy_updates: dict
40
+ Dictionary of legacy updates to apply.
41
+ """
42
+ for par_name, legacy_data in legacy_updates.items():
43
+ if legacy_data is None or par_name not in parameters:
44
+ continue
45
+ for key in parameters[par_name].keys():
46
+ if key in legacy_data:
47
+ parameters[par_name][key] = legacy_data[key]
48
+ if legacy_data.get("remove_parameter", False):
49
+ parameters.pop(par_name)
50
+
51
+
52
+ def update_parameter(par_name, parameters, schema_version):
53
+ """Update legacy model parameters to recent formats.
54
+
55
+ Parameters
56
+ ----------
57
+ par_name: str
58
+ Model parameter name.
59
+ parameters: dict
60
+ Dictionary of model parameters (all parameters).
61
+ schema_version: str
62
+ Target schema version.
63
+
64
+ Returns
65
+ -------
66
+ dict
67
+ Updated model parameter.
68
+ """
69
+ handler = UPDATE_HANDLERS.get(par_name)
70
+ if handler is None:
71
+ raise ValueError(_get_unsupported_update_message(parameters[par_name], schema_version))
72
+ return handler(parameters, schema_version)
73
+
74
+
75
+ @register_update("dsum_threshold")
76
+ def _update_dsum_threshold(parameters, schema_version):
77
+ """Update legacy dsum_threshold parameter."""
78
+ para_data = parameters["dsum_threshold"]
79
+ if para_data["model_parameter_schema_version"] == "0.1.0" and schema_version == "0.2.0":
80
+ logger.info(
81
+ "Updating legacy model parameter dsum_threshold from schema version "
82
+ f"{para_data['model_parameter_schema_version']} to {schema_version}"
83
+ )
84
+ return {
85
+ para_data["parameter"]: {
86
+ "value": int(para_data["value"]),
87
+ "model_parameter_schema_version": schema_version,
88
+ }
89
+ }
90
+ raise ValueError(_get_unsupported_update_message(para_data, schema_version))
91
+
92
+
93
+ @register_update("corsika_starting_grammage")
94
+ def _update_corsika_starting_grammage(parameters, schema_version):
95
+ """Update legacy corsika_starting_grammage parameter (dummy function until model is updated)."""
96
+ logger.debug(f"No fix applied to corsika_starting_grammage to schema version {schema_version}")
97
+ return {
98
+ parameters["corsika_starting_grammage"]["parameter"]: None,
99
+ }
100
+
101
+
102
+ @register_update("flasher_pulse_shape")
103
+ def _update_flasher_pulse_shape(parameters, schema_version):
104
+ """Update legacy flasher_pulse_shape parameter."""
105
+ para_data = parameters["flasher_pulse_shape"]
106
+ if para_data["model_parameter_schema_version"] == "0.1.0" and schema_version == "0.2.0":
107
+ logger.info(
108
+ f"Updating legacy model parameter flasher_pulse_shape from schema version "
109
+ f"{para_data['model_parameter_schema_version']} to {schema_version}"
110
+ )
111
+ return {
112
+ para_data["parameter"]: {
113
+ "value": [
114
+ para_data["value"],
115
+ parameters.get("flasher_pulse_width", {}).get("value", 0.0),
116
+ parameters.get("flasher_pulse_exp_decay", {}).get("value", 0.0),
117
+ ],
118
+ "model_parameter_schema_version": schema_version,
119
+ "unit": [None, "ns", "ns"],
120
+ "type": ["string", "float64", "float64"],
121
+ },
122
+ "flasher_pulse_width": {"remove_parameter": True},
123
+ "flasher_pulse_exp_decay": {"remove_parameter": True},
124
+ }
125
+
126
+ raise ValueError(_get_unsupported_update_message(para_data, schema_version))
127
+
128
+
129
+ def _get_unsupported_update_message(para_data, schema_version):
130
+ """Get unsupported update message."""
131
+ return (
132
+ f"Unsupported update for legacy parameter {para_data['parameter']}: "
133
+ f"{para_data['model_parameter_schema_version']} to {schema_version}"
134
+ )