gammasimtools 0.16.0__py3-none-any.whl → 0.18.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.16.0.dist-info → gammasimtools-0.18.0.dist-info}/METADATA +5 -2
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/RECORD +82 -74
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/entry_points.txt +4 -1
- simtools/_version.py +2 -2
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +10 -1
- simtools/applications/derive_ctao_array_layouts.py +5 -5
- simtools/applications/derive_mirror_rnda.py +1 -1
- simtools/applications/generate_simtel_event_data.py +128 -46
- simtools/applications/merge_tables.py +102 -0
- simtools/applications/plot_array_layout.py +145 -258
- simtools/applications/plot_tabular_data.py +12 -1
- simtools/applications/plot_tabular_data_for_model_parameter.py +103 -0
- simtools/applications/production_derive_corsika_limits.py +78 -225
- simtools/applications/production_derive_statistics.py +77 -43
- simtools/applications/simulate_light_emission.py +1 -0
- simtools/applications/simulate_prod.py +30 -18
- simtools/applications/simulate_prod_htcondor_generator.py +0 -1
- simtools/applications/submit_array_layouts.py +93 -0
- simtools/applications/verify_simulation_model_production_tables.py +52 -0
- simtools/camera/camera_efficiency.py +3 -3
- simtools/configuration/commandline_parser.py +30 -35
- simtools/configuration/configurator.py +0 -4
- simtools/constants.py +2 -0
- simtools/corsika/corsika_config.py +17 -12
- simtools/corsika/primary_particle.py +46 -13
- simtools/data_model/metadata_collector.py +7 -3
- simtools/data_model/schema.py +15 -1
- simtools/db/db_handler.py +16 -11
- simtools/db/db_model_upload.py +2 -2
- simtools/io_operations/io_handler.py +2 -2
- simtools/io_operations/io_table_handler.py +345 -0
- simtools/job_execution/htcondor_script_generator.py +2 -2
- simtools/job_execution/job_manager.py +7 -121
- simtools/layout/array_layout_utils.py +389 -0
- simtools/model/array_model.py +10 -1
- simtools/model/model_repository.py +134 -0
- simtools/production_configuration/{calculate_statistical_errors_grid_point.py → calculate_statistical_uncertainties_grid_point.py} +101 -112
- simtools/production_configuration/derive_corsika_limits.py +239 -111
- simtools/production_configuration/derive_corsika_limits_grid.py +232 -0
- simtools/production_configuration/derive_production_statistics.py +57 -26
- simtools/production_configuration/derive_production_statistics_handler.py +70 -37
- simtools/production_configuration/interpolation_handler.py +296 -94
- simtools/ray_tracing/ray_tracing.py +7 -6
- simtools/reporting/docs_read_parameters.py +104 -62
- simtools/resources/array-element-ids.json +126 -0
- simtools/runners/corsika_simtel_runner.py +4 -1
- simtools/runners/runner_services.py +5 -4
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +5 -1
- simtools/schemas/model_parameters/atmospheric_profile.schema.yml +41 -0
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +43 -0
- simtools/schemas/model_parameters/camera_filter.schema.yml +10 -0
- simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +10 -0
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +31 -0
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +12 -0
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +10 -0
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +10 -0
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +12 -0
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +19 -0
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +10 -0
- simtools/schemas/plot_configuration.metaschema.yml +46 -57
- simtools/schemas/production_configuration_metrics.schema.yml +2 -2
- simtools/simtel/simtel_config_writer.py +34 -14
- simtools/simtel/simtel_io_event_reader.py +301 -194
- simtools/simtel/simtel_io_event_writer.py +237 -221
- simtools/simtel/simtel_io_file_info.py +9 -4
- simtools/simtel/simtel_io_metadata.py +119 -8
- simtools/simtel/simulator_array.py +2 -2
- simtools/simtel/simulator_light_emission.py +79 -34
- simtools/simtel/simulator_ray_tracing.py +2 -2
- simtools/simulator.py +101 -68
- simtools/testing/validate_output.py +4 -1
- simtools/utils/general.py +1 -3
- simtools/utils/names.py +76 -7
- simtools/visualization/plot_array_layout.py +242 -0
- simtools/visualization/plot_pixels.py +680 -0
- simtools/visualization/plot_tables.py +81 -2
- simtools/visualization/visualize.py +3 -219
- simtools/applications/production_generate_simulation_config.py +0 -152
- simtools/layout/ctao_array_layouts.py +0 -172
- simtools/production_configuration/generate_simulation_config.py +0 -158
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/top_level.txt +0 -0
- /simtools/{schemas → resources}/array_elements.yml +0 -0
simtools/simulator.py
CHANGED
|
@@ -12,11 +12,12 @@ import numpy as np
|
|
|
12
12
|
|
|
13
13
|
import simtools.utils.general as gen
|
|
14
14
|
from simtools.corsika.corsika_config import CorsikaConfig
|
|
15
|
-
from simtools.io_operations import io_handler
|
|
15
|
+
from simtools.io_operations import io_handler, io_table_handler
|
|
16
16
|
from simtools.job_execution.job_manager import JobManager
|
|
17
17
|
from simtools.model.array_model import ArrayModel
|
|
18
18
|
from simtools.runners.corsika_runner import CorsikaRunner
|
|
19
19
|
from simtools.runners.corsika_simtel_runner import CorsikaSimtelRunner
|
|
20
|
+
from simtools.simtel.simtel_io_event_writer import SimtelIOEventDataWriter
|
|
20
21
|
from simtools.simtel.simulator_array import SimulatorArray
|
|
21
22
|
from simtools.testing.sim_telarray_metadata import assert_sim_telarray_metadata
|
|
22
23
|
|
|
@@ -72,8 +73,6 @@ class Simulator:
|
|
|
72
73
|
self.runs = self._initialize_run_list()
|
|
73
74
|
self._results = defaultdict(list)
|
|
74
75
|
self._test = self.args_dict.get("test", False)
|
|
75
|
-
self.submit_engine = self.args_dict.get("submit_engine", "local")
|
|
76
|
-
self._submit_options = self.args_dict.get("submit_options", None)
|
|
77
76
|
self._extra_commands = extra_commands
|
|
78
77
|
|
|
79
78
|
self.sim_telarray_seeds = {
|
|
@@ -145,6 +144,7 @@ class Simulator:
|
|
|
145
144
|
],
|
|
146
145
|
"seed_file_name": self.sim_telarray_seeds["seed_file_name"],
|
|
147
146
|
},
|
|
147
|
+
simtel_path=self.args_dict.get("simtel_path", None),
|
|
148
148
|
)
|
|
149
149
|
for version in versions
|
|
150
150
|
]
|
|
@@ -179,7 +179,10 @@ class Simulator:
|
|
|
179
179
|
|
|
180
180
|
def _initialize_run_list(self):
|
|
181
181
|
"""
|
|
182
|
-
Initialize run list using the configuration values
|
|
182
|
+
Initialize run list using the configuration values.
|
|
183
|
+
|
|
184
|
+
Uses 'run_number', 'run_number_offset' and 'number_of_runs' arguments
|
|
185
|
+
to create a list of run numbers.
|
|
183
186
|
|
|
184
187
|
Returns
|
|
185
188
|
-------
|
|
@@ -189,19 +192,27 @@ class Simulator:
|
|
|
189
192
|
Raises
|
|
190
193
|
------
|
|
191
194
|
KeyError
|
|
192
|
-
If '
|
|
195
|
+
If 'run_number', 'run_number_offset' and 'number_of_runs' are
|
|
196
|
+
not found in the configuration.
|
|
193
197
|
"""
|
|
194
198
|
try:
|
|
199
|
+
offset_run_number = self.args_dict["run_number_offset"] + self.args_dict["run_number"]
|
|
200
|
+
if self.args_dict["number_of_runs"] <= 1:
|
|
201
|
+
return self._validate_run_list_and_range(
|
|
202
|
+
run_list=offset_run_number,
|
|
203
|
+
run_range=None,
|
|
204
|
+
)
|
|
195
205
|
return self._validate_run_list_and_range(
|
|
196
206
|
run_list=None,
|
|
197
207
|
run_range=[
|
|
198
|
-
|
|
199
|
-
|
|
208
|
+
offset_run_number,
|
|
209
|
+
offset_run_number + self.args_dict["number_of_runs"],
|
|
200
210
|
],
|
|
201
211
|
)
|
|
202
212
|
except KeyError as exc:
|
|
203
213
|
self._logger.error(
|
|
204
|
-
"Error in initializing run list
|
|
214
|
+
"Error in initializing run list "
|
|
215
|
+
"(missing 'run_number', 'run_number_offset' or 'number_of_runs')."
|
|
205
216
|
)
|
|
206
217
|
raise exc
|
|
207
218
|
|
|
@@ -301,6 +312,8 @@ class Simulator:
|
|
|
301
312
|
runner_args["keep_seeds"] = self.args_dict.get("corsika_test_seeds", False)
|
|
302
313
|
if runner_class is not CorsikaRunner:
|
|
303
314
|
runner_args["sim_telarray_seeds"] = self.sim_telarray_seeds
|
|
315
|
+
if runner_class is CorsikaSimtelRunner:
|
|
316
|
+
runner_args["sequential"] = self.args_dict.get("sequential", False)
|
|
304
317
|
|
|
305
318
|
return runner_class(**runner_args)
|
|
306
319
|
|
|
@@ -330,8 +343,6 @@ class Simulator:
|
|
|
330
343
|
input_file_list: str or list of str
|
|
331
344
|
Single file or list of files of shower simulations.
|
|
332
345
|
"""
|
|
333
|
-
self._logger.info(f"Submission command: {self.submit_engine}")
|
|
334
|
-
|
|
335
346
|
runs_and_files_to_submit = self._get_runs_and_files_to_submit(
|
|
336
347
|
input_file_list=input_file_list
|
|
337
348
|
)
|
|
@@ -345,11 +356,7 @@ class Simulator:
|
|
|
345
356
|
run_number=run_number, input_file=input_file, extra_commands=self._extra_commands
|
|
346
357
|
)
|
|
347
358
|
|
|
348
|
-
job_manager = JobManager(
|
|
349
|
-
submit_engine=self.submit_engine,
|
|
350
|
-
submit_options=self._submit_options,
|
|
351
|
-
test=self._test,
|
|
352
|
-
)
|
|
359
|
+
job_manager = JobManager(test=self._test)
|
|
353
360
|
job_manager.submit(
|
|
354
361
|
run_script=run_script,
|
|
355
362
|
run_out_file=self._simulation_runner.get_file_name(
|
|
@@ -454,73 +461,66 @@ class Simulator:
|
|
|
454
461
|
run number
|
|
455
462
|
|
|
456
463
|
"""
|
|
457
|
-
keys = ["
|
|
464
|
+
keys = ["simtel_output", "sub_out", "log", "input", "hist", "corsika_log", "event_data"]
|
|
458
465
|
results = {key: [] for key in keys}
|
|
459
466
|
|
|
467
|
+
def get_file_name(name, **kwargs):
|
|
468
|
+
return str(self._simulation_runner.get_file_name(file_type=name, **kwargs))
|
|
469
|
+
|
|
460
470
|
if "sim_telarray" in self.simulation_software:
|
|
461
471
|
results["input"].append(str(file))
|
|
462
472
|
|
|
463
|
-
results["sub_out"].append(
|
|
464
|
-
str(
|
|
465
|
-
self._simulation_runner.get_file_name(
|
|
466
|
-
file_type="sub_log",
|
|
467
|
-
mode="out",
|
|
468
|
-
run_number=run_number,
|
|
469
|
-
)
|
|
470
|
-
)
|
|
471
|
-
)
|
|
473
|
+
results["sub_out"].append(get_file_name("sub_log", mode="out", run_number=run_number))
|
|
472
474
|
|
|
473
|
-
for
|
|
474
|
-
results["
|
|
475
|
-
|
|
476
|
-
self._simulation_runner.get_file_name(
|
|
477
|
-
file_type="output",
|
|
478
|
-
run_number=run_number,
|
|
479
|
-
model_version_index=model_version_index,
|
|
480
|
-
)
|
|
481
|
-
)
|
|
475
|
+
for i in range(len(self.array_models)):
|
|
476
|
+
results["simtel_output"].append(
|
|
477
|
+
get_file_name("simtel_output", run_number=run_number, model_version_index=i)
|
|
482
478
|
)
|
|
479
|
+
|
|
483
480
|
if "sim_telarray" in self.simulation_software:
|
|
484
481
|
results["log"].append(
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
model_version_index=model_version_index,
|
|
491
|
-
)
|
|
482
|
+
get_file_name(
|
|
483
|
+
"log",
|
|
484
|
+
simulation_software="sim_telarray",
|
|
485
|
+
run_number=run_number,
|
|
486
|
+
model_version_index=i,
|
|
492
487
|
)
|
|
493
488
|
)
|
|
494
489
|
results["hist"].append(
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
model_version_index=model_version_index,
|
|
501
|
-
)
|
|
490
|
+
get_file_name(
|
|
491
|
+
"histogram",
|
|
492
|
+
simulation_software="sim_telarray",
|
|
493
|
+
run_number=run_number,
|
|
494
|
+
model_version_index=i,
|
|
502
495
|
)
|
|
503
496
|
)
|
|
497
|
+
results["event_data"].append(
|
|
498
|
+
get_file_name(
|
|
499
|
+
"event_data",
|
|
500
|
+
simulation_software="sim_telarray",
|
|
501
|
+
run_number=run_number,
|
|
502
|
+
model_version_index=i,
|
|
503
|
+
)
|
|
504
|
+
)
|
|
505
|
+
|
|
504
506
|
if "corsika" in self.simulation_software:
|
|
505
507
|
results["corsika_log"].append(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
model_version_index=model_version_index,
|
|
512
|
-
)
|
|
508
|
+
get_file_name(
|
|
509
|
+
"corsika_log",
|
|
510
|
+
simulation_software="corsika",
|
|
511
|
+
run_number=run_number,
|
|
512
|
+
model_version_index=i,
|
|
513
513
|
)
|
|
514
514
|
)
|
|
515
515
|
|
|
516
516
|
for key in keys:
|
|
517
517
|
self._results[key].extend(results[key])
|
|
518
518
|
|
|
519
|
-
def get_file_list(self, file_type="
|
|
519
|
+
def get_file_list(self, file_type="simtel_output"):
|
|
520
520
|
"""
|
|
521
521
|
Get list of files generated by simulations.
|
|
522
522
|
|
|
523
|
-
Options are "input", "
|
|
523
|
+
Options are "input", "simtel_output", "hist", "log", "corsika_log".
|
|
524
524
|
Not all file types are available for all simulation types.
|
|
525
525
|
Returns an empty list for an unknown file type.
|
|
526
526
|
|
|
@@ -538,11 +538,11 @@ class Simulator:
|
|
|
538
538
|
self._logger.info(f"Getting list of {file_type} files")
|
|
539
539
|
return self._results[file_type]
|
|
540
540
|
|
|
541
|
-
def print_list_of_files(self, file_type="
|
|
541
|
+
def print_list_of_files(self, file_type="simtel_output"):
|
|
542
542
|
"""
|
|
543
543
|
Print list of output files generated by simulations.
|
|
544
544
|
|
|
545
|
-
Options are "input", "
|
|
545
|
+
Options are "input", "simtel_output", "hist", "log".
|
|
546
546
|
|
|
547
547
|
Parameters
|
|
548
548
|
----------
|
|
@@ -636,7 +636,7 @@ class Simulator:
|
|
|
636
636
|
|
|
637
637
|
def save_file_lists(self):
|
|
638
638
|
"""Save files lists for output and log files."""
|
|
639
|
-
for file_type in ["
|
|
639
|
+
for file_type in ["simtel_output", "log", "corsika_log", "hist"]:
|
|
640
640
|
file_name = self.io_handler.get_output_directory(label=self.label).joinpath(
|
|
641
641
|
f"{file_type}_files.txt"
|
|
642
642
|
)
|
|
@@ -649,6 +649,29 @@ class Simulator:
|
|
|
649
649
|
else:
|
|
650
650
|
self._logger.debug(f"No files to save for {file_type} files.")
|
|
651
651
|
|
|
652
|
+
def save_reduced_event_lists(self):
|
|
653
|
+
"""
|
|
654
|
+
Save reduced event lists with event data on simulated and triggered events.
|
|
655
|
+
|
|
656
|
+
The files are saved with the same name as the sim_telarray output file
|
|
657
|
+
but with a 'hdf5' extension.
|
|
658
|
+
"""
|
|
659
|
+
if "sim_telarray" not in self.simulation_software:
|
|
660
|
+
self._logger.warning(
|
|
661
|
+
"Reduced event lists can only be saved for sim_telarray simulations."
|
|
662
|
+
)
|
|
663
|
+
return
|
|
664
|
+
|
|
665
|
+
input_files = self.get_file_list(file_type="simtel_output")
|
|
666
|
+
output_files = self.get_file_list(file_type="event_data")
|
|
667
|
+
for input_file, output_file in zip(input_files, output_files):
|
|
668
|
+
generator = SimtelIOEventDataWriter([input_file])
|
|
669
|
+
io_table_handler.write_tables(
|
|
670
|
+
tables=generator.process_files(),
|
|
671
|
+
output_file=Path(output_file),
|
|
672
|
+
overwrite_existing=True,
|
|
673
|
+
)
|
|
674
|
+
|
|
652
675
|
def pack_for_register(self, directory_for_grid_upload=None):
|
|
653
676
|
"""
|
|
654
677
|
Pack simulation output files for registering on the grid.
|
|
@@ -664,10 +687,15 @@ class Simulator:
|
|
|
664
687
|
self._logger.info(
|
|
665
688
|
f"Packing the output files for registering on the grid ({directory_for_grid_upload})"
|
|
666
689
|
)
|
|
667
|
-
output_files = self.get_file_list(file_type="
|
|
690
|
+
output_files = self.get_file_list(file_type="simtel_output")
|
|
668
691
|
log_files = self.get_file_list(file_type="log")
|
|
669
692
|
corsika_log_files = self.get_file_list(file_type="corsika_log")
|
|
670
693
|
histogram_files = self.get_file_list(file_type="hist")
|
|
694
|
+
reduced_event_files = (
|
|
695
|
+
self.get_file_list(file_type="event_data")
|
|
696
|
+
if self.args_dict.get("save_reduced_event_lists")
|
|
697
|
+
else []
|
|
698
|
+
)
|
|
671
699
|
|
|
672
700
|
directory_for_grid_upload = (
|
|
673
701
|
Path(directory_for_grid_upload)
|
|
@@ -697,11 +725,12 @@ class Simulator:
|
|
|
697
725
|
tar_file_path = directory_for_grid_upload.joinpath(tar_file_name)
|
|
698
726
|
|
|
699
727
|
with tarfile.open(tar_file_path, "w:gz") as tar:
|
|
728
|
+
# Add all relevant log, histogram, and CORSIKA log files to the tarball
|
|
700
729
|
files_to_tar = model_logs + model_hists + model_corsika_logs
|
|
701
730
|
for file_to_tar in files_to_tar:
|
|
702
731
|
tar.add(file_to_tar, arcname=Path(file_to_tar).name)
|
|
703
732
|
|
|
704
|
-
for file_to_move in output_files:
|
|
733
|
+
for file_to_move in output_files + reduced_event_files:
|
|
705
734
|
source_file = Path(file_to_move)
|
|
706
735
|
destination_file = directory_for_grid_upload / source_file.name
|
|
707
736
|
if destination_file.exists():
|
|
@@ -717,7 +746,7 @@ class Simulator:
|
|
|
717
746
|
return
|
|
718
747
|
|
|
719
748
|
for model in self.array_models:
|
|
720
|
-
files = self.get_file_list(file_type="
|
|
749
|
+
files = self.get_file_list(file_type="simtel_output")
|
|
721
750
|
output_file = next((f for f in files if model.model_version in f), None)
|
|
722
751
|
if output_file:
|
|
723
752
|
self._logger.info(f"Validating metadata for {output_file}")
|
|
@@ -738,7 +767,6 @@ class Simulator:
|
|
|
738
767
|
----------
|
|
739
768
|
corsika_log_files: list
|
|
740
769
|
List containing the original CORSIKA log file path.
|
|
741
|
-
|
|
742
770
|
"""
|
|
743
771
|
original_log = Path(corsika_log_files[0])
|
|
744
772
|
# Find which model version the original log belongs to
|
|
@@ -759,15 +787,20 @@ class Simulator:
|
|
|
759
787
|
original_version, model.model_version
|
|
760
788
|
)
|
|
761
789
|
|
|
762
|
-
with gzip.open(new_log, "wt") as new_file:
|
|
763
|
-
|
|
790
|
+
with gzip.open(new_log, "wt", encoding="utf-8") as new_file:
|
|
791
|
+
# Write the header to the new file
|
|
792
|
+
header = (
|
|
764
793
|
f"###############################################################\n"
|
|
765
794
|
f"Copy of CORSIKA log file from model version {original_version}.\n"
|
|
766
795
|
f"Applicable also for {model.model_version} (same CORSIKA configuration,\n"
|
|
767
796
|
f"different sim_telarray model versions in the same run).\n"
|
|
768
797
|
f"###############################################################\n\n"
|
|
769
798
|
)
|
|
770
|
-
|
|
771
|
-
|
|
799
|
+
new_file.write(header)
|
|
800
|
+
|
|
801
|
+
# Copy the content of the original log file, ignoring invalid characters
|
|
802
|
+
with gzip.open(original_log, "rt", encoding="utf-8", errors="ignore") as orig_file:
|
|
803
|
+
for line in orig_file:
|
|
804
|
+
new_file.write(line)
|
|
772
805
|
|
|
773
806
|
corsika_log_files.append(str(new_log))
|
|
@@ -102,7 +102,10 @@ def _validate_output_path_and_file(config, integration_file_tests):
|
|
|
102
102
|
|
|
103
103
|
output_file_path = Path(output_path) / file_test["FILE"]
|
|
104
104
|
_logger.info(f"Checking path: {output_file_path}")
|
|
105
|
-
|
|
105
|
+
try:
|
|
106
|
+
assert output_file_path.exists()
|
|
107
|
+
except AssertionError as exc:
|
|
108
|
+
raise AssertionError(f"Output file {output_file_path} does not exist. ") from exc
|
|
106
109
|
|
|
107
110
|
if "EXPECTED_OUTPUT" in file_test:
|
|
108
111
|
assert assertions.check_output_from_sim_telarray(
|
simtools/utils/general.py
CHANGED
|
@@ -178,7 +178,7 @@ def _collect_data_from_different_file_types(file, file_name, suffix, yaml_docume
|
|
|
178
178
|
"""Collect data from different file types."""
|
|
179
179
|
if suffix == ".json":
|
|
180
180
|
return json.load(file)
|
|
181
|
-
if suffix
|
|
181
|
+
if suffix in (".list", ".txt"):
|
|
182
182
|
return [line.strip() for line in file.readlines()]
|
|
183
183
|
if suffix in [".yml", ".yaml"]:
|
|
184
184
|
return _collect_data_from_yaml_file(file, file_name, yaml_document)
|
|
@@ -324,10 +324,8 @@ def get_log_level_from_user(log_level):
|
|
|
324
324
|
possible_levels = {
|
|
325
325
|
"info": logging.INFO,
|
|
326
326
|
"debug": logging.DEBUG,
|
|
327
|
-
"warn": logging.WARNING,
|
|
328
327
|
"warning": logging.WARNING,
|
|
329
328
|
"error": logging.ERROR,
|
|
330
|
-
"critical": logging.CRITICAL,
|
|
331
329
|
}
|
|
332
330
|
try:
|
|
333
331
|
log_level_lower = log_level.lower()
|
simtools/utils/names.py
CHANGED
|
@@ -12,6 +12,7 @@ Naming in simtools:
|
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
+
import json
|
|
15
16
|
import logging
|
|
16
17
|
import re
|
|
17
18
|
from functools import cache
|
|
@@ -22,7 +23,7 @@ import yaml
|
|
|
22
23
|
from simtools.constants import (
|
|
23
24
|
MODEL_PARAMETER_DESCRIPTION_METASCHEMA,
|
|
24
25
|
MODEL_PARAMETER_SCHEMA_PATH,
|
|
25
|
-
|
|
26
|
+
RESOURCE_PATH,
|
|
26
27
|
)
|
|
27
28
|
|
|
28
29
|
_logger = logging.getLogger(__name__)
|
|
@@ -59,10 +60,30 @@ def array_elements():
|
|
|
59
60
|
dict
|
|
60
61
|
Array elements.
|
|
61
62
|
"""
|
|
62
|
-
|
|
63
|
+
# for efficiency reason, no functions from simtools.utils.general are used here
|
|
64
|
+
with open(Path(RESOURCE_PATH) / "array_elements.yml", encoding="utf-8") as file:
|
|
63
65
|
return yaml.safe_load(file)["data"]
|
|
64
66
|
|
|
65
67
|
|
|
68
|
+
@cache
|
|
69
|
+
def array_element_common_identifiers():
|
|
70
|
+
"""
|
|
71
|
+
Get array element IDs from CTAO common identifier.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
dict, dict
|
|
76
|
+
Dictionary mapping array element names to their IDs and vice versa.
|
|
77
|
+
"""
|
|
78
|
+
# for efficiency reason, no functions from simtools.utils.general are used here
|
|
79
|
+
id_to_name = {}
|
|
80
|
+
with open(Path(RESOURCE_PATH) / "array-element-ids.json", encoding="utf-8") as file:
|
|
81
|
+
data = json.load(file)
|
|
82
|
+
id_to_name = {e["id"]: e["name"] for e in data["array_elements"]}
|
|
83
|
+
name_to_id = {e["name"]: e["id"] for e in data["array_elements"]}
|
|
84
|
+
return id_to_name, name_to_id
|
|
85
|
+
|
|
86
|
+
|
|
66
87
|
@cache
|
|
67
88
|
def simulation_software():
|
|
68
89
|
"""
|
|
@@ -415,6 +436,54 @@ def get_array_element_id_from_name(array_element_name):
|
|
|
415
436
|
raise ValueError(f"Invalid name {array_element_name}") from exc
|
|
416
437
|
|
|
417
438
|
|
|
439
|
+
def get_common_identifier_from_array_element_name(array_element_name, default_return=None):
|
|
440
|
+
"""
|
|
441
|
+
Get numerical common identifier from array element name as used by CTAO.
|
|
442
|
+
|
|
443
|
+
Common identifiers are numerical IDs used by the CTAO ACADA and DPPS systems.
|
|
444
|
+
|
|
445
|
+
Parameters
|
|
446
|
+
----------
|
|
447
|
+
array_element_name: str
|
|
448
|
+
Array element name (e.g. LSTN-01)
|
|
449
|
+
|
|
450
|
+
Returns
|
|
451
|
+
-------
|
|
452
|
+
int
|
|
453
|
+
Common identifier.
|
|
454
|
+
"""
|
|
455
|
+
_, name_to_id = array_element_common_identifiers()
|
|
456
|
+
try:
|
|
457
|
+
return name_to_id[array_element_name]
|
|
458
|
+
except KeyError as exc:
|
|
459
|
+
if default_return is not None:
|
|
460
|
+
return default_return
|
|
461
|
+
raise ValueError(f"Unknown array element name {array_element_name}") from exc
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def get_array_element_name_from_common_identifier(common_identifier):
|
|
465
|
+
"""
|
|
466
|
+
Get array element name from common identifier as used by CTAO.
|
|
467
|
+
|
|
468
|
+
Common identifiers are numerical IDs used by the CTAO ACADA and DPPS systems.
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
common_identifier: int
|
|
473
|
+
Common identifier.
|
|
474
|
+
|
|
475
|
+
Returns
|
|
476
|
+
-------
|
|
477
|
+
str
|
|
478
|
+
Array element name.
|
|
479
|
+
"""
|
|
480
|
+
id_to_name, _ = array_element_common_identifiers()
|
|
481
|
+
try:
|
|
482
|
+
return id_to_name[common_identifier]
|
|
483
|
+
except KeyError as exc:
|
|
484
|
+
raise ValueError(f"Unknown common identifier {common_identifier}") from exc
|
|
485
|
+
|
|
486
|
+
|
|
418
487
|
def get_list_of_array_element_types(
|
|
419
488
|
array_element_class="telescopes", site=None, observatory="CTAO"
|
|
420
489
|
):
|
|
@@ -658,7 +727,7 @@ def generate_file_name(
|
|
|
658
727
|
"""
|
|
659
728
|
Generate a file name for output, config, or plotting.
|
|
660
729
|
|
|
661
|
-
Used e.g., to generate
|
|
730
|
+
Used e.g., to generate camera_efficiency and ray_tracing output files.
|
|
662
731
|
|
|
663
732
|
Parameters
|
|
664
733
|
----------
|
|
@@ -690,10 +759,10 @@ def generate_file_name(
|
|
|
690
759
|
str
|
|
691
760
|
File name.
|
|
692
761
|
"""
|
|
693
|
-
name = f"{file_type}
|
|
694
|
-
name += f"
|
|
695
|
-
name += f"
|
|
696
|
-
name += f"
|
|
762
|
+
name = f"{file_type}_{site}_{telescope_model_name}"
|
|
763
|
+
name += f"_d{source_distance:.1f}km" if source_distance is not None else ""
|
|
764
|
+
name += f"_za{float(zenith_angle):.1f}deg"
|
|
765
|
+
name += f"_off{off_axis_angle:.3f}deg" if off_axis_angle is not None else ""
|
|
697
766
|
name += f"_azm{round(azimuth_angle):03}deg" if azimuth_angle is not None else ""
|
|
698
767
|
name += f"_mirror{mirror_number}" if mirror_number is not None else ""
|
|
699
768
|
name += f"_{label}" if label is not None else ""
|