gammasimtools 0.17.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.17.0.dist-info → gammasimtools-0.18.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.18.0.dist-info}/RECORD +44 -42
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.18.0.dist-info}/entry_points.txt +1 -0
- simtools/_version.py +2 -2
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +10 -1
- simtools/applications/derive_mirror_rnda.py +1 -1
- simtools/applications/generate_simtel_event_data.py +95 -3
- simtools/applications/merge_tables.py +14 -16
- 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 +61 -23
- simtools/configuration/commandline_parser.py +2 -1
- simtools/constants.py +2 -0
- simtools/data_model/schema.py +15 -1
- simtools/db/db_handler.py +5 -0
- simtools/io_operations/io_table_handler.py +1 -1
- simtools/layout/array_layout_utils.py +5 -1
- simtools/model/array_model.py +5 -1
- simtools/production_configuration/derive_corsika_limits_grid.py +46 -3
- simtools/resources/array-element-ids.json +126 -0
- 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/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/simtel/simtel_io_event_reader.py +1 -1
- simtools/simtel/simtel_io_event_writer.py +37 -1
- simtools/simtel/simtel_io_metadata.py +99 -3
- simtools/utils/general.py +0 -2
- simtools/utils/names.py +71 -2
- simtools/visualization/plot_pixels.py +0 -1
- simtools/visualization/plot_tables.py +81 -2
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.18.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.17.0.dist-info → gammasimtools-0.18.0.dist-info}/top_level.txt +0 -0
- /simtools/{schemas → resources}/array_elements.yml +0 -0
|
@@ -32,3 +32,15 @@ source:
|
|
|
32
32
|
- Calibration
|
|
33
33
|
simulation_software:
|
|
34
34
|
- name: simtools
|
|
35
|
+
plot_configuration:
|
|
36
|
+
- type: nsb_reference_spectrum
|
|
37
|
+
title: 'NSB spectrum'
|
|
38
|
+
xtitle: 'Wavelength [nm]'
|
|
39
|
+
ytitle: 'Differential photon rate [10^9 / (nm s m^2 sr)]'
|
|
40
|
+
xscale: 'linear'
|
|
41
|
+
yscale: 'log'
|
|
42
|
+
no_markers: true
|
|
43
|
+
tables:
|
|
44
|
+
- parameter: nsb_reference_spectrum
|
|
45
|
+
column_x: 'wavelength'
|
|
46
|
+
column_y: 'differential photon rate'
|
|
@@ -39,3 +39,22 @@ source:
|
|
|
39
39
|
- Calibration
|
|
40
40
|
simulation_software:
|
|
41
41
|
- name: sim_telarray
|
|
42
|
+
plot_configuration:
|
|
43
|
+
- type: pm_photoelectron_spectrum
|
|
44
|
+
title: 'Single p.e. response'
|
|
45
|
+
xtitle: 'Amplitude'
|
|
46
|
+
ytitle: 'Response'
|
|
47
|
+
xscale: 'linear'
|
|
48
|
+
yscale: 'log'
|
|
49
|
+
xlim: [0., 40.]
|
|
50
|
+
ylim: [1.e-11, null]
|
|
51
|
+
no_markers: true
|
|
52
|
+
tables:
|
|
53
|
+
- parameter: pm_photoelectron_spectrum
|
|
54
|
+
label: 'prompt'
|
|
55
|
+
column_x: 'amplitude'
|
|
56
|
+
column_y: 'response'
|
|
57
|
+
- parameter: pm_photoelectron_spectrum
|
|
58
|
+
label: 'prompt + afterpulsing'
|
|
59
|
+
column_x: 'amplitude'
|
|
60
|
+
column_y: 'response_with_ap'
|
|
@@ -40,3 +40,13 @@ source:
|
|
|
40
40
|
- Calibration
|
|
41
41
|
simulation_software:
|
|
42
42
|
- name: sim_telarray
|
|
43
|
+
plot_configuration:
|
|
44
|
+
- type: quantum_efficiency
|
|
45
|
+
title: 'Quantum/detection efficiency'
|
|
46
|
+
xtitle: 'Wavelength [nm]'
|
|
47
|
+
ytitle: 'Quantum/detection efficiency'
|
|
48
|
+
no_markers: true
|
|
49
|
+
tables:
|
|
50
|
+
- parameter: quantum_efficiency
|
|
51
|
+
column_x: 'wavelength'
|
|
52
|
+
column_y: 'efficiency'
|
|
@@ -6,157 +6,146 @@ description: YAML representation of plot configuration metaschema
|
|
|
6
6
|
version: 0.1.0
|
|
7
7
|
name: plot_configuration.metaschema
|
|
8
8
|
type: object
|
|
9
|
-
additionalProperties: false
|
|
10
9
|
|
|
11
10
|
definitions:
|
|
12
11
|
SimtoolsPlotConfiguration:
|
|
13
12
|
type: object
|
|
14
13
|
additionalProperties: false
|
|
15
14
|
properties:
|
|
16
|
-
|
|
17
|
-
"$ref": "#/definitions/
|
|
18
|
-
|
|
15
|
+
plot:
|
|
16
|
+
"$ref": "#/definitions/plot"
|
|
17
|
+
schema_version:
|
|
19
18
|
type: string
|
|
20
19
|
description: "Version of the schema."
|
|
21
|
-
|
|
20
|
+
schema_url:
|
|
22
21
|
type: string
|
|
23
22
|
format: uri
|
|
24
23
|
description: "URL of the schema."
|
|
25
|
-
|
|
24
|
+
schema_name:
|
|
26
25
|
type: string
|
|
27
26
|
description: "Name of the schema."
|
|
28
27
|
required:
|
|
29
|
-
-
|
|
28
|
+
- plot
|
|
30
29
|
title: "SimtoolsPlotConfiguration"
|
|
31
|
-
|
|
32
|
-
type: object
|
|
33
|
-
additionalProperties: false
|
|
34
|
-
properties:
|
|
35
|
-
PLOT:
|
|
36
|
-
"$ref": "#/definitions/Plot"
|
|
37
|
-
required:
|
|
38
|
-
- PLOT
|
|
39
|
-
title: "CTASimpipe"
|
|
40
|
-
Plot:
|
|
30
|
+
plot:
|
|
41
31
|
description: "Plot configuration of simtools data visualization."
|
|
42
32
|
type: object
|
|
43
33
|
additionalProperties: false
|
|
44
34
|
properties:
|
|
45
|
-
|
|
35
|
+
type:
|
|
46
36
|
type: string
|
|
47
37
|
description: "Type of the plot (e.g., mirror reflectivity, quantum_efficiency)."
|
|
48
|
-
|
|
38
|
+
title:
|
|
49
39
|
type: string
|
|
50
40
|
description: "Title of the plot."
|
|
51
|
-
|
|
41
|
+
xtitle:
|
|
52
42
|
type: string
|
|
53
43
|
description: "Title of x-axis."
|
|
54
|
-
|
|
44
|
+
ytitle:
|
|
55
45
|
type: string
|
|
56
46
|
description: "Title of y-axis."
|
|
57
|
-
|
|
47
|
+
xscale:
|
|
58
48
|
type: string
|
|
59
49
|
enum: ["linear", "log"]
|
|
60
50
|
description: "Scale of x-axis (linear or log)."
|
|
61
|
-
|
|
51
|
+
yscale:
|
|
62
52
|
type: string
|
|
63
53
|
enum: ["linear", "log"]
|
|
64
54
|
description: "Scale of y-axis (linear or log)."
|
|
65
|
-
|
|
55
|
+
xlim:
|
|
66
56
|
type: array
|
|
67
57
|
items:
|
|
68
58
|
type: [number, "null"]
|
|
69
59
|
description: "Limits for x-axis [min, max]. Use null for auto-limit."
|
|
70
60
|
minItems: 2
|
|
71
61
|
maxItems: 2
|
|
72
|
-
|
|
62
|
+
ylim:
|
|
73
63
|
type: array
|
|
74
64
|
items:
|
|
75
65
|
type: [number, "null"]
|
|
76
66
|
description: "Limits for y-axis [min, max]. Use null for auto-limit."
|
|
77
67
|
minItems: 2
|
|
78
68
|
maxItems: 2
|
|
79
|
-
|
|
69
|
+
error_type:
|
|
80
70
|
type: string
|
|
81
71
|
enum: ["fill_between", "errorbar", "none"]
|
|
82
72
|
description: "Type of errors."
|
|
83
|
-
|
|
73
|
+
no_markers:
|
|
84
74
|
type: boolean
|
|
85
75
|
description: "Whether to display markers on data points."
|
|
86
|
-
|
|
76
|
+
plot_ratio:
|
|
87
77
|
type: boolean
|
|
88
78
|
description: "Whether to display ratio plot."
|
|
89
|
-
|
|
79
|
+
tables:
|
|
90
80
|
type: array
|
|
91
81
|
description: "List of tables to plot."
|
|
92
82
|
items:
|
|
93
|
-
"$ref": "#/definitions/
|
|
83
|
+
"$ref": "#/definitions/table_config"
|
|
94
84
|
required:
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
85
|
+
- type
|
|
86
|
+
- title
|
|
87
|
+
- xtitle
|
|
88
|
+
- ytitle
|
|
89
|
+
- tables
|
|
100
90
|
title: "Plot"
|
|
101
|
-
|
|
91
|
+
table_config:
|
|
102
92
|
type: object
|
|
103
93
|
description: "Configuration for a data table to plot."
|
|
104
94
|
additionalProperties: false
|
|
105
95
|
properties:
|
|
106
|
-
|
|
96
|
+
parameter:
|
|
107
97
|
type: string
|
|
108
98
|
description: "Parameter name to retrieve data for."
|
|
109
|
-
|
|
99
|
+
file_name:
|
|
110
100
|
type: string
|
|
111
101
|
description: "Path to the data file."
|
|
112
|
-
|
|
102
|
+
type:
|
|
113
103
|
type: string
|
|
114
104
|
description: "Type of data file."
|
|
115
|
-
|
|
105
|
+
telescope:
|
|
116
106
|
type: string
|
|
117
107
|
description: "Telescope descriptor to retrieve data for."
|
|
118
|
-
|
|
108
|
+
site:
|
|
119
109
|
type: string
|
|
120
110
|
description: "Site name (North/South)."
|
|
121
|
-
|
|
111
|
+
model_version:
|
|
122
112
|
type: string
|
|
123
113
|
description: "Model version to use."
|
|
124
|
-
|
|
114
|
+
parameter_version:
|
|
125
115
|
type: string
|
|
126
116
|
description: "Parameter version to use."
|
|
127
|
-
|
|
117
|
+
label:
|
|
128
118
|
type: string
|
|
129
119
|
description: "Label for the plot legend."
|
|
130
|
-
|
|
120
|
+
column_x:
|
|
131
121
|
type: string
|
|
132
122
|
description: "Column name to use for x-axis."
|
|
133
|
-
|
|
123
|
+
column_y:
|
|
134
124
|
type: string
|
|
135
125
|
description: "Column name to use for y-axis."
|
|
136
|
-
|
|
126
|
+
column_x_err:
|
|
137
127
|
type: string
|
|
138
128
|
description: "Column name to use for x-axis error."
|
|
139
|
-
|
|
129
|
+
column_y_err:
|
|
140
130
|
type: string
|
|
141
131
|
description: "Column name to use for y-axis error."
|
|
142
|
-
|
|
132
|
+
normalize_y:
|
|
143
133
|
type: boolean
|
|
144
134
|
description: "Whether to normalize y values."
|
|
145
|
-
|
|
135
|
+
select_values:
|
|
146
136
|
type: object
|
|
147
137
|
description: "Selection criteria for data filtering."
|
|
148
138
|
properties:
|
|
149
|
-
|
|
139
|
+
column_name:
|
|
150
140
|
type: string
|
|
151
141
|
description: "Column name to use for filtering."
|
|
152
|
-
|
|
142
|
+
value:
|
|
153
143
|
type: [number, string]
|
|
154
144
|
description: "Value to filter by."
|
|
155
145
|
required:
|
|
156
|
-
-
|
|
157
|
-
-
|
|
146
|
+
- column_name
|
|
147
|
+
- value
|
|
158
148
|
required:
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
- LABEL
|
|
149
|
+
- column_x
|
|
150
|
+
- column_y
|
|
162
151
|
title: "TableConfig"
|
|
@@ -144,7 +144,7 @@ class SimtelIOEventDataReader:
|
|
|
144
144
|
for col in table.colnames:
|
|
145
145
|
if col == "telescope_list":
|
|
146
146
|
arrays = [
|
|
147
|
-
np.array(list(map(
|
|
147
|
+
np.array(list(map(str, tel_list.split(","))), dtype=np.str_)
|
|
148
148
|
for tel_list in table[col]
|
|
149
149
|
]
|
|
150
150
|
triggered_data.telescope_list = arrays
|
|
@@ -18,7 +18,11 @@ from eventio.simtel import (
|
|
|
18
18
|
|
|
19
19
|
from simtools.corsika.primary_particle import PrimaryParticle
|
|
20
20
|
from simtools.simtel.simtel_io_file_info import get_corsika_run_header
|
|
21
|
+
from simtools.simtel.simtel_io_metadata import (
|
|
22
|
+
get_sim_telarray_telescope_id_to_telescope_name_mapping,
|
|
23
|
+
)
|
|
21
24
|
from simtools.utils.geometry import calculate_circular_mean
|
|
25
|
+
from simtools.utils.names import get_common_identifier_from_array_element_name
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
@dataclass
|
|
@@ -44,6 +48,7 @@ class TableSchemas:
|
|
|
44
48
|
"array_altitude": (np.float64, u.rad),
|
|
45
49
|
"array_azimuth": (np.float64, u.rad),
|
|
46
50
|
"telescope_list": (str, None), # Store as comma-separated string
|
|
51
|
+
"telescope_list_common_id": (str, None), # Store as comma-separated string
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
file_info_schema = {
|
|
@@ -93,6 +98,7 @@ class SimtelIOEventDataWriter:
|
|
|
93
98
|
self.shower_data = []
|
|
94
99
|
self.trigger_data = []
|
|
95
100
|
self.file_info = []
|
|
101
|
+
self.telescope_id_to_name = {}
|
|
96
102
|
|
|
97
103
|
def process_files(self):
|
|
98
104
|
"""
|
|
@@ -152,6 +158,7 @@ class SimtelIOEventDataWriter:
|
|
|
152
158
|
def _process_file_info(self, file_id, file):
|
|
153
159
|
"""Process file information and append to file info list."""
|
|
154
160
|
run_info = get_corsika_run_header(file)
|
|
161
|
+
self.telescope_id_to_name = get_sim_telarray_telescope_id_to_telescope_name_mapping(file)
|
|
155
162
|
particle = PrimaryParticle(
|
|
156
163
|
particle_id_type="eventio_id", particle_id=run_info.get("primary_id", 1)
|
|
157
164
|
)
|
|
@@ -246,7 +253,12 @@ class SimtelIOEventDataWriter:
|
|
|
246
253
|
)
|
|
247
254
|
|
|
248
255
|
if len(telescopes) > 0 and tracking_positions:
|
|
249
|
-
self._fill_array_event(
|
|
256
|
+
self._fill_array_event(
|
|
257
|
+
self._map_telescope_names(telescopes),
|
|
258
|
+
tracking_positions,
|
|
259
|
+
eventio_object.event_id,
|
|
260
|
+
file_id,
|
|
261
|
+
)
|
|
250
262
|
|
|
251
263
|
def _fill_array_event(self, telescopes, tracking_positions, event_id, file_id):
|
|
252
264
|
"""Add array event triggered events with tracking positions."""
|
|
@@ -261,9 +273,33 @@ class SimtelIOEventDataWriter:
|
|
|
261
273
|
"array_altitude": float(np.mean(altitudes)),
|
|
262
274
|
"array_azimuth": float(calculate_circular_mean(azimuths)),
|
|
263
275
|
"telescope_list": ",".join(map(str, telescopes)),
|
|
276
|
+
"telescope_list_common_id": ",".join(
|
|
277
|
+
[
|
|
278
|
+
str(get_common_identifier_from_array_element_name(tel, 0))
|
|
279
|
+
for tel in telescopes
|
|
280
|
+
]
|
|
281
|
+
),
|
|
264
282
|
}
|
|
265
283
|
)
|
|
266
284
|
|
|
285
|
+
def _map_telescope_names(self, telescope_ids):
|
|
286
|
+
"""
|
|
287
|
+
Map sim_telarray telescopes IDs to CTAO array element names.
|
|
288
|
+
|
|
289
|
+
Parameters
|
|
290
|
+
----------
|
|
291
|
+
telescope_ids : list
|
|
292
|
+
List of telescope IDs.
|
|
293
|
+
|
|
294
|
+
Returns
|
|
295
|
+
-------
|
|
296
|
+
list
|
|
297
|
+
List of telescope names corresponding to the IDs.
|
|
298
|
+
"""
|
|
299
|
+
return [
|
|
300
|
+
self.telescope_id_to_name.get(tel_id, f"Unknown_{tel_id}") for tel_id in telescope_ids
|
|
301
|
+
]
|
|
302
|
+
|
|
267
303
|
def _get_preliminary_nsb_level(self, file):
|
|
268
304
|
"""
|
|
269
305
|
Return preliminary NSB level from file name.
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
"""Read metadata from sim_telarray files."""
|
|
3
3
|
|
|
4
4
|
import logging
|
|
5
|
+
import re
|
|
5
6
|
from functools import cache
|
|
6
7
|
|
|
7
8
|
from eventio import EventIOFile
|
|
9
|
+
from eventio.iact import InputCard
|
|
8
10
|
from eventio.simtel import HistoryMeta
|
|
9
11
|
|
|
12
|
+
from simtools.utils import names
|
|
13
|
+
|
|
10
14
|
_logger = logging.getLogger(__name__)
|
|
11
15
|
|
|
12
16
|
|
|
@@ -56,9 +60,12 @@ def read_sim_telarray_metadata(file, encoding="utf8"):
|
|
|
56
60
|
return {k: v.strip() if isinstance(v, str) else v for k, v in meta.items()}
|
|
57
61
|
|
|
58
62
|
# keys to lower case and strip leading '*', trailing spaces
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
try:
|
|
64
|
+
return clean_meta(global_meta), {
|
|
65
|
+
tel_id: clean_meta(meta) for tel_id, meta in telescope_meta.items()
|
|
66
|
+
}
|
|
67
|
+
except AttributeError as e:
|
|
68
|
+
raise AttributeError(f"Error reading metadata from file {file}: {e}") from e
|
|
62
69
|
|
|
63
70
|
|
|
64
71
|
def _decode_dictionary(meta, encoding="utf8"):
|
|
@@ -104,3 +111,92 @@ def get_sim_telarray_telescope_id(telescope_name, file):
|
|
|
104
111
|
telescope_name_to_sim_telarray_id[telescope_name] = tel_id
|
|
105
112
|
|
|
106
113
|
return telescope_name_to_sim_telarray_id.get(telescope_name, None)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_sim_telarray_telescope_id_to_telescope_name_mapping(file):
|
|
117
|
+
"""
|
|
118
|
+
Return a mapping of telescope IDs to telescope names from a sim_telarray file.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
file: str
|
|
123
|
+
Path to the sim_telarray file.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
dict
|
|
128
|
+
Dictionary mapping telescope IDs to telescope names.
|
|
129
|
+
"""
|
|
130
|
+
_, telescope_meta = read_sim_telarray_metadata(file)
|
|
131
|
+
telescope_map = {}
|
|
132
|
+
for i, (tel_id, meta) in enumerate(telescope_meta.items()):
|
|
133
|
+
try:
|
|
134
|
+
telescope_name = names.validate_array_element_name(
|
|
135
|
+
meta.get("optics_config_name", f"Unknown-{tel_id}")
|
|
136
|
+
)
|
|
137
|
+
except ValueError:
|
|
138
|
+
telescope_name = _guess_telescope_name_for_legacy_files(i, file)
|
|
139
|
+
if telescope_name is not None:
|
|
140
|
+
telescope_map[tel_id] = telescope_name
|
|
141
|
+
|
|
142
|
+
return telescope_map
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _guess_telescope_name_for_legacy_files(tel_counter, file):
|
|
146
|
+
"""
|
|
147
|
+
Guess telescope names for legacy prod6 sim_telarray files with incomplete metadata.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
tel_counter: int
|
|
152
|
+
Telescope counter, used to index into the telescope list.
|
|
153
|
+
file: str, Path
|
|
154
|
+
Path to the sim_telarray file.
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
str, None
|
|
159
|
+
Guessed telescope name or None if not found.
|
|
160
|
+
"""
|
|
161
|
+
telescope_list = _get_telescope_list_from_input_card(file)
|
|
162
|
+
try:
|
|
163
|
+
return names.validate_array_element_name(telescope_list[tel_counter])
|
|
164
|
+
except (IndexError, ValueError):
|
|
165
|
+
pass
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@cache
|
|
170
|
+
def _get_telescope_list_from_input_card(file):
|
|
171
|
+
r"""
|
|
172
|
+
Return telescope list from CORSIKA input card.
|
|
173
|
+
|
|
174
|
+
Note hardwired regex pattern with telescope naming convention.
|
|
175
|
+
This function is intended for legacy files generated for prod6,
|
|
176
|
+
where metadata is incomplete.
|
|
177
|
+
|
|
178
|
+
Expected format in input card:
|
|
179
|
+
|
|
180
|
+
.. code-block:: console
|
|
181
|
+
TELESCOPE -70.91E2 -52.35E2 45.00E2 12.50E2 # (ID=1) LSTN 01 2B5\n
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
file: str, Path
|
|
186
|
+
Path to the sim_telarray file.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
list
|
|
191
|
+
List of telescope names as found in CORSIKA input card.
|
|
192
|
+
"""
|
|
193
|
+
with EventIOFile(file) as f:
|
|
194
|
+
for o in f:
|
|
195
|
+
if isinstance(o, InputCard):
|
|
196
|
+
input_card = o.parse().decode("utf-8")
|
|
197
|
+
regex = (
|
|
198
|
+
r"TELESCOPE\s+[-\d.E]+\s+[-\d.E]+\s+[-\d.E]+\s+[-\d.E]+\s+"
|
|
199
|
+
r"# \(ID=\d+\)\s+(LST[N|S]|MST[N|S]|S[S|C]TS)\s+([^\s]+)"
|
|
200
|
+
)
|
|
201
|
+
return [f"{m[0]}-{m[1]}" for m in re.findall(regex, input_card)]
|
|
202
|
+
return []
|
simtools/utils/general.py
CHANGED
|
@@ -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
|
):
|