gammasimtools 0.22.0__py3-none-any.whl → 0.24.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 (128) hide show
  1. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/METADATA +2 -1
  2. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/RECORD +128 -125
  3. simtools/_version.py +2 -2
  4. simtools/application_control.py +118 -0
  5. simtools/applications/calculate_incident_angles.py +17 -22
  6. simtools/applications/convert_all_model_parameters_from_simtel.py +28 -43
  7. simtools/applications/convert_geo_coordinates_of_array_elements.py +26 -45
  8. simtools/applications/convert_model_parameter_from_simtel.py +21 -41
  9. simtools/applications/db_add_file_to_db.py +13 -14
  10. simtools/applications/db_add_simulation_model_from_repository_to_db.py +20 -33
  11. simtools/applications/db_add_value_from_json_to_db.py +29 -24
  12. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +20 -35
  13. simtools/applications/db_generate_compound_indexes.py +11 -13
  14. simtools/applications/db_get_array_layouts_from_db.py +20 -40
  15. simtools/applications/db_get_file_from_db.py +15 -17
  16. simtools/applications/db_get_parameter_from_db.py +33 -35
  17. simtools/applications/db_inspect_databases.py +13 -12
  18. simtools/applications/db_upload_model_repository.py +13 -31
  19. simtools/applications/derive_ctao_array_layouts.py +16 -21
  20. simtools/applications/derive_mirror_rnda.py +9 -14
  21. simtools/applications/derive_photon_electron_spectrum.py +7 -10
  22. simtools/applications/derive_psf_parameters.py +13 -20
  23. simtools/applications/derive_trigger_rates.py +6 -9
  24. simtools/applications/docs_produce_array_element_report.py +22 -23
  25. simtools/applications/docs_produce_calibration_reports.py +26 -24
  26. simtools/applications/docs_produce_model_parameter_reports.py +15 -22
  27. simtools/applications/docs_produce_simulation_configuration_report.py +21 -22
  28. simtools/applications/generate_array_config.py +14 -33
  29. simtools/applications/generate_corsika_histograms.py +22 -43
  30. simtools/applications/generate_default_metadata.py +15 -36
  31. simtools/applications/generate_regular_arrays.py +11 -15
  32. simtools/applications/generate_simtel_event_data.py +23 -33
  33. simtools/applications/maintain_simulation_model_add_production.py +20 -37
  34. simtools/applications/maintain_simulation_model_compare_productions.py +10 -12
  35. simtools/applications/maintain_simulation_model_verify_production_tables.py +8 -11
  36. simtools/applications/merge_tables.py +14 -23
  37. simtools/applications/plot_array_layout.py +77 -54
  38. simtools/applications/plot_simtel_events.py +11 -13
  39. simtools/applications/plot_tabular_data.py +17 -38
  40. simtools/applications/plot_tabular_data_for_model_parameter.py +16 -23
  41. simtools/applications/print_version.py +14 -42
  42. simtools/applications/production_derive_corsika_limits.py +5 -9
  43. simtools/applications/production_derive_statistics.py +12 -25
  44. simtools/applications/production_generate_grid.py +20 -48
  45. simtools/applications/production_merge_corsika_limits.py +17 -21
  46. simtools/applications/run_application.py +12 -32
  47. simtools/applications/simulate_flasher.py +21 -25
  48. simtools/applications/simulate_illuminator.py +7 -14
  49. simtools/applications/simulate_pedestals.py +13 -13
  50. simtools/applications/simulate_prod.py +21 -33
  51. simtools/applications/simulate_prod_htcondor_generator.py +11 -25
  52. simtools/applications/submit_array_layouts.py +16 -19
  53. simtools/applications/submit_data_from_external.py +18 -34
  54. simtools/applications/submit_model_parameter_from_external.py +27 -40
  55. simtools/applications/validate_camera_efficiency.py +23 -21
  56. simtools/applications/validate_camera_fov.py +21 -26
  57. simtools/applications/validate_cumulative_psf.py +27 -35
  58. simtools/applications/validate_file_using_schema.py +15 -33
  59. simtools/applications/validate_optics.py +27 -33
  60. simtools/camera/camera_efficiency.py +0 -2
  61. simtools/configuration/commandline_parser.py +39 -13
  62. simtools/configuration/configurator.py +1 -6
  63. simtools/corsika/corsika_config.py +2 -9
  64. simtools/data_model/data_reader.py +0 -2
  65. simtools/data_model/metadata_collector.py +0 -2
  66. simtools/data_model/model_data_writer.py +1 -3
  67. simtools/data_model/schema.py +36 -34
  68. simtools/data_model/validate_data.py +0 -2
  69. simtools/db/db_handler.py +61 -296
  70. simtools/db/db_model_upload.py +1 -1
  71. simtools/db/mongo_db.py +535 -0
  72. simtools/dependencies.py +33 -8
  73. simtools/io/hdf5_handler.py +0 -5
  74. simtools/io/legacy_data_handler.py +0 -5
  75. simtools/job_execution/job_manager.py +0 -3
  76. simtools/layout/array_layout.py +7 -9
  77. simtools/layout/array_layout_utils.py +3 -3
  78. simtools/layout/telescope_position.py +0 -2
  79. simtools/model/array_model.py +38 -71
  80. simtools/model/calibration_model.py +12 -11
  81. simtools/model/camera.py +0 -2
  82. simtools/model/mirrors.py +0 -2
  83. simtools/model/model_parameter.py +200 -140
  84. simtools/model/model_repository.py +159 -35
  85. simtools/model/model_utils.py +3 -8
  86. simtools/model/site_model.py +59 -29
  87. simtools/model/telescope_model.py +21 -15
  88. simtools/production_configuration/calculate_statistical_uncertainties_grid_point.py +0 -2
  89. simtools/production_configuration/derive_production_statistics.py +0 -2
  90. simtools/production_configuration/interpolation_handler.py +0 -2
  91. simtools/ray_tracing/mirror_panel_psf.py +4 -4
  92. simtools/ray_tracing/psf_analysis.py +0 -2
  93. simtools/ray_tracing/psf_parameter_optimisation.py +1 -1
  94. simtools/ray_tracing/ray_tracing.py +0 -2
  95. simtools/reporting/docs_auto_report_generator.py +109 -1
  96. simtools/reporting/docs_read_parameters.py +4 -9
  97. simtools/runners/corsika_runner.py +0 -2
  98. simtools/runners/corsika_simtel_runner.py +0 -2
  99. simtools/runners/simtel_runner.py +0 -2
  100. simtools/schemas/model_parameters/transit_time_random.schema.yml +29 -0
  101. simtools/schemas/simulation_models_info.schema.yml +2 -1
  102. simtools/simtel/simtel_config_reader.py +0 -2
  103. simtools/simtel/simtel_config_writer.py +128 -33
  104. simtools/simtel/simtel_io_metadata.py +3 -3
  105. simtools/simtel/simulator_array.py +9 -21
  106. simtools/simtel/simulator_camera_efficiency.py +0 -2
  107. simtools/simtel/simulator_light_emission.py +1 -3
  108. simtools/simtel/simulator_ray_tracing.py +0 -2
  109. simtools/simulator.py +2 -6
  110. simtools/testing/assertions.py +52 -8
  111. simtools/testing/configuration.py +17 -4
  112. simtools/testing/validate_output.py +4 -8
  113. simtools/utils/general.py +5 -13
  114. simtools/utils/geometry.py +0 -5
  115. simtools/utils/names.py +1 -13
  116. simtools/utils/value_conversion.py +10 -5
  117. simtools/version.py +85 -0
  118. simtools/visualization/plot_array_layout.py +129 -23
  119. simtools/visualization/plot_incident_angles.py +0 -2
  120. simtools/visualization/plot_pixels.py +1 -1
  121. simtools/visualization/plot_psf.py +1 -1
  122. simtools/visualization/plot_simtel_events.py +0 -11
  123. simtools/visualization/plot_tables.py +1 -1
  124. simtools/visualization/visualize.py +0 -12
  125. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/WHEEL +0 -0
  126. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/entry_points.txt +0 -0
  127. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/licenses/LICENSE +0 -0
  128. {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,15 @@
1
1
  """Utilities for managing the simulation models repository.
2
2
 
3
3
  Simulation model parameters and production tables are managed through
4
- a gitlab repository ('SimulationModels'). This module provides service
4
+ a gitlab repository ('simulation_models'). This module provides service
5
5
  functions to interact with and verify the repository.
6
+
7
+ Main functionalities are:
8
+
9
+ - validation of production tables against model parameters
10
+ - generation of new production tables and model parameters based on
11
+ updates defined in a configuration file
12
+
6
13
  """
7
14
 
8
15
  import logging
@@ -18,6 +25,44 @@ from simtools.utils import names
18
25
  _logger = logging.getLogger(__name__)
19
26
 
20
27
 
28
+ def get_production_directory(simulation_models_path, model_version=None):
29
+ """
30
+ Get the production directory for a specific model version.
31
+
32
+ Parameters
33
+ ----------
34
+ simulation_models_path : str
35
+ Path to the simulation models repository.
36
+ model_version : str, optional
37
+ Specific model version to get the production directory for.
38
+
39
+ Returns
40
+ -------
41
+ Path
42
+ Path to the production directory.
43
+ """
44
+ if model_version:
45
+ return Path(simulation_models_path) / "simulation-models/productions" / str(model_version)
46
+ return Path(simulation_models_path) / "simulation-models/productions"
47
+
48
+
49
+ def get_model_parameter_directory(simulation_models_path):
50
+ """
51
+ Get the model parameters directory.
52
+
53
+ Parameters
54
+ ----------
55
+ simulation_models_path : str
56
+ Path to the simulation models repository.
57
+
58
+ Returns
59
+ -------
60
+ Path
61
+ Path to the model parameters directory.
62
+ """
63
+ return Path(simulation_models_path) / "simulation-models/model_parameters"
64
+
65
+
21
66
  def verify_simulation_model_production_tables(simulation_models_path):
22
67
  """
23
68
  Verify the simulation model production tables in the specified path.
@@ -35,7 +80,7 @@ def verify_simulation_model_production_tables(simulation_models_path):
35
80
  bool
36
81
  True if all parameters found, False if any missing.
37
82
  """
38
- productions_path = Path(simulation_models_path) / "simulation-models" / "productions"
83
+ productions_path = get_production_directory(simulation_models_path)
39
84
  production_files = list(productions_path.rglob("*.json"))
40
85
 
41
86
  _logger.info(
@@ -124,9 +169,7 @@ def _get_model_parameter_file_path(
124
169
  """
125
170
  collection = names.get_collection_name_from_parameter_name(parameter_name)
126
171
  return (
127
- Path(simulation_models_path)
128
- / "simulation-models"
129
- / "model_parameters"
172
+ get_model_parameter_directory(simulation_models_path)
130
173
  / (
131
174
  collection
132
175
  if collection in ("configuration_sim_telarray", "configuration_corsika")
@@ -138,39 +181,36 @@ def _get_model_parameter_file_path(
138
181
  )
139
182
 
140
183
 
141
- def generate_new_production(modifications, simulation_models_path):
184
+ def generate_new_production(model_version, simulation_models_path):
142
185
  """
143
186
  Generate a new production definition (production tables and model parameters).
144
187
 
145
188
  The following steps are performed:
146
189
 
147
190
  - copy of production tables from an existing base model version
148
- - update production tables with changes defined in a YAML file
191
+ - update production tables with changes defined in a configuration file (expected
192
+ to be called 'info.yml' in the target production directory)
149
193
  - generate new model parameter entries for changed parameters
150
194
  - allows for full or patch updates
151
195
 
152
196
  Parameters
153
197
  ----------
154
- modifications: str
155
- Path to the YAML file defining the changes to be applied.
198
+ model_version: str
199
+ Model version to be created or updated.
156
200
  simulation_models_path: str
157
201
  Path to the simulation models repository.
158
202
  """
159
- modifications = ascii_handler.collect_data_from_file(modifications)
160
- model_version_history = modifications.get("model_version_history", [])
161
- try:
162
- # oldest version is the base version
163
- base_model_version = min(set(model_version_history), key=Version)
164
- except ValueError as exc:
165
- raise ValueError(f"Base model version not found in {modifications}") from exc
166
- model_version = modifications["model_version"]
167
- changes = modifications.get("changes", {})
203
+ modification_dict = _get_changes_dict(model_version, simulation_models_path)
204
+ update_type = modification_dict.get("model_update", "full_update")
205
+ changes, base_model_version = _get_changes_to_production(
206
+ modification_dict, simulation_models_path, update_type
207
+ )
168
208
 
169
209
  _apply_changes_to_production_tables(
170
210
  changes,
171
211
  base_model_version,
172
- model_version,
173
- modifications.get("model_update", "full_update"),
212
+ modification_dict["model_version"],
213
+ update_type,
174
214
  simulation_models_path,
175
215
  )
176
216
 
@@ -181,27 +221,27 @@ def _apply_changes_to_production_tables(
181
221
  changes, base_model_version, model_version, update_type, simulation_models_path
182
222
  ):
183
223
  """
184
- Apply changes to production tables and write them to target directory.
224
+ Apply changes to or generate new production tables and write them to target directory.
185
225
 
186
226
  Parameters
187
227
  ----------
188
228
  changes: dict
189
- The changes to be applied.
229
+ Changes to be applied.
190
230
  base_model_version: str
191
- The base model version (source directory for production tables).
231
+ Base model version (source directory for production tables).
192
232
  model_version: str
193
- The model version to be set in the JSON data.
233
+ Model version of the new production tables.
194
234
  update_type: str
195
- Update mode, either 'full_update' or 'patch_update'.
235
+ Update type (e.g., 'full_update' or 'patch_update').
196
236
  simulation_models_path: Path
197
237
  Path to the simulation models repository.
198
238
  """
199
- source = simulation_models_path / "productions" / base_model_version
200
- target = simulation_models_path / "productions" / model_version
239
+ source = get_production_directory(simulation_models_path, base_model_version)
240
+ target = get_production_directory(simulation_models_path, model_version)
201
241
  _logger.info(f"Production tables {update_type} from {source} to {target}")
202
242
  target.mkdir(parents=True, exist_ok=True)
203
243
 
204
- # load existing tables
244
+ # load existing tables from source
205
245
  tables = {}
206
246
  for file_path in Path(source).rglob("*.json"):
207
247
  data = ascii_handler.collect_data_from_file(file_path)
@@ -217,9 +257,10 @@ def _apply_changes_to_production_tables(
217
257
  if _apply_changes_to_production_table(
218
258
  table_name, data, changes, model_version, update_type == "patch_update"
219
259
  ):
220
- _logger.info(f"Writing updated production table '{table_name}'")
260
+ target_file = target / f"{table_name}.json"
261
+ _logger.info(f"Writing updated production table '{target_file}'")
221
262
  data["production_table_name"] = table_name
222
- ascii_handler.write_data_to_file(data, target / f"{table_name}.json", sort_keys=True)
263
+ ascii_handler.write_data_to_file(data, target_file, sort_keys=True)
223
264
 
224
265
 
225
266
  def _apply_changes_to_production_table(table_name, data, changes, model_version, patch_update):
@@ -228,12 +269,14 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
228
269
 
229
270
  Parameters
230
271
  ----------
272
+ table_name: str
273
+ Name of the production table.
231
274
  data: dict
232
- The data to be updated.
275
+ Data to be updated.
233
276
  changes: dict
234
- The changes to be applied.
277
+ Changes to be applied.
235
278
  model_version: str
236
- The model version to be set in the JSON data.
279
+ Model version of the new production tables.
237
280
  patch_update: bool
238
281
  True if patch update (modify only changed parameters), False for full update.
239
282
 
@@ -248,7 +291,7 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
248
291
  table_parameters = {} if patch_update else data.get("parameters", {}).get(table_name, {})
249
292
  parameters, deprecated = _update_parameters_dict(table_parameters, changes, table_name)
250
293
  data["parameters"] = parameters
251
- if deprecated:
294
+ if deprecated and patch_update:
252
295
  data["deprecated_parameters"] = deprecated
253
296
  elif patch_update:
254
297
  return False
@@ -256,6 +299,86 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
256
299
  return True
257
300
 
258
301
 
302
+ def _get_changes_dict(model_version, simulation_models_path):
303
+ """
304
+ Load the changes dictionary from 'info.yml' files in production directories.
305
+
306
+ Parameters
307
+ ----------
308
+ model_version: str
309
+ Model version of the new production tables.
310
+ simulation_models_path: Path
311
+ Path to the simulation models directory.
312
+
313
+ Returns
314
+ -------
315
+ dict
316
+ Changes dictionary.
317
+ """
318
+ return ascii_handler.collect_data_from_file(
319
+ get_production_directory(simulation_models_path, model_version) / "info.yml"
320
+ )
321
+
322
+
323
+ def _get_changes_to_production(
324
+ modification_dict, simulation_models_path, update_type="full_update"
325
+ ):
326
+ """
327
+ Prepare changes applied to production tables.
328
+
329
+ For full updates, this includes the combination of changes to be applied
330
+ for all model versions in the history, starting from the base version.
331
+
332
+ Parameters
333
+ ----------
334
+ modification_dict: dict
335
+ Modifications dictionary.
336
+ simulation_models_path: Path
337
+ Path to the simulation models directory.
338
+ update_type: str
339
+ Update mode.
340
+
341
+ Returns
342
+ -------
343
+ dict, str
344
+ Changes dictionary and base model version.
345
+ """
346
+ model_version_history = modification_dict.get("model_version_history", [])
347
+
348
+ try:
349
+ # oldest version is the base version
350
+ base_model_version = min(set(model_version_history), key=Version)
351
+ except ValueError:
352
+ _logger.debug(f"Base model version not found in {model_version_history}")
353
+ return {}, modification_dict.get("model_version")
354
+
355
+ changes = modification_dict.get("changes", {})
356
+ if update_type == "patch_update":
357
+ return changes, base_model_version
358
+
359
+ for version_mod in reversed(model_version_history):
360
+ _changes_dict = _get_changes_dict(version_mod, simulation_models_path)
361
+ _version_changes, base_model_version = _get_changes_to_production(
362
+ _changes_dict, simulation_models_path, update_type="full_update"
363
+ )
364
+ changes = _update_two_levels_in_changes_dict(changes, _version_changes)
365
+ # stop iterative loop after reaching first full version of production tables
366
+ if _changes_dict.get("model_update", "full_update") == "full_update":
367
+ break
368
+
369
+ return changes, base_model_version
370
+
371
+
372
+ def _update_two_levels_in_changes_dict(d, u):
373
+ """Update changes dict, e.g. {"LSTN-design": { "parameter_name: { ... } } }."""
374
+ for k, v in u.items():
375
+ if isinstance(v, dict) and isinstance(d.get(k), dict):
376
+ d[k].update(v)
377
+ else:
378
+ d[k] = v
379
+ return d
380
+
381
+
259
382
  def _update_parameters_dict(table_parameters, changes, table_name):
260
383
  """
261
384
  Create a new parameters dictionary for the production tables.
@@ -285,6 +408,7 @@ def _update_parameters_dict(table_parameters, changes, table_name):
285
408
  if data.get("deprecated", False):
286
409
  _logger.info(f"Removing model parameter '{table_name} - {param}'")
287
410
  deprecated_params.append(param)
411
+ new_params[table_name].pop(param, None)
288
412
  else:
289
413
  version = data["version"]
290
414
  _logger.info(f"Setting '{table_name} - {param}' to version {version}")
@@ -330,7 +454,7 @@ def _create_new_model_parameter_entry(telescope, param, param_data, simulation_m
330
454
  simulation_models_path: Path
331
455
  Path to the simulation models directory.
332
456
  """
333
- telescope_dir = simulation_models_path / "model_parameters" / telescope
457
+ telescope_dir = get_model_parameter_directory(simulation_models_path) / telescope
334
458
  if not telescope_dir.exists():
335
459
  _logger.info(f"Create directory for array element '{telescope}': '{telescope_dir}'.")
336
460
  telescope_dir.mkdir(parents=True, exist_ok=True)
@@ -8,11 +8,6 @@ from simtools.model.site_model import SiteModel
8
8
  from simtools.model.telescope_model import TelescopeModel
9
9
  from simtools.utils import names
10
10
 
11
- __all__ = [
12
- "compute_telescope_transmission",
13
- "is_two_mirror_telescope",
14
- ]
15
-
16
11
 
17
12
  def initialize_simulation_models(
18
13
  label, db_config, model_version, site, telescope_name, calibration_device_name=None
@@ -43,21 +38,21 @@ def initialize_simulation_models(
43
38
  tel_model = TelescopeModel(
44
39
  site=site,
45
40
  telescope_name=telescope_name,
46
- mongo_db_config=db_config,
41
+ db_config=db_config,
47
42
  model_version=model_version,
48
43
  label=label,
49
44
  )
50
45
  site_model = SiteModel(
51
46
  site=site,
52
47
  model_version=model_version,
53
- mongo_db_config=db_config,
48
+ db_config=db_config,
54
49
  label=label,
55
50
  )
56
51
  if calibration_device_name is not None:
57
52
  calibration_model = CalibrationModel(
58
53
  site=site,
59
54
  calibration_device_model_name=calibration_device_name,
60
- mongo_db_config=db_config,
55
+ db_config=db_config,
61
56
  model_version=model_version,
62
57
  label=label,
63
58
  )
@@ -9,52 +9,67 @@ from astropy import units as u
9
9
 
10
10
  from simtools.model.model_parameter import ModelParameter
11
11
 
12
- __all__ = ["SiteModel"]
13
-
14
12
 
15
13
  class SiteModel(ModelParameter):
16
14
  """
17
- SiteModel represents the MC model of an observatory site.
15
+ Representation of an observatory site model.
16
+
17
+ The site model includes (among others):
18
+
19
+ - Reference point coordinates
20
+ - Array elements
21
+ - Geomagnetic field parameters
22
+ - Atmospheric parameters
23
+ - NSB parameters
18
24
 
19
25
  Parameters
20
26
  ----------
21
27
  site: str
22
28
  Site name (e.g., South or North).
23
- mongo_db_config: dict
24
- MongoDB configuration.
29
+ db_config: dict
30
+ Database configuration.
25
31
  model_version: str or list
26
32
  Model version or list of model versions (in which case only the first one is used).
27
33
  label: str, optional
28
- Instance label. Important for output file naming.
34
+ Instance label.
35
+ overwrite_model_parameters: str, optional
36
+ File name to overwrite model parameters from DB with provided values.
37
+ ignore_software_version: bool, optional
38
+ If True, ignore software version checks for deprecated parameters.
29
39
  """
30
40
 
31
41
  def __init__(
32
42
  self,
33
- site: str,
34
- mongo_db_config: dict,
35
- model_version: str,
36
- label: str | None = None,
43
+ site,
44
+ db_config,
45
+ model_version,
46
+ label=None,
47
+ overwrite_model_parameters=None,
48
+ ignore_software_version=False,
37
49
  ):
38
50
  """Initialize SiteModel."""
39
51
  self._logger = logging.getLogger(__name__)
40
52
  self._logger.debug("Init SiteModel for site %s", site)
41
53
  super().__init__(
42
54
  site=site,
43
- mongo_db_config=mongo_db_config,
55
+ db_config=db_config,
44
56
  model_version=model_version,
45
- db=None,
46
57
  label=label,
47
58
  collection="sites",
59
+ overwrite_model_parameters=overwrite_model_parameters,
60
+ ignore_software_version=ignore_software_version,
48
61
  )
49
62
 
50
- def get_reference_point(self) -> dict:
63
+ def get_reference_point(self):
51
64
  """
52
- Get reference point coordinates as dict.
65
+ Get reference point coordinates.
66
+
67
+ Ground coordinates are calculated relative to this point.
53
68
 
54
69
  Returns
55
70
  -------
56
71
  dict
57
- Reference point coordinates as dict
72
+ Reference point coordinates.
58
73
  """
59
74
  return {
60
75
  "center_altitude": self.get_parameter_value_with_unit("reference_point_altitude"),
@@ -63,13 +78,12 @@ class SiteModel(ModelParameter):
63
78
  "epsg_code": self.get_parameter_value("epsg_code"),
64
79
  }
65
80
 
66
- def get_corsika_site_parameters(
67
- self, config_file_style: bool = False, model_directory: Path | None = None
68
- ) -> dict:
81
+ def get_corsika_site_parameters(self, config_file_style=False, model_directory=None):
69
82
  """
70
- Get site-related CORSIKA parameters as dict.
83
+ Get site-related CORSIKA parameters.
71
84
 
72
- Parameters are returned with units wherever possible.
85
+ Parameters are returned with units wherever possible ('config_file_style=False')
86
+ or in CORSIKA-expected coordinates.
73
87
 
74
88
  Parameters
75
89
  ----------
@@ -81,7 +95,7 @@ class SiteModel(ModelParameter):
81
95
  Returns
82
96
  -------
83
97
  dict
84
- Site-related CORSIKA parameters as dict
98
+ Site-related CORSIKA parameters.
85
99
  """
86
100
  if config_file_style:
87
101
  model_directory = model_directory or Path()
@@ -110,7 +124,7 @@ class SiteModel(ModelParameter):
110
124
  "geomag_rotation": self.get_parameter_value_with_unit("geomag_rotation"),
111
125
  }
112
126
 
113
- def get_array_elements_for_layout(self, layout_name: str) -> list:
127
+ def get_array_elements_for_layout(self, layout_name):
114
128
  """
115
129
  Return list of array elements for a given array layout.
116
130
 
@@ -130,7 +144,27 @@ class SiteModel(ModelParameter):
130
144
  return layout["elements"]
131
145
  raise ValueError(f"Array layout '{layout_name}' not found in '{self.site}' site model.")
132
146
 
133
- def get_list_of_array_layouts(self) -> list:
147
+ def get_array_elements_of_type(self, array_element_type):
148
+ """
149
+ Get all array elements of a given type.
150
+
151
+ Parameters
152
+ ----------
153
+ array_element_type : str
154
+ Type of the array element (e.g. LSTN, MSTS)
155
+
156
+ Returns
157
+ -------
158
+ dict
159
+ Dict with array elements.
160
+ """
161
+ return self.db.get_array_elements_of_type(
162
+ array_element_type=array_element_type,
163
+ model_version=self.model_version,
164
+ collection="telescopes",
165
+ )
166
+
167
+ def get_list_of_array_layouts(self):
134
168
  """
135
169
  Get list of available array layouts.
136
170
 
@@ -141,13 +175,9 @@ class SiteModel(ModelParameter):
141
175
  """
142
176
  return [layout["name"] for layout in self.get_parameter_value("array_layouts")]
143
177
 
144
- def export_atmospheric_transmission_file(self, model_directory: Path):
178
+ def export_atmospheric_transmission_file(self, model_directory):
145
179
  """
146
- Export atmospheric transmission file.
147
-
148
- This method is needed because when CORSIKA is not piped to sim_telarray,
149
- the atmospheric transmission file is not written out to the model directory.
150
- This method allows to export it explicitly.
180
+ Export atmospheric transmission file from database to the given directory.
151
181
 
152
182
  Parameters
153
183
  ----------
@@ -13,8 +13,6 @@ from simtools.model.mirrors import Mirrors
13
13
  from simtools.model.model_parameter import InvalidModelParameterError, ModelParameter
14
14
  from simtools.utils import names
15
15
 
16
- __all__ = ["TelescopeModel"]
17
-
18
16
 
19
17
  class TelescopeModel(ModelParameter):
20
18
  """
@@ -28,30 +26,37 @@ class TelescopeModel(ModelParameter):
28
26
  Site name (e.g., South or North).
29
27
  telescope_name: str
30
28
  Telescope name (ex. LSTN-01, LSTN-design, ...).
31
- mongo_db_config: dict
32
- MongoDB configuration.
29
+ db_config: dict
30
+ Database configuration.
33
31
  model_version: str
34
32
  Model version.
35
33
  label: str, optional
36
- Instance label. Important for output file naming.
34
+ Instance label.
35
+ overwrite_model_parameters: str, optional
36
+ File name to overwrite model parameters from DB with provided values.
37
+ ignore_software_version: bool, optional
38
+ If True, ignore software version checks for deprecated parameters.
37
39
  """
38
40
 
39
41
  def __init__(
40
42
  self,
41
- site: str,
42
- telescope_name: str,
43
- mongo_db_config: dict,
44
- model_version: str,
45
- label: str | None = None,
43
+ site,
44
+ telescope_name,
45
+ db_config,
46
+ model_version,
47
+ label=None,
48
+ overwrite_model_parameters=None,
49
+ ignore_software_version=False,
46
50
  ):
47
51
  """Initialize TelescopeModel."""
48
52
  super().__init__(
49
53
  site=site,
50
54
  array_element_name=telescope_name,
51
- mongo_db_config=mongo_db_config,
55
+ db_config=db_config,
52
56
  model_version=model_version,
53
- db=None,
54
57
  label=label,
58
+ overwrite_model_parameters=overwrite_model_parameters,
59
+ ignore_software_version=ignore_software_version,
55
60
  )
56
61
 
57
62
  self._logger = logging.getLogger(__name__)
@@ -144,7 +149,7 @@ class TelescopeModel(ModelParameter):
144
149
  except TypeError as exc:
145
150
  raise TypeError("Undefined mirror list") from exc
146
151
 
147
- self._mirrors = Mirrors(mirror_list_file, parameters=self._parameters)
152
+ self._mirrors = Mirrors(mirror_list_file, parameters=self.parameters)
148
153
 
149
154
  def get_telescope_effective_focal_length(
150
155
  self, unit: str = "m", return_focal_length_if_zero: bool = False
@@ -376,8 +381,9 @@ class TelescopeModel(ModelParameter):
376
381
  try:
377
382
  return self.get_parameter_value_with_unit(f"array_element_position_{coordinate_system}")
378
383
  except InvalidModelParameterError as exc:
379
- self._logger.error(f"Coordinate system {coordinate_system} not found.")
380
- raise exc
384
+ raise InvalidModelParameterError(
385
+ f"Coordinate system {coordinate_system} not found."
386
+ ) from exc
381
387
 
382
388
  def get_calibration_device_name(self, device_type):
383
389
  """
@@ -6,8 +6,6 @@ import numpy as np
6
6
  from astropy import units as u
7
7
  from astropy.io import fits
8
8
 
9
- __all__ = ["StatisticalUncertaintyEvaluator"]
10
-
11
9
 
12
10
  class StatisticalUncertaintyEvaluator:
13
11
  """
@@ -10,8 +10,6 @@ metrics and the evaluator's results.
10
10
  import astropy.units as u
11
11
  import numpy as np
12
12
 
13
- __all__ = ["ProductionStatisticsDerivator"]
14
-
15
13
 
16
14
  class ProductionStatisticsDerivator:
17
15
  """
@@ -10,8 +10,6 @@ from simtools.production_configuration.derive_production_statistics import (
10
10
  ProductionStatisticsDerivator,
11
11
  )
12
12
 
13
- __all__ = ["InterpolationHandler"]
14
-
15
13
 
16
14
  class InterpolationHandler:
17
15
  """
@@ -81,10 +81,10 @@ class MirrorPanelPSF:
81
81
  mirror_list_file = gen.find_file(
82
82
  name=self.args_dict["mirror_list"], loc=self.args_dict["model_path"]
83
83
  )
84
- tel_model.change_parameter("mirror_list", self.args_dict["mirror_list"])
85
- tel_model.export_parameter_file("mirror_list", mirror_list_file)
84
+ tel_model.overwrite_model_parameter("mirror_list", self.args_dict["mirror_list"])
85
+ tel_model.overwrite_model_file("mirror_list", mirror_list_file)
86
86
  if self.args_dict["random_focal_length"] is not None:
87
- tel_model.change_parameter(
87
+ tel_model.overwrite_model_parameter(
88
88
  "random_focal_length", str(self.args_dict["random_focal_length"])
89
89
  )
90
90
 
@@ -221,7 +221,7 @@ class MirrorPanelPSF:
221
221
  sig_d80: float
222
222
  Standard deviation of D80 in cm.
223
223
  """
224
- self.telescope_model.change_parameter("mirror_reflection_random_angle", rnda)
224
+ self.telescope_model.overwrite_model_parameter("mirror_reflection_random_angle", rnda)
225
225
  ray = RayTracing(
226
226
  telescope_model=self.telescope_model,
227
227
  site_model=self.site_model,
@@ -19,8 +19,6 @@ import numpy as np
19
19
 
20
20
  from simtools.utils.general import collect_kwargs, set_default_kwargs
21
21
 
22
- __all__ = ["PSFImage"]
23
-
24
22
 
25
23
  class PSFImage:
26
24
  """
@@ -95,7 +95,7 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars):
95
95
  if pars is None:
96
96
  raise ValueError("No best parameters found")
97
97
 
98
- tel_model.change_multiple_parameters(**pars)
98
+ tel_model.overwrite_parameters(pars)
99
99
  ray = RayTracing(
100
100
  telescope_model=tel_model,
101
101
  site_model=site_model,
@@ -20,8 +20,6 @@ from simtools.simtel.simulator_ray_tracing import SimulatorRayTracing
20
20
  from simtools.utils import names
21
21
  from simtools.visualization import visualize
22
22
 
23
- __all__ = ["RayTracing"]
24
-
25
23
  INVALID_KEY_TO_PLOT = "Invalid key to plot"
26
24
 
27
25