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.
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/METADATA +6 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/RECORD +135 -130
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/entry_points.txt +3 -2
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.27.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +2 -2
- simtools/application_control.py +35 -7
- simtools/applications/convert_geo_coordinates_of_array_elements.py +3 -3
- simtools/applications/db_add_file_to_db.py +1 -1
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
- simtools/applications/db_add_value_from_json_to_db.py +1 -1
- simtools/applications/db_generate_compound_indexes.py +1 -1
- simtools/applications/db_get_array_layouts_from_db.py +3 -7
- simtools/applications/db_get_file_from_db.py +1 -1
- simtools/applications/db_get_parameter_from_db.py +1 -1
- simtools/applications/db_inspect_databases.py +1 -1
- simtools/applications/db_upload_model_repository.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +1 -2
- simtools/applications/{calculate_incident_angles.py → derive_incident_angle.py} +16 -18
- simtools/applications/derive_mirror_rnda.py +112 -180
- simtools/applications/derive_psf_parameters.py +0 -1
- simtools/applications/derive_pulse_shape_parameters.py +0 -1
- simtools/applications/derive_trigger_rates.py +1 -1
- simtools/applications/docs_produce_array_element_report.py +2 -8
- simtools/applications/docs_produce_calibration_reports.py +1 -3
- simtools/applications/docs_produce_model_parameter_reports.py +0 -2
- simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
- simtools/applications/generate_array_config.py +0 -1
- simtools/applications/generate_corsika_histograms.py +79 -229
- simtools/applications/generate_regular_arrays.py +76 -69
- simtools/applications/generate_simtel_event_data.py +2 -2
- simtools/applications/maintain_simulation_model_add_production.py +2 -2
- simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
- simtools/applications/plot_array_layout.py +5 -111
- simtools/applications/plot_simulated_event_distributions.py +57 -0
- simtools/applications/plot_tabular_data.py +0 -1
- simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
- simtools/applications/production_derive_corsika_limits.py +1 -1
- simtools/applications/production_generate_grid.py +0 -1
- simtools/applications/run_application.py +1 -1
- simtools/applications/simulate_flasher.py +3 -15
- simtools/applications/simulate_illuminator.py +2 -11
- simtools/applications/simulate_pedestals.py +1 -5
- simtools/applications/simulate_prod.py +8 -11
- simtools/applications/simulate_prod_htcondor_generator.py +1 -1
- simtools/applications/submit_array_layouts.py +2 -4
- simtools/applications/submit_data_from_external.py +2 -1
- simtools/applications/submit_model_parameter_from_external.py +1 -3
- simtools/applications/validate_camera_efficiency.py +28 -28
- simtools/applications/validate_camera_fov.py +0 -1
- simtools/applications/validate_cumulative_psf.py +1 -5
- simtools/applications/validate_optics.py +2 -14
- simtools/atmosphere.py +83 -0
- simtools/camera/camera_efficiency.py +171 -53
- simtools/camera/single_photon_electron_spectrum.py +8 -7
- simtools/configuration/commandline_parser.py +82 -11
- simtools/configuration/configurator.py +6 -11
- simtools/constants.py +5 -0
- simtools/corsika/corsika_config.py +100 -202
- simtools/corsika/corsika_histograms.py +561 -1708
- simtools/corsika/primary_particle.py +1 -1
- simtools/data_model/metadata_collector.py +5 -2
- simtools/data_model/metadata_model.py +0 -4
- simtools/data_model/model_data_writer.py +59 -64
- simtools/data_model/schema.py +2 -0
- simtools/data_model/validate_data.py +1 -3
- simtools/db/db_handler.py +23 -10
- simtools/db/mongo_db.py +2 -2
- simtools/dependencies.py +81 -38
- simtools/io/ascii_handler.py +55 -5
- simtools/io/io_handler.py +23 -12
- simtools/io/table_handler.py +1 -1
- simtools/job_execution/job_manager.py +154 -79
- simtools/job_execution/process_pool.py +137 -0
- simtools/layout/array_layout.py +4 -13
- simtools/layout/array_layout_utils.py +348 -57
- simtools/model/array_model.py +23 -63
- simtools/model/calibration_model.py +4 -8
- simtools/model/legacy_model_parameter.py +134 -0
- simtools/model/model_parameter.py +147 -86
- simtools/model/model_utils.py +40 -6
- simtools/model/site_model.py +4 -8
- simtools/model/telescope_model.py +10 -16
- simtools/production_configuration/derive_corsika_limits.py +6 -11
- simtools/production_configuration/interpolation_handler.py +16 -16
- simtools/ray_tracing/incident_angles.py +92 -17
- simtools/ray_tracing/mirror_panel_psf.py +338 -222
- simtools/ray_tracing/psf_analysis.py +62 -48
- simtools/ray_tracing/psf_parameter_optimisation.py +3 -3
- simtools/ray_tracing/ray_tracing.py +43 -25
- simtools/reporting/docs_auto_report_generator.py +8 -13
- simtools/reporting/docs_read_parameters.py +2 -8
- simtools/runners/corsika_runner.py +52 -195
- simtools/runners/corsika_simtel_runner.py +77 -108
- simtools/runners/runner_services.py +214 -213
- simtools/runners/simtel_runner.py +27 -160
- simtools/runners/simtools_runner.py +11 -73
- simtools/schemas/application_workflow.metaschema.yml +8 -0
- simtools/settings.py +173 -0
- simtools/{io/eventio_handler.py → sim_events/file_info.py} +3 -3
- simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
- simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
- simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
- simtools/simtel/pulse_shapes.py +7 -2
- simtools/simtel/simtel_config_writer.py +79 -91
- simtools/simtel/simtel_seeds.py +184 -0
- simtools/simtel/simtel_table_reader.py +6 -4
- simtools/simtel/simulator_array.py +114 -109
- simtools/simtel/simulator_camera_efficiency.py +68 -46
- simtools/simtel/simulator_light_emission.py +164 -132
- simtools/simtel/simulator_ray_tracing.py +80 -71
- simtools/simulator.py +137 -355
- simtools/telescope_trigger_rates.py +3 -4
- simtools/testing/assertions.py +84 -33
- simtools/testing/configuration.py +1 -2
- simtools/testing/helpers.py +2 -3
- simtools/testing/log_inspector.py +1 -0
- simtools/testing/sim_telarray_metadata.py +14 -12
- simtools/testing/validate_output.py +121 -42
- simtools/utils/general.py +43 -17
- simtools/utils/geometry.py +0 -77
- simtools/utils/names.py +5 -5
- simtools/utils/random.py +36 -0
- simtools/visualization/legend_handlers.py +7 -6
- simtools/visualization/plot_array_layout.py +91 -16
- simtools/visualization/plot_corsika_histograms.py +145 -605
- simtools/visualization/plot_incident_angles.py +48 -1
- simtools/visualization/plot_mirrors.py +1 -4
- simtools/visualization/plot_pixels.py +2 -4
- simtools/visualization/plot_psf.py +160 -19
- simtools/visualization/plot_simtel_event_histograms.py +4 -4
- simtools/visualization/plot_simtel_events.py +6 -11
- simtools/visualization/plot_tables.py +8 -19
- simtools/visualization/visualize.py +22 -2
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
- simtools/applications/print_version.py +0 -53
- simtools/io/hdf5_handler.py +0 -139
- {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
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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
|
-
|
|
329
|
-
|
|
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.
|
|
335
|
-
parameters.keys(), software_name=software_name
|
|
336
|
-
)
|
|
332
|
+
self._check_model_parameter_versions(parameters, software_name=software_name)
|
|
337
333
|
|
|
338
|
-
def
|
|
334
|
+
def _check_model_parameter_versions(self, parameters, software_name=None):
|
|
339
335
|
"""
|
|
340
|
-
Ensure
|
|
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
|
-
|
|
348
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
-
|
|
506
|
-
self.
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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=
|
|
674
|
+
label=desired_label,
|
|
614
675
|
)
|
|
615
676
|
|
|
616
677
|
def export_nsb_spectrum_to_telescope_altitude_correction_file(self, model_directory):
|
simtools/model/model_utils.py
CHANGED
|
@@ -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,
|
|
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.
|
simtools/model/site_model.py
CHANGED
|
@@ -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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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.
|
|
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
|
|
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 =
|
|
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 :
|
|
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 :
|
|
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 :
|
|
335
|
+
histograms : EventDataHistograms
|
|
341
336
|
Histograms.
|
|
342
337
|
loss_fraction : float
|
|
343
338
|
Fraction of events to be lost.
|