gammasimtools 0.25.0__py3-none-any.whl → 0.26.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.26.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +122 -121
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +2 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +2 -2
- simtools/application_control.py +35 -7
- simtools/applications/calculate_incident_angles.py +0 -2
- simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -2
- 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 +2 -6
- 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/derive_mirror_rnda.py +1 -3
- 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 +48 -235
- simtools/applications/generate_regular_arrays.py +5 -35
- 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 +0 -2
- simtools/applications/simulate_illuminator.py +0 -1
- simtools/applications/simulate_pedestals.py +1 -5
- simtools/applications/simulate_prod.py +1 -5
- simtools/applications/simulate_prod_htcondor_generator.py +1 -1
- simtools/applications/submit_array_layouts.py +2 -4
- simtools/applications/submit_model_parameter_from_external.py +1 -3
- simtools/applications/validate_camera_efficiency.py +0 -1
- simtools/applications/validate_camera_fov.py +0 -1
- simtools/applications/validate_cumulative_psf.py +0 -2
- simtools/applications/validate_optics.py +0 -13
- simtools/camera/camera_efficiency.py +1 -6
- simtools/camera/single_photon_electron_spectrum.py +2 -1
- simtools/configuration/commandline_parser.py +35 -2
- simtools/configuration/configurator.py +6 -11
- simtools/corsika/corsika_config.py +16 -21
- simtools/corsika/corsika_histograms.py +411 -1735
- 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 +13 -15
- simtools/data_model/validate_data.py +1 -3
- simtools/db/db_handler.py +19 -8
- simtools/dependencies.py +81 -38
- simtools/io/ascii_handler.py +4 -2
- simtools/io/table_handler.py +1 -1
- simtools/layout/array_layout.py +4 -12
- simtools/layout/array_layout_utils.py +226 -57
- simtools/model/array_model.py +1 -13
- simtools/model/calibration_model.py +0 -4
- simtools/model/legacy_model_parameter.py +134 -0
- simtools/model/model_parameter.py +24 -13
- simtools/model/model_utils.py +1 -6
- simtools/model/site_model.py +0 -4
- simtools/model/telescope_model.py +6 -11
- simtools/production_configuration/derive_corsika_limits.py +6 -11
- simtools/production_configuration/interpolation_handler.py +16 -16
- simtools/ray_tracing/incident_angles.py +5 -11
- simtools/ray_tracing/mirror_panel_psf.py +3 -7
- simtools/ray_tracing/psf_analysis.py +18 -19
- simtools/ray_tracing/psf_parameter_optimisation.py +0 -1
- simtools/ray_tracing/ray_tracing.py +6 -15
- simtools/reporting/docs_auto_report_generator.py +8 -13
- simtools/reporting/docs_read_parameters.py +2 -8
- simtools/runners/corsika_runner.py +5 -9
- simtools/runners/corsika_simtel_runner.py +3 -8
- simtools/runners/simtel_runner.py +0 -5
- simtools/runners/simtools_runner.py +2 -4
- simtools/settings.py +154 -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 -36
- simtools/simtel/simtel_table_reader.py +6 -4
- simtools/simtel/simulator_array.py +4 -11
- simtools/simtel/simulator_camera_efficiency.py +4 -6
- simtools/simtel/simulator_light_emission.py +69 -24
- simtools/simtel/simulator_ray_tracing.py +4 -10
- simtools/simulator.py +7 -14
- 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 +1 -1
- simtools/testing/validate_output.py +34 -23
- simtools/utils/general.py +37 -0
- simtools/utils/geometry.py +0 -77
- simtools/utils/names.py +5 -5
- simtools/visualization/legend_handlers.py +7 -6
- simtools/visualization/plot_array_layout.py +91 -16
- simtools/visualization/plot_corsika_histograms.py +143 -605
- simtools/visualization/plot_mirrors.py +1 -4
- simtools/visualization/plot_pixels.py +2 -4
- simtools/visualization/plot_psf.py +0 -1
- 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.26.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
|
@@ -185,7 +185,7 @@ class PrimaryParticle:
|
|
|
185
185
|
"silicon": {"corsika7_id": 2814},
|
|
186
186
|
"iron": {"corsika7_id": 5626},
|
|
187
187
|
}
|
|
188
|
-
for
|
|
188
|
+
for ids in particles.values():
|
|
189
189
|
ids["pdg_id"] = Corsika7ID(ids["corsika7_id"]).to_pdgid().numerator
|
|
190
190
|
ids["pdg_name"] = Particle.findall(pdgid=ids["pdg_id"])[0].name
|
|
191
191
|
|
|
@@ -360,6 +360,9 @@ class MetadataCollector:
|
|
|
360
360
|
"Metadata extraction from sim_telarray files is not supported yet."
|
|
361
361
|
)
|
|
362
362
|
continue
|
|
363
|
+
elif Path(metadata_file).name.endswith((".corsika.zst", ".corsika")):
|
|
364
|
+
self._logger.warning("Metadata extraction from CORSIKA files is not supported yet.")
|
|
365
|
+
continue
|
|
363
366
|
else:
|
|
364
367
|
raise ValueError(f"Unknown metadata file format: {metadata_file}")
|
|
365
368
|
|
|
@@ -422,7 +425,7 @@ class MetadataCollector:
|
|
|
422
425
|
product_dict["creation_time"] = gen.now_date_time_in_isoformat()
|
|
423
426
|
product_dict["description"] = self.schema_dict.get("description", None)
|
|
424
427
|
|
|
425
|
-
# DATA:CATEGORY
|
|
428
|
+
# metadata DATA:CATEGORY
|
|
426
429
|
product_dict["data"]["category"] = "SIM"
|
|
427
430
|
product_dict["data"]["level"] = "R1"
|
|
428
431
|
product_dict["data"]["type"] = "Service"
|
|
@@ -431,7 +434,7 @@ class MetadataCollector:
|
|
|
431
434
|
except KeyError:
|
|
432
435
|
pass
|
|
433
436
|
|
|
434
|
-
# DATA:MODEL
|
|
437
|
+
# metadata DATA:MODEL
|
|
435
438
|
product_dict["data"]["model"]["name"] = (
|
|
436
439
|
self.schema_dict.get("name")
|
|
437
440
|
or self.args_dict.get("metadata_product_data_name")
|
|
@@ -8,13 +8,9 @@ Follows CTAO top-level data model definition.
|
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
import logging
|
|
12
|
-
|
|
13
11
|
import simtools.data_model.schema
|
|
14
12
|
import simtools.utils.general as gen
|
|
15
13
|
|
|
16
|
-
_logger = logging.getLogger(__name__)
|
|
17
|
-
|
|
18
14
|
|
|
19
15
|
def get_default_metadata_dict(
|
|
20
16
|
schema_file=None, observatory="CTA", schema_version="latest", lower_case=True
|
|
@@ -98,10 +98,10 @@ class ModelDataWriter:
|
|
|
98
98
|
output_file,
|
|
99
99
|
output_path=None,
|
|
100
100
|
metadata_input_dict=None,
|
|
101
|
-
db_config=None,
|
|
102
101
|
unit=None,
|
|
103
102
|
meta_parameter=False,
|
|
104
103
|
model_parameter_schema_version=None,
|
|
104
|
+
check_db_for_existing_parameter=True,
|
|
105
105
|
):
|
|
106
106
|
"""
|
|
107
107
|
Generate DB-style model parameter dict and write it to json file.
|
|
@@ -122,14 +122,14 @@ class ModelDataWriter:
|
|
|
122
122
|
Path to output file.
|
|
123
123
|
metadata_input_dict: dict
|
|
124
124
|
Input to metadata collector.
|
|
125
|
-
db_config: dict
|
|
126
|
-
Database configuration. If not None, check if parameter with the same version exists.
|
|
127
125
|
unit: str
|
|
128
126
|
Unit of the parameter value (if applicable and value is not of type astropy Quantity).
|
|
129
127
|
meta_parameter: bool
|
|
130
128
|
Setting for meta parameter flag.
|
|
131
129
|
model_parameter_schema_version: str, None
|
|
132
130
|
Version of the model parameter schema (if None, use schema version from schema dict).
|
|
131
|
+
check_db_for_existing_parameter: bool
|
|
132
|
+
If True, check if parameter with same version exists in DB before writing.
|
|
133
133
|
|
|
134
134
|
Returns
|
|
135
135
|
-------
|
|
@@ -142,10 +142,8 @@ class ModelDataWriter:
|
|
|
142
142
|
args_dict=None,
|
|
143
143
|
output_path=output_path,
|
|
144
144
|
)
|
|
145
|
-
if
|
|
146
|
-
writer.check_db_for_existing_parameter(
|
|
147
|
-
parameter_name, instrument, parameter_version, db_config
|
|
148
|
-
)
|
|
145
|
+
if check_db_for_existing_parameter:
|
|
146
|
+
writer.check_db_for_existing_parameter(parameter_name, instrument, parameter_version)
|
|
149
147
|
|
|
150
148
|
unique_id = None
|
|
151
149
|
if metadata_input_dict is not None:
|
|
@@ -170,9 +168,7 @@ class ModelDataWriter:
|
|
|
170
168
|
writer.write_dict_to_model_parameter_json(output_file, _json_dict)
|
|
171
169
|
return _json_dict
|
|
172
170
|
|
|
173
|
-
def check_db_for_existing_parameter(
|
|
174
|
-
self, parameter_name, instrument, parameter_version, db_config
|
|
175
|
-
):
|
|
171
|
+
def check_db_for_existing_parameter(self, parameter_name, instrument, parameter_version):
|
|
176
172
|
"""
|
|
177
173
|
Check if a parameter with the same version exists in the simulation model database.
|
|
178
174
|
|
|
@@ -184,15 +180,15 @@ class ModelDataWriter:
|
|
|
184
180
|
Name of the instrument.
|
|
185
181
|
parameter_version: str
|
|
186
182
|
Version of the parameter.
|
|
187
|
-
db_config: dict
|
|
188
|
-
Database configuration.
|
|
189
183
|
|
|
190
184
|
Raises
|
|
191
185
|
------
|
|
192
186
|
ValueError
|
|
193
187
|
If parameter with the same version exists in the database.
|
|
194
188
|
"""
|
|
195
|
-
db = db_handler.DatabaseHandler(
|
|
189
|
+
db = db_handler.DatabaseHandler()
|
|
190
|
+
if not db.is_configured():
|
|
191
|
+
return
|
|
196
192
|
try:
|
|
197
193
|
db.get_model_parameter(
|
|
198
194
|
parameter=parameter_name,
|
|
@@ -373,8 +369,10 @@ class ModelDataWriter:
|
|
|
373
369
|
"""
|
|
374
370
|
try:
|
|
375
371
|
unit_list = []
|
|
376
|
-
|
|
377
|
-
|
|
372
|
+
unit_list = [
|
|
373
|
+
data["unit"] if data["unit"] != "dimensionless" else None
|
|
374
|
+
for data in self.schema_dict["data"]
|
|
375
|
+
]
|
|
378
376
|
return unit_list if len(unit_list) > 1 else unit_list[0]
|
|
379
377
|
except (KeyError, IndexError):
|
|
380
378
|
pass
|
|
@@ -928,9 +928,7 @@ class DataValidator:
|
|
|
928
928
|
"""Return value as sorted list."""
|
|
929
929
|
return [value] if isinstance(value, str) else sorted(value)
|
|
930
930
|
|
|
931
|
-
instrument_sites = []
|
|
932
|
-
for inst in instruments:
|
|
933
|
-
instrument_sites.append(names.get_site_from_array_element_name(inst))
|
|
931
|
+
instrument_sites = [names.get_site_from_array_element_name(inst) for inst in instruments]
|
|
934
932
|
# names.get_site_from_array_element_name might return a list
|
|
935
933
|
flat_sites = [
|
|
936
934
|
s
|
simtools/db/db_handler.py
CHANGED
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from simtools import settings
|
|
7
8
|
from simtools.data_model import validate_data
|
|
8
9
|
from simtools.db.mongo_db import MongoDBHandler
|
|
9
10
|
from simtools.io import io_handler
|
|
@@ -20,11 +21,6 @@ class DatabaseHandler:
|
|
|
20
21
|
|
|
21
22
|
- db_simulation_model_version (from db_config): version of the simulation model database
|
|
22
23
|
- model_version (from production_tables): version of the model contained in the database
|
|
23
|
-
|
|
24
|
-
Parameters
|
|
25
|
-
----------
|
|
26
|
-
db_config: dict
|
|
27
|
-
Dictionary with the DB configuration.
|
|
28
24
|
"""
|
|
29
25
|
|
|
30
26
|
ALLOWED_FILE_EXTENSIONS = [".dat", ".txt", ".lis", ".cfg", ".yml", ".yaml", ".ecsv"]
|
|
@@ -33,13 +29,17 @@ class DatabaseHandler:
|
|
|
33
29
|
model_parameters_cached = {}
|
|
34
30
|
model_versions_cached = {}
|
|
35
31
|
|
|
36
|
-
def __init__(self
|
|
32
|
+
def __init__(self):
|
|
37
33
|
"""Initialize the DatabaseHandler class."""
|
|
38
34
|
self._logger = logging.getLogger(__name__)
|
|
39
35
|
|
|
40
|
-
self.db_config =
|
|
36
|
+
self.db_config = (
|
|
37
|
+
MongoDBHandler.validate_db_config(dict(settings.config.db_config))
|
|
38
|
+
if settings.config.db_config
|
|
39
|
+
else None
|
|
40
|
+
)
|
|
41
41
|
self.io_handler = io_handler.IOHandler()
|
|
42
|
-
self.mongo_db_handler = MongoDBHandler(db_config) if self.db_config else None
|
|
42
|
+
self.mongo_db_handler = MongoDBHandler(self.db_config) if self.db_config else None
|
|
43
43
|
|
|
44
44
|
self.db_name = (
|
|
45
45
|
MongoDBHandler.get_db_name(
|
|
@@ -50,6 +50,17 @@ class DatabaseHandler:
|
|
|
50
50
|
else None
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
+
def is_configured(self):
|
|
54
|
+
"""
|
|
55
|
+
Check if the DatabaseHandler is configured.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
bool
|
|
60
|
+
True if the DatabaseHandler is configured, False otherwise.
|
|
61
|
+
"""
|
|
62
|
+
return self.mongo_db_handler is not None
|
|
63
|
+
|
|
53
64
|
def get_db_name(self, db_name=None, db_simulation_model_version=None, model_name=None):
|
|
54
65
|
"""Build DB name from configuration."""
|
|
55
66
|
if db_name:
|
simtools/dependencies.py
CHANGED
|
@@ -9,27 +9,26 @@ This modules provides two main functionalities:
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
|
-
import os
|
|
13
12
|
import re
|
|
14
13
|
import subprocess
|
|
15
14
|
from pathlib import Path
|
|
16
15
|
|
|
17
16
|
import yaml
|
|
18
17
|
|
|
18
|
+
from simtools import settings
|
|
19
19
|
from simtools.io import ascii_handler
|
|
20
|
+
from simtools.utils import general as gen
|
|
20
21
|
from simtools.version import __version__
|
|
21
22
|
|
|
22
23
|
_logger = logging.getLogger(__name__)
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def get_version_string(
|
|
26
|
+
def get_version_string(run_time=None):
|
|
26
27
|
"""
|
|
27
28
|
Print the versions of the dependencies.
|
|
28
29
|
|
|
29
30
|
Parameters
|
|
30
31
|
----------
|
|
31
|
-
db_config : dict, optional
|
|
32
|
-
Database configuration dictionary.
|
|
33
32
|
run_time : list, optional
|
|
34
33
|
Runtime environment command (e.g., Docker).
|
|
35
34
|
|
|
@@ -40,10 +39,13 @@ def get_version_string(db_config=None, run_time=None):
|
|
|
40
39
|
|
|
41
40
|
"""
|
|
42
41
|
return (
|
|
43
|
-
f"Database name: {get_database_version_or_name(
|
|
44
|
-
f"Database version: {get_database_version_or_name(
|
|
42
|
+
f"Database name: {get_database_version_or_name(version=False)}\n"
|
|
43
|
+
f"Database version: {get_database_version_or_name(version=True)}\n"
|
|
45
44
|
f"sim_telarray version: {get_sim_telarray_version(run_time)}\n"
|
|
45
|
+
"sim_telarray exe: "
|
|
46
|
+
f"{settings.config.sim_telarray_exe if settings.config.sim_telarray_exe else 'None'}\n"
|
|
46
47
|
f"CORSIKA version: {get_corsika_version(run_time)}\n"
|
|
48
|
+
f"CORSIKA exe: {settings.config.corsika_exe if settings.config.corsika_exe else 'None'}\n"
|
|
47
49
|
f"Build options: {get_build_options(run_time)}\n"
|
|
48
50
|
f"Runtime environment: {run_time if run_time else 'None'}\n"
|
|
49
51
|
)
|
|
@@ -73,14 +75,12 @@ def get_software_version(software):
|
|
|
73
75
|
raise ValueError(f"Unknown software: {software}") from exc
|
|
74
76
|
|
|
75
77
|
|
|
76
|
-
def get_database_version_or_name(
|
|
78
|
+
def get_database_version_or_name(version=True):
|
|
77
79
|
"""
|
|
78
80
|
Get the version or name of the simulation model data base used.
|
|
79
81
|
|
|
80
82
|
Parameters
|
|
81
83
|
----------
|
|
82
|
-
db_config : dict
|
|
83
|
-
Dictionary containing the database configuration.
|
|
84
84
|
version : bool
|
|
85
85
|
If True, return the version of the database. If False, return the name.
|
|
86
86
|
|
|
@@ -91,8 +91,10 @@ def get_database_version_or_name(db_config, version=True):
|
|
|
91
91
|
|
|
92
92
|
"""
|
|
93
93
|
if version:
|
|
94
|
-
return db_config and db_config.get(
|
|
95
|
-
|
|
94
|
+
return settings.config.db_config and settings.config.db_config.get(
|
|
95
|
+
"db_simulation_model_version"
|
|
96
|
+
)
|
|
97
|
+
return settings.config.db_config and settings.config.db_config.get("db_simulation_model")
|
|
96
98
|
|
|
97
99
|
|
|
98
100
|
def get_sim_telarray_version(run_time=None):
|
|
@@ -111,16 +113,13 @@ def get_sim_telarray_version(run_time=None):
|
|
|
111
113
|
str
|
|
112
114
|
Version of the sim_telarray package.
|
|
113
115
|
"""
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
_logger.warning("Environment variable SIMTOOLS_SIMTEL_PATH is not set.")
|
|
116
|
+
if settings.config.sim_telarray_exe is None:
|
|
117
|
+
_logger.warning("sim_telarray environment not configured.")
|
|
117
118
|
return None
|
|
118
|
-
sim_telarray_path = Path(sim_telarray_path) / "sim_telarray" / "bin" / "sim_telarray"
|
|
119
|
-
|
|
120
119
|
if run_time is None:
|
|
121
|
-
command = [str(
|
|
120
|
+
command = [str(settings.config.sim_telarray_exe), "--version"]
|
|
122
121
|
else:
|
|
123
|
-
command = [*run_time, str(
|
|
122
|
+
command = [*run_time, str(settings.config.sim_telarray_exe), "--version"]
|
|
124
123
|
|
|
125
124
|
_logger.debug(f"Running command: {command}")
|
|
126
125
|
result = subprocess.run(command, capture_output=True, text=True, check=False)
|
|
@@ -151,19 +150,15 @@ def get_corsika_version(run_time=None):
|
|
|
151
150
|
str
|
|
152
151
|
Version of the CORSIKA package.
|
|
153
152
|
"""
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
_logger.warning("Environment variable SIMTOOLS_SIMTEL_PATH is not set.")
|
|
153
|
+
if settings.config.corsika_exe is None:
|
|
154
|
+
_logger.warning("CORSIKA environment not configured.")
|
|
157
155
|
return None
|
|
158
|
-
corsika_command = Path(corsika_path) / "corsika-run" / "corsika"
|
|
159
156
|
|
|
160
157
|
if run_time is None:
|
|
161
|
-
command = [str(
|
|
158
|
+
command = [str(settings.config.corsika_exe)]
|
|
162
159
|
else:
|
|
163
|
-
command = [*run_time, str(
|
|
160
|
+
command = [*run_time, str(settings.config.corsika_exe)]
|
|
164
161
|
|
|
165
|
-
# Below I do not use the standard context manager because
|
|
166
|
-
# it makes mocking in the tests significantly more difficult
|
|
167
162
|
process = subprocess.Popen( # pylint: disable=consider-using-with
|
|
168
163
|
command,
|
|
169
164
|
stdout=subprocess.PIPE,
|
|
@@ -197,9 +192,14 @@ def get_corsika_version(run_time=None):
|
|
|
197
192
|
|
|
198
193
|
def get_build_options(run_time=None):
|
|
199
194
|
"""
|
|
200
|
-
Return CORSIKA / sim_telarray build options.
|
|
195
|
+
Return CORSIKA / sim_telarray config and build options.
|
|
196
|
+
|
|
197
|
+
For CORSIKA / sim_telarray build for simtools version >0.25.0:
|
|
198
|
+
expects build_opts.yml file in each CORSIKA and sim_telarray
|
|
199
|
+
directories.
|
|
201
200
|
|
|
202
|
-
|
|
201
|
+
For CORSIKA / sim_telarray build for simtools version <=0.25.0:
|
|
202
|
+
expects a build_opts.yml file in the sim_telarray directory.
|
|
203
203
|
|
|
204
204
|
Parameters
|
|
205
205
|
----------
|
|
@@ -209,28 +209,71 @@ def get_build_options(run_time=None):
|
|
|
209
209
|
Returns
|
|
210
210
|
-------
|
|
211
211
|
dict
|
|
212
|
-
|
|
212
|
+
CORSIKA / sim_telarray build options.
|
|
213
213
|
"""
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
build_opts = {}
|
|
215
|
+
for package in ["corsika", "sim_telarray"]:
|
|
216
|
+
path = _get_package_path(package)
|
|
217
|
+
if not path:
|
|
218
|
+
continue
|
|
219
|
+
try:
|
|
220
|
+
build_opts.update(_get_build_options_from_file(path / "build_opts.yml", run_time))
|
|
221
|
+
except (FileNotFoundError, TypeError, ValueError):
|
|
222
|
+
# legacy fallback only for sim_telarray
|
|
223
|
+
if package == "sim_telarray":
|
|
224
|
+
try:
|
|
225
|
+
legacy_path = path.parent / "build_opts.yml"
|
|
226
|
+
build_opts.update(_get_build_options_from_file(legacy_path, run_time))
|
|
227
|
+
except (FileNotFoundError, TypeError, ValueError):
|
|
228
|
+
_logger.debug(f"No build options found for {package}.")
|
|
229
|
+
if not build_opts:
|
|
230
|
+
raise FileNotFoundError("No build option file found.")
|
|
231
|
+
|
|
232
|
+
return build_opts
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _get_package_path(package):
|
|
236
|
+
"""Get the package path from settings or environment variables."""
|
|
237
|
+
path = getattr(settings.config, f"{package}_path")
|
|
238
|
+
if path is None:
|
|
239
|
+
path = gen.load_environment_variables().get(f"{package}_path")
|
|
240
|
+
return Path(path) if path else None
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _get_build_options_from_file(build_opts_path, run_time=None):
|
|
244
|
+
"""Read build options from file."""
|
|
220
245
|
if run_time is None:
|
|
221
246
|
try:
|
|
222
247
|
return ascii_handler.collect_data_from_file(build_opts_path)
|
|
223
248
|
except FileNotFoundError as exc:
|
|
224
|
-
raise FileNotFoundError("No
|
|
249
|
+
raise FileNotFoundError("No build option file found.") from exc
|
|
225
250
|
|
|
226
251
|
command = [*run_time, "cat", str(build_opts_path)]
|
|
227
|
-
_logger.debug(f"Reading
|
|
252
|
+
_logger.debug(f"Reading build option with command: {command}")
|
|
228
253
|
|
|
229
254
|
result = subprocess.run(command, capture_output=True, text=True, check=False)
|
|
230
255
|
if result.returncode:
|
|
231
|
-
raise FileNotFoundError(f"No
|
|
256
|
+
raise FileNotFoundError(f"No build option file found in container: {result.stderr}")
|
|
232
257
|
|
|
233
258
|
try:
|
|
234
259
|
return yaml.safe_load(result.stdout)
|
|
235
260
|
except yaml.YAMLError as exc:
|
|
236
261
|
raise ValueError(f"Error parsing build_opts.yml from container: {exc}") from exc
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def export_build_info(output_file, run_time=None):
|
|
265
|
+
"""
|
|
266
|
+
Export build and version information to a file.
|
|
267
|
+
|
|
268
|
+
Parameters
|
|
269
|
+
----------
|
|
270
|
+
output_file : str
|
|
271
|
+
Path to the output file.
|
|
272
|
+
run_time : list, optional
|
|
273
|
+
Runtime environment command (e.g., Docker).
|
|
274
|
+
"""
|
|
275
|
+
build_info = get_build_options(run_time)
|
|
276
|
+
build_info["simtools"] = __version__
|
|
277
|
+
build_info["database_name"] = get_database_version_or_name(version=False)
|
|
278
|
+
build_info["database_version"] = get_database_version_or_name(version=True)
|
|
279
|
+
ascii_handler.write_data_to_file(data=build_info, output_file=Path(output_file))
|
simtools/io/ascii_handler.py
CHANGED
|
@@ -208,9 +208,11 @@ def write_data_to_file(data, output_file, sort_keys=False, numpy_types=False):
|
|
|
208
208
|
"""
|
|
209
209
|
output_file = Path(output_file)
|
|
210
210
|
if output_file.suffix.lower() == ".json":
|
|
211
|
-
|
|
211
|
+
_write_to_json(data, output_file, sort_keys, numpy_types)
|
|
212
|
+
return
|
|
212
213
|
if output_file.suffix.lower() in [".yml", ".yaml"]:
|
|
213
|
-
|
|
214
|
+
_write_to_yaml(data, output_file, sort_keys)
|
|
215
|
+
return
|
|
214
216
|
|
|
215
217
|
raise ValueError(
|
|
216
218
|
f"Unsupported file type {output_file.suffix}. Only .json, .yml, and .yaml are supported."
|
simtools/io/table_handler.py
CHANGED
|
@@ -295,7 +295,7 @@ def write_table_in_hdf5(table, output_file, table_name):
|
|
|
295
295
|
None
|
|
296
296
|
"""
|
|
297
297
|
for col in table.colnames:
|
|
298
|
-
if table[col].dtype.kind == "U": #
|
|
298
|
+
if table[col].dtype.kind == "U": # hdf5 does not support unicode
|
|
299
299
|
table[col] = table[col].astype("S")
|
|
300
300
|
|
|
301
301
|
with h5py.File(output_file, "a") as f:
|
simtools/layout/array_layout.py
CHANGED
|
@@ -32,8 +32,6 @@ class ArrayLayout:
|
|
|
32
32
|
|
|
33
33
|
Parameters
|
|
34
34
|
----------
|
|
35
|
-
db_config: dict
|
|
36
|
-
Database configuration.
|
|
37
35
|
site: str
|
|
38
36
|
Site name or location (e.g., North/South or LaPalma/Paranal)
|
|
39
37
|
model_version: str
|
|
@@ -52,7 +50,6 @@ class ArrayLayout:
|
|
|
52
50
|
|
|
53
51
|
def __init__(
|
|
54
52
|
self,
|
|
55
|
-
db_config,
|
|
56
53
|
site,
|
|
57
54
|
model_version,
|
|
58
55
|
label=None,
|
|
@@ -67,7 +64,6 @@ class ArrayLayout:
|
|
|
67
64
|
self.model_version = model_version
|
|
68
65
|
self.label = label
|
|
69
66
|
self.name = name
|
|
70
|
-
self.db_config = db_config
|
|
71
67
|
self.site = None if site is None else names.validate_site_name(site)
|
|
72
68
|
self.site_model = None
|
|
73
69
|
self.io_handler = io_handler.IOHandler()
|
|
@@ -95,14 +91,11 @@ class ArrayLayout:
|
|
|
95
91
|
def _initialize_site_parameters_from_db(self):
|
|
96
92
|
"""Initialize site parameters required for transformations using the database."""
|
|
97
93
|
self._logger.debug("Initialize parameters from DB")
|
|
98
|
-
if self.db_config is None:
|
|
99
|
-
raise ValueError("No database configuration provided")
|
|
100
94
|
|
|
101
|
-
|
|
102
|
-
site=self.site,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
95
|
+
try:
|
|
96
|
+
self.site_model = SiteModel(site=self.site, model_version=self.model_version)
|
|
97
|
+
except RuntimeError as e:
|
|
98
|
+
raise ValueError("No database configuration provided") from e
|
|
106
99
|
self._corsika_observation_level = self.site_model.get_corsika_site_parameters().get(
|
|
107
100
|
"corsika_observation_level", None
|
|
108
101
|
)
|
|
@@ -419,7 +412,6 @@ class ArrayLayout:
|
|
|
419
412
|
site=self.site,
|
|
420
413
|
telescope_name=telescope_name,
|
|
421
414
|
model_version=self.model_version,
|
|
422
|
-
db_config=self.db_config,
|
|
423
415
|
label=self.label,
|
|
424
416
|
)
|
|
425
417
|
|