gammasimtools 0.5.1__py3-none-any.whl → 0.6.1__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.5.1.dist-info → gammasimtools-0.6.1.dist-info}/METADATA +80 -28
- gammasimtools-0.6.1.dist-info/RECORD +91 -0
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/WHEEL +1 -1
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/entry_points.txt +4 -2
- simtools/_version.py +14 -2
- simtools/applications/add_file_to_db.py +2 -1
- simtools/applications/compare_cumulative_psf.py +10 -15
- simtools/applications/db_development_tools/add_new_parameter_to_db.py +12 -6
- simtools/applications/derive_mirror_rnda.py +95 -71
- simtools/applications/generate_corsika_histograms.py +216 -131
- simtools/applications/generate_default_metadata.py +110 -0
- simtools/applications/generate_simtel_array_histograms.py +192 -0
- simtools/applications/get_file_from_db.py +1 -1
- simtools/applications/get_parameter.py +3 -3
- simtools/applications/make_regular_arrays.py +89 -93
- simtools/applications/{plot_layout_array.py → plot_array_layout.py} +15 -14
- simtools/applications/print_array_elements.py +81 -34
- simtools/applications/produce_array_config.py +2 -2
- simtools/applications/production.py +39 -5
- simtools/applications/sim_showers_for_trigger_rates.py +26 -30
- simtools/applications/simulate_prod.py +49 -107
- simtools/applications/submit_data_from_external.py +8 -10
- simtools/applications/tune_psf.py +16 -18
- simtools/applications/validate_camera_efficiency.py +63 -9
- simtools/applications/validate_camera_fov.py +9 -13
- simtools/applications/validate_file_using_schema.py +127 -0
- simtools/applications/validate_optics.py +13 -15
- simtools/camera_efficiency.py +73 -80
- simtools/configuration/commandline_parser.py +52 -22
- simtools/configuration/configurator.py +98 -33
- simtools/constants.py +9 -0
- simtools/corsika/corsika_config.py +28 -22
- simtools/corsika/corsika_default_config.py +282 -0
- simtools/corsika/corsika_histograms.py +328 -282
- simtools/corsika/corsika_histograms_visualize.py +162 -163
- simtools/corsika/corsika_runner.py +8 -4
- simtools/corsika_simtel/corsika_simtel_runner.py +18 -23
- simtools/data_model/data_reader.py +129 -0
- simtools/data_model/metadata_collector.py +346 -118
- simtools/data_model/metadata_model.py +123 -218
- simtools/data_model/model_data_writer.py +79 -22
- simtools/data_model/validate_data.py +96 -46
- simtools/db_handler.py +67 -42
- simtools/io_operations/__init__.py +0 -0
- simtools/io_operations/hdf5_handler.py +112 -0
- simtools/{io_handler.py → io_operations/io_handler.py} +51 -22
- simtools/job_execution/job_manager.py +1 -1
- simtools/layout/{layout_array.py → array_layout.py} +168 -199
- simtools/layout/geo_coordinates.py +196 -0
- simtools/layout/telescope_position.py +12 -12
- simtools/model/array_model.py +16 -14
- simtools/model/camera.py +5 -8
- simtools/model/mirrors.py +136 -73
- simtools/model/model_utils.py +1 -69
- simtools/model/telescope_model.py +32 -25
- simtools/psf_analysis.py +26 -19
- simtools/ray_tracing.py +54 -26
- simtools/schemas/data.metaschema.yml +400 -0
- simtools/schemas/metadata.metaschema.yml +566 -0
- simtools/simtel/simtel_config_writer.py +14 -5
- simtools/simtel/simtel_histograms.py +266 -83
- simtools/simtel/simtel_runner.py +8 -7
- simtools/simtel/simtel_runner_array.py +7 -8
- simtools/simtel/simtel_runner_camera_efficiency.py +48 -2
- simtools/simtel/simtel_runner_ray_tracing.py +61 -25
- simtools/simulator.py +43 -50
- simtools/utils/general.py +232 -286
- simtools/utils/geometry.py +163 -0
- simtools/utils/names.py +294 -142
- simtools/visualization/legend_handlers.py +115 -9
- simtools/visualization/visualize.py +13 -13
- gammasimtools-0.5.1.dist-info/RECORD +0 -83
- simtools/applications/plot_simtel_histograms.py +0 -120
- simtools/applications/validate_schema_files.py +0 -135
- simtools/corsika/corsika_output_visualize.py +0 -345
- simtools/data_model/validate_schema.py +0 -285
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/LICENSE +0 -0
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/top_level.txt +0 -0
simtools/utils/names.py
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import re
|
|
2
3
|
|
|
3
4
|
_logger = logging.getLogger(__name__)
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
7
|
+
"array_element_id_from_telescope_model_name",
|
|
6
8
|
"camera_efficiency_log_file_name",
|
|
7
9
|
"camera_efficiency_results_file_name",
|
|
8
10
|
"camera_efficiency_simtel_file_name",
|
|
9
|
-
"
|
|
11
|
+
"convert_telescope_model_name_to_yaml_name",
|
|
10
12
|
"get_site_from_telescope_name",
|
|
11
|
-
"
|
|
12
|
-
"is_valid_name",
|
|
13
|
+
"get_telescope_class",
|
|
13
14
|
"layout_telescope_list_file_name",
|
|
14
15
|
"ray_tracing_file_name",
|
|
15
16
|
"ray_tracing_plot_file_name",
|
|
16
17
|
"ray_tracing_results_file_name",
|
|
18
|
+
"sanitize_name",
|
|
17
19
|
"simtel_array_config_file_name",
|
|
20
|
+
"simtel_single_mirror_list_file_name",
|
|
18
21
|
"simtel_telescope_config_file_name",
|
|
19
|
-
"
|
|
22
|
+
"get_telescope_name_db",
|
|
20
23
|
"split_telescope_model_name",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
24
|
+
"telescope_model_name_from_array_element_id",
|
|
25
|
+
"translate_simtools_to_corsika",
|
|
26
|
+
"validate_array_layout_name",
|
|
23
27
|
"validate_model_version_name",
|
|
24
|
-
"validate_name",
|
|
25
|
-
"validate_simtel_mode_name",
|
|
26
28
|
"validate_site_name",
|
|
27
29
|
"validate_sub_system_name",
|
|
28
30
|
"validate_telescope_id_name",
|
|
@@ -34,28 +36,40 @@ lst = "LST"
|
|
|
34
36
|
mst = "MST"
|
|
35
37
|
sct = "SCT"
|
|
36
38
|
sst = "SST"
|
|
39
|
+
hess = "HESS"
|
|
40
|
+
magic = "MAGIC"
|
|
41
|
+
veritas = "VERITAS"
|
|
37
42
|
|
|
38
43
|
all_telescope_class_names = {
|
|
39
44
|
lst: ["lst"],
|
|
40
45
|
mst: ["mst"],
|
|
41
46
|
sct: ["sct"],
|
|
42
47
|
sst: ["sst"],
|
|
48
|
+
hess: ["hess"],
|
|
49
|
+
magic: ["magic"],
|
|
50
|
+
veritas: ["veritas"],
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
"SST": ["sst"],
|
|
53
|
+
all_subsystem_names = {
|
|
54
|
+
"SST": ["sst", "ssts", "SSTS"],
|
|
47
55
|
"ASTRI": ["astri"],
|
|
48
56
|
"GCT": ["gct", "gct-s"],
|
|
49
57
|
"1M": ["1m"],
|
|
50
|
-
"FlashCam": ["flashcam", "flash-cam"],
|
|
51
|
-
"NectarCam": ["nectarcam", "nectar-cam"],
|
|
52
|
-
"SCT": ["sct"],
|
|
53
|
-
"LST": ["lst"],
|
|
58
|
+
"FlashCam": ["flashcam", "flash-cam", "msts", "MSTS"],
|
|
59
|
+
"NectarCam": ["nectarcam", "nectar-cam", "mstn", "MSTN"],
|
|
60
|
+
"SCT": ["sct", "scts", "SCTS"],
|
|
61
|
+
"LST": ["lst", "lsts", "LSTS", "lstn", "LSTN"],
|
|
62
|
+
"Camera": ["Camera", "camera"],
|
|
63
|
+
"Structure": ["Structure", "structure"],
|
|
64
|
+
"MAGIC": ["magic", "MAGIC"],
|
|
65
|
+
"VERITAS": ["veritas", "VERITAS"],
|
|
66
|
+
"HESS": ["hess", "HESS"],
|
|
54
67
|
}
|
|
55
68
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
all_site_names = {
|
|
70
|
+
"South": ["paranal", "south", "cta-south", "ctao-south", "s"],
|
|
71
|
+
"North": ["lapalma", "north", "cta-north", "ctao-north", "n"],
|
|
72
|
+
}
|
|
59
73
|
|
|
60
74
|
all_model_version_names = {
|
|
61
75
|
"2015-07-21": [""],
|
|
@@ -76,21 +90,11 @@ all_model_version_names = {
|
|
|
76
90
|
"2020-06-28": ["prod5"],
|
|
77
91
|
"prod4-prototype": [""],
|
|
78
92
|
"default": [],
|
|
79
|
-
"
|
|
93
|
+
"Released": [],
|
|
80
94
|
"Latest": [],
|
|
81
95
|
}
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
"RayTracing": ["raytracing", "ray-tracing"],
|
|
85
|
-
"RayTracingSingleMirror": [
|
|
86
|
-
"raytracing-singlemirror",
|
|
87
|
-
"ray-tracing-singlemirror",
|
|
88
|
-
"ray-tracing-single-mirror",
|
|
89
|
-
],
|
|
90
|
-
"Trigger": ["trigger"],
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
all_layout_array_names = {
|
|
97
|
+
all_array_layout_names = {
|
|
94
98
|
"4LST": ["4-lst", "4lst"],
|
|
95
99
|
"1LST": ["1-lst", "1lst"],
|
|
96
100
|
"4MST": ["4-mst", "4mst"],
|
|
@@ -101,8 +105,16 @@ all_layout_array_names = {
|
|
|
101
105
|
"TestLayout": ["test-layout"],
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
# array elements as defined by CTAO
|
|
109
|
+
# (includes for now only telescopes;
|
|
110
|
+
# can be extended to other elements)
|
|
111
|
+
all_array_element_id_names = {
|
|
112
|
+
"lstn": ["LSTN", "lstn"],
|
|
113
|
+
"mstn": ["MSTN", "mstn"],
|
|
114
|
+
"lsts": ["LSTS", "lsts"],
|
|
115
|
+
"msts": ["MSTS", "msts"],
|
|
116
|
+
"ssts": ["SSTS", "ssts"],
|
|
117
|
+
"scts": ["SCTS", "scts"],
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
|
|
@@ -120,24 +132,24 @@ def validate_sub_system_name(name):
|
|
|
120
132
|
str
|
|
121
133
|
Validated name.
|
|
122
134
|
"""
|
|
123
|
-
return
|
|
135
|
+
return _validate_name(name, all_subsystem_names)
|
|
124
136
|
|
|
125
137
|
|
|
126
|
-
def
|
|
138
|
+
def validate_telescope_class_name(name):
|
|
127
139
|
"""
|
|
128
|
-
Validate a
|
|
140
|
+
Validate a telescope class name (LST, MST, SST, ...).
|
|
129
141
|
|
|
130
142
|
Parameters
|
|
131
143
|
----------
|
|
132
144
|
name: str
|
|
133
|
-
|
|
145
|
+
Telescope class name.
|
|
134
146
|
|
|
135
147
|
Returns
|
|
136
148
|
-------
|
|
137
149
|
str
|
|
138
150
|
Validated name.
|
|
139
151
|
"""
|
|
140
|
-
return
|
|
152
|
+
return _validate_name(name, all_telescope_class_names)
|
|
141
153
|
|
|
142
154
|
|
|
143
155
|
def validate_telescope_id_name(name):
|
|
@@ -146,11 +158,11 @@ def validate_telescope_id_name(name):
|
|
|
146
158
|
|
|
147
159
|
Valid names e.g.,
|
|
148
160
|
- D
|
|
149
|
-
- telescope ID
|
|
161
|
+
- telescope ID (e.g., 1, 5, 15)
|
|
150
162
|
|
|
151
163
|
Parameters
|
|
152
164
|
----------
|
|
153
|
-
name: str
|
|
165
|
+
name: str or int
|
|
154
166
|
Telescope ID name.
|
|
155
167
|
|
|
156
168
|
Returns
|
|
@@ -164,8 +176,8 @@ def validate_telescope_id_name(name):
|
|
|
164
176
|
If name is not valid.
|
|
165
177
|
"""
|
|
166
178
|
|
|
167
|
-
if name
|
|
168
|
-
return name
|
|
179
|
+
if isinstance(name, int) or name.upper() in ("D", "D234", "TEST") or name.isdigit():
|
|
180
|
+
return str(name).upper()
|
|
169
181
|
|
|
170
182
|
msg = f"Invalid telescope ID name {name}"
|
|
171
183
|
_logger.error(msg)
|
|
@@ -186,24 +198,7 @@ def validate_model_version_name(name):
|
|
|
186
198
|
str
|
|
187
199
|
Validated name.
|
|
188
200
|
"""
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def validate_simtel_mode_name(name):
|
|
193
|
-
"""
|
|
194
|
-
Validate a sim_telarray mode name.
|
|
195
|
-
|
|
196
|
-
Parameters
|
|
197
|
-
----------
|
|
198
|
-
name: str
|
|
199
|
-
sim_telarray mode name.
|
|
200
|
-
|
|
201
|
-
Returns
|
|
202
|
-
-------
|
|
203
|
-
str
|
|
204
|
-
Validated name.
|
|
205
|
-
"""
|
|
206
|
-
return validate_name(name, all_simtel_mode_names)
|
|
201
|
+
return _validate_name(name, all_model_version_names)
|
|
207
202
|
|
|
208
203
|
|
|
209
204
|
def validate_site_name(name):
|
|
@@ -220,12 +215,12 @@ def validate_site_name(name):
|
|
|
220
215
|
str
|
|
221
216
|
Validated name.
|
|
222
217
|
"""
|
|
223
|
-
return
|
|
218
|
+
return _validate_name(name, all_site_names)
|
|
224
219
|
|
|
225
220
|
|
|
226
|
-
def
|
|
221
|
+
def validate_array_layout_name(name):
|
|
227
222
|
"""
|
|
228
|
-
Validate a layout
|
|
223
|
+
Validate a array layout name.
|
|
229
224
|
|
|
230
225
|
Parameters
|
|
231
226
|
----------
|
|
@@ -237,10 +232,10 @@ def validate_layout_array_name(name):
|
|
|
237
232
|
str
|
|
238
233
|
Validated name.
|
|
239
234
|
"""
|
|
240
|
-
return
|
|
235
|
+
return _validate_name(name, all_array_layout_names)
|
|
241
236
|
|
|
242
237
|
|
|
243
|
-
def
|
|
238
|
+
def _validate_name(name, all_names):
|
|
244
239
|
"""
|
|
245
240
|
Validate a name given the all_names options. For each key in all_names, a list of options is \
|
|
246
241
|
given. If name is in this list, the key name is returned.
|
|
@@ -262,7 +257,7 @@ def validate_name(name, all_names):
|
|
|
262
257
|
If name is not valid.
|
|
263
258
|
"""
|
|
264
259
|
|
|
265
|
-
if not
|
|
260
|
+
if not _is_valid_name(name, all_names):
|
|
266
261
|
msg = f"Invalid name {name}"
|
|
267
262
|
raise ValueError(msg)
|
|
268
263
|
for main_name, list_of_names in all_names.items():
|
|
@@ -273,7 +268,7 @@ def validate_name(name, all_names):
|
|
|
273
268
|
return None
|
|
274
269
|
|
|
275
270
|
|
|
276
|
-
def
|
|
271
|
+
def _is_valid_name(name, all_names):
|
|
277
272
|
"""
|
|
278
273
|
Check if name is valid.
|
|
279
274
|
|
|
@@ -313,27 +308,27 @@ def validate_telescope_model_name(name):
|
|
|
313
308
|
Validated name.
|
|
314
309
|
"""
|
|
315
310
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
tel_type = tel_type.replace("nectarcam", "NectarCam")
|
|
322
|
-
if "1m" in tel_type:
|
|
323
|
-
tel_type = tel_type.replace("1m", "1M")
|
|
324
|
-
if "gct" in tel_type:
|
|
325
|
-
tel_type = tel_type.replace("gct", "GCT")
|
|
326
|
-
if "astri" in tel_type:
|
|
327
|
-
tel_type = tel_type.replace("astri", "ASTRI")
|
|
328
|
-
if "-d" in "-" + tel_type:
|
|
329
|
-
tel_type = tel_type.replace("d", "D")
|
|
311
|
+
# e.g, MSTN or MSTN-01
|
|
312
|
+
try:
|
|
313
|
+
return _validate_name(name, all_array_element_id_names)
|
|
314
|
+
except ValueError:
|
|
315
|
+
pass
|
|
330
316
|
|
|
331
|
-
|
|
317
|
+
# e.g., MST-FlashCam or MST-FlashCam-01
|
|
318
|
+
tel_class, tel_type, tel_id = split_telescope_model_name(name)
|
|
319
|
+
_telescope_name = tel_class
|
|
320
|
+
if tel_class != tel_type and len(tel_type) > 0:
|
|
321
|
+
_telescope_name += "-" + tel_type
|
|
322
|
+
if len(tel_id) > 0:
|
|
323
|
+
_telescope_name += "-" + tel_id
|
|
324
|
+
return _telescope_name
|
|
332
325
|
|
|
333
326
|
|
|
334
327
|
def split_telescope_model_name(name):
|
|
335
328
|
"""
|
|
336
|
-
Split a telescope name into class
|
|
329
|
+
Split a telescope name into class, type, telescope id.
|
|
330
|
+
Allow various inputs, e.g., MST-FlashCam-01, MST-FlashCam,
|
|
331
|
+
MSTN-01, MSTN, MST-1
|
|
337
332
|
|
|
338
333
|
Parameters
|
|
339
334
|
----------
|
|
@@ -342,14 +337,44 @@ def split_telescope_model_name(name):
|
|
|
342
337
|
|
|
343
338
|
Returns
|
|
344
339
|
-------
|
|
345
|
-
str, str
|
|
346
|
-
class (LST, MST, SST ...)
|
|
340
|
+
str, str, str
|
|
341
|
+
class (LST, MST, SST ...), type (any complement), telescope id
|
|
347
342
|
"""
|
|
348
|
-
|
|
349
343
|
name_parts = name.split("-")
|
|
344
|
+
# e.g., MSTN or MSTN-01
|
|
345
|
+
try:
|
|
346
|
+
_is_valid_name(name_parts[0], all_array_element_id_names)
|
|
347
|
+
return (
|
|
348
|
+
validate_telescope_class_name(name_parts[0][0:3]),
|
|
349
|
+
validate_sub_system_name(name_parts[0]),
|
|
350
|
+
validate_telescope_id_name(name_parts[1]) if len(name_parts) > 1 else "",
|
|
351
|
+
)
|
|
352
|
+
except ValueError:
|
|
353
|
+
pass
|
|
354
|
+
|
|
355
|
+
# e.g., MST-FlashCam or MST-FlashCam-01, MST-1
|
|
356
|
+
# (note that this complicated, as LST-1 is a valid
|
|
357
|
+
# name without explicit subsystem given in name)
|
|
350
358
|
tel_class = name_parts[0]
|
|
351
|
-
|
|
352
|
-
|
|
359
|
+
try:
|
|
360
|
+
tel_id = validate_telescope_id_name(name_parts[-1])
|
|
361
|
+
_tmp_tel_type = name_parts[1:-1]
|
|
362
|
+
except ValueError:
|
|
363
|
+
tel_id = ""
|
|
364
|
+
_tmp_tel_type = name_parts[1:]
|
|
365
|
+
if len(_tmp_tel_type) > 0:
|
|
366
|
+
tel_type = "-".join(_tmp_tel_type)
|
|
367
|
+
else:
|
|
368
|
+
try:
|
|
369
|
+
tel_type = validate_sub_system_name(tel_class)
|
|
370
|
+
except ValueError:
|
|
371
|
+
tel_type = ""
|
|
372
|
+
|
|
373
|
+
return (
|
|
374
|
+
validate_telescope_class_name(tel_class),
|
|
375
|
+
validate_sub_system_name(tel_type) if len(tel_type) > 0 else "",
|
|
376
|
+
validate_telescope_id_name(tel_id) if len(tel_id) > 0 else "",
|
|
377
|
+
)
|
|
353
378
|
|
|
354
379
|
|
|
355
380
|
def get_site_from_telescope_name(name):
|
|
@@ -366,12 +391,20 @@ def get_site_from_telescope_name(name):
|
|
|
366
391
|
str
|
|
367
392
|
Site name (South or North).
|
|
368
393
|
"""
|
|
394
|
+
# e.g, MSTN or MSTN-01 (tested by get_telescope_class)
|
|
395
|
+
try:
|
|
396
|
+
get_telescope_class(name)
|
|
397
|
+
return validate_site_name(name[3])
|
|
398
|
+
except ValueError:
|
|
399
|
+
pass
|
|
400
|
+
# e.g., South-MST-FlashCam
|
|
369
401
|
return validate_site_name(name.split("-")[0])
|
|
370
402
|
|
|
371
403
|
|
|
372
404
|
def validate_telescope_name_db(name):
|
|
373
405
|
"""
|
|
374
406
|
Validate a telescope DB name.
|
|
407
|
+
Examples are North-LST-1, North-MST-NectarCam-D, or South-SST-Structure-D.
|
|
375
408
|
|
|
376
409
|
Parameters
|
|
377
410
|
----------
|
|
@@ -388,7 +421,7 @@ def validate_telescope_name_db(name):
|
|
|
388
421
|
return f"{validate_site_name(site)}-{validate_telescope_model_name(tel_model_name)}"
|
|
389
422
|
|
|
390
423
|
|
|
391
|
-
def
|
|
424
|
+
def convert_telescope_model_name_to_yaml_name(name):
|
|
392
425
|
"""
|
|
393
426
|
Get telescope name following the old convention (yaml files) from the current telescope name.
|
|
394
427
|
|
|
@@ -407,8 +440,9 @@ def convert_telescope_model_name_to_yaml(name):
|
|
|
407
440
|
ValueError
|
|
408
441
|
if name is not valid.
|
|
409
442
|
"""
|
|
410
|
-
tel_class, tel_type = split_telescope_model_name(name)
|
|
411
|
-
new_name = tel_class + "-" + tel_type
|
|
443
|
+
tel_class, tel_type, tel_id = split_telescope_model_name(name)
|
|
444
|
+
new_name = tel_class if tel_class == tel_type else tel_class + "-" + tel_type
|
|
445
|
+
new_name = new_name + "-" + tel_id if len(tel_id) > 0 else new_name
|
|
412
446
|
old_names = {
|
|
413
447
|
"SST-D": "SST",
|
|
414
448
|
"SST-1M": "SST-1M",
|
|
@@ -422,14 +456,97 @@ def convert_telescope_model_name_to_yaml(name):
|
|
|
422
456
|
}
|
|
423
457
|
|
|
424
458
|
if new_name not in old_names:
|
|
425
|
-
raise ValueError(f"Telescope name {name} could not be converted to yml names")
|
|
459
|
+
raise ValueError(f"Telescope name {name}/{new_name} could not be converted to yml names")
|
|
426
460
|
|
|
427
461
|
return old_names[new_name]
|
|
428
462
|
|
|
429
463
|
|
|
430
|
-
def
|
|
464
|
+
def array_element_id_from_telescope_model_name(site, telescope_model_name):
|
|
465
|
+
"""
|
|
466
|
+
Array element ID (CTAO convention) from telescope model name.
|
|
467
|
+
This returns e.g., "LSTN" for any LST telescope in the North site.
|
|
468
|
+
If a telescope number is given, it adds it as e.g., "LSTN-01".
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
site: str
|
|
473
|
+
Observatory site (e.g., South or North)
|
|
474
|
+
telescope_class_name: str
|
|
475
|
+
Name of the telescope class (e.g. LST-1, LST-D234, MST-FlashCam-D, ...)
|
|
476
|
+
|
|
477
|
+
Returns
|
|
478
|
+
-------
|
|
479
|
+
str
|
|
480
|
+
Array element ID (CTAO style).
|
|
481
|
+
|
|
482
|
+
"""
|
|
483
|
+
|
|
484
|
+
_class, _type, _tel_id = split_telescope_model_name(telescope_model_name)
|
|
485
|
+
_id = _class.upper() + site[0].upper()
|
|
486
|
+
if _tel_id.isdigit():
|
|
487
|
+
_id += f"-{int(_tel_id):02d}"
|
|
488
|
+
return _id
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def telescope_model_name_from_array_element_id(
|
|
492
|
+
array_element_id, sub_system_name="structure", available_telescopes=None
|
|
493
|
+
):
|
|
494
|
+
"""
|
|
495
|
+
Telescope model name from array element ID (CTAO convention).
|
|
496
|
+
Does not include the site in the returned name (e.g., returns
|
|
497
|
+
South-MST-FlashCam-1 for MSTS-01; this method is quite finetuned).
|
|
498
|
+
|
|
499
|
+
Parameters
|
|
500
|
+
----------
|
|
501
|
+
array_element_id: str
|
|
502
|
+
Array element ID (CTAO convention).
|
|
503
|
+
available_telescopes: list
|
|
504
|
+
List of available telescopes.
|
|
505
|
+
|
|
506
|
+
Returns
|
|
507
|
+
-------
|
|
508
|
+
str
|
|
509
|
+
Telescope model name.
|
|
510
|
+
"""
|
|
511
|
+
|
|
512
|
+
name_parts = array_element_id.split("-")
|
|
513
|
+
try:
|
|
514
|
+
_class = name_parts[0][0:3]
|
|
515
|
+
_site = validate_site_name(name_parts[0][3])
|
|
516
|
+
except IndexError as exc:
|
|
517
|
+
_logger.error("Invalid array element ID %s", array_element_id)
|
|
518
|
+
raise exc
|
|
519
|
+
try:
|
|
520
|
+
_id = int(name_parts[1])
|
|
521
|
+
except (ValueError, IndexError):
|
|
522
|
+
_id = "D"
|
|
523
|
+
|
|
524
|
+
if _class in ("LST", "SCT"):
|
|
525
|
+
sub_system_name = None
|
|
526
|
+
elif _class == "MST" and sub_system_name.lower() == "camera":
|
|
527
|
+
sub_system_name = "NectarCam" if _site == "North" else "FlashCam"
|
|
528
|
+
|
|
529
|
+
_simtools_name = get_telescope_name_db(
|
|
530
|
+
site=_site,
|
|
531
|
+
telescope_class_name=_class,
|
|
532
|
+
sub_system_name=sub_system_name,
|
|
533
|
+
telescope_id_name=_id,
|
|
534
|
+
)
|
|
535
|
+
if available_telescopes is not None and _simtools_name not in available_telescopes:
|
|
536
|
+
_logger.debug("Telescope %s not available", _simtools_name)
|
|
537
|
+
_simtools_name = get_telescope_name_db(
|
|
538
|
+
site=_site,
|
|
539
|
+
telescope_class_name=_class,
|
|
540
|
+
sub_system_name=sub_system_name,
|
|
541
|
+
telescope_id_name="D234" if _site == "North" and _class == "LST" else "D",
|
|
542
|
+
)
|
|
543
|
+
return _simtools_name.split("-", 1)[1]
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def get_telescope_name_db(site, telescope_class_name, sub_system_name, telescope_id_name):
|
|
431
547
|
"""
|
|
432
548
|
Instrument name following simtools naming convention
|
|
549
|
+
Examples are North-LST-1, North-MST-NectarCam-D, or South-SST-Structure-D.
|
|
433
550
|
|
|
434
551
|
Parameters
|
|
435
552
|
----------
|
|
@@ -437,8 +554,8 @@ def simtools_instrument_name(site, telescope_class_name, sub_system_name, telesc
|
|
|
437
554
|
South or North.
|
|
438
555
|
telescope_class_name: str
|
|
439
556
|
LST, MST, ...
|
|
440
|
-
sub_system_name: str
|
|
441
|
-
FlashCam, NectarCam
|
|
557
|
+
sub_system_name: str or None
|
|
558
|
+
FlashCam, NectarCam, Structure
|
|
442
559
|
telescope_id_name: str
|
|
443
560
|
telescope ID (e.g., D, numerical value)
|
|
444
561
|
|
|
@@ -451,9 +568,8 @@ def simtools_instrument_name(site, telescope_class_name, sub_system_name, telesc
|
|
|
451
568
|
return (
|
|
452
569
|
validate_site_name(site)
|
|
453
570
|
+ "-"
|
|
454
|
-
+
|
|
455
|
-
+ "-"
|
|
456
|
-
+ validate_sub_system_name(sub_system_name)
|
|
571
|
+
+ _validate_name(telescope_class_name, all_telescope_class_names)
|
|
572
|
+
+ ("" if sub_system_name is None else "-" + validate_sub_system_name(sub_system_name))
|
|
457
573
|
+ "-"
|
|
458
574
|
+ validate_telescope_id_name(telescope_id_name)
|
|
459
575
|
)
|
|
@@ -490,7 +606,7 @@ def simtel_telescope_config_file_name(
|
|
|
490
606
|
return name
|
|
491
607
|
|
|
492
608
|
|
|
493
|
-
def simtel_array_config_file_name(array_name, site,
|
|
609
|
+
def simtel_array_config_file_name(array_name, site, model_version, label):
|
|
494
610
|
"""
|
|
495
611
|
sim_telarray config file name for an array.
|
|
496
612
|
|
|
@@ -500,7 +616,7 @@ def simtel_array_config_file_name(array_name, site, version, label):
|
|
|
500
616
|
Prod5, ...
|
|
501
617
|
site: str
|
|
502
618
|
South or North.
|
|
503
|
-
|
|
619
|
+
model_version: str
|
|
504
620
|
Version of the model.
|
|
505
621
|
label: str
|
|
506
622
|
Instance label.
|
|
@@ -510,7 +626,7 @@ def simtel_array_config_file_name(array_name, site, version, label):
|
|
|
510
626
|
str
|
|
511
627
|
File name.
|
|
512
628
|
"""
|
|
513
|
-
name = f"CTA-{array_name}-{site}-{
|
|
629
|
+
name = f"CTA-{array_name}-{site}-{model_version}"
|
|
514
630
|
name += f"_{label}" if label is not None else ""
|
|
515
631
|
name += ".cfg"
|
|
516
632
|
return name
|
|
@@ -679,7 +795,9 @@ def ray_tracing_plot_file_name(
|
|
|
679
795
|
return name
|
|
680
796
|
|
|
681
797
|
|
|
682
|
-
def camera_efficiency_results_file_name(
|
|
798
|
+
def camera_efficiency_results_file_name(
|
|
799
|
+
site, telescope_model_name, zenith_angle, azimuth_angle, label
|
|
800
|
+
):
|
|
683
801
|
"""
|
|
684
802
|
Camera efficiency results file name.
|
|
685
803
|
|
|
@@ -691,6 +809,8 @@ def camera_efficiency_results_file_name(site, telescope_model_name, zenith_angle
|
|
|
691
809
|
LST-1, MST-FlashCam, ...
|
|
692
810
|
zenith_angle: float
|
|
693
811
|
Zenith angle (deg).
|
|
812
|
+
azimuth_angle: float
|
|
813
|
+
Azimuth angle (deg).
|
|
694
814
|
label: str
|
|
695
815
|
Instance label.
|
|
696
816
|
|
|
@@ -699,13 +819,18 @@ def camera_efficiency_results_file_name(site, telescope_model_name, zenith_angle
|
|
|
699
819
|
str
|
|
700
820
|
File name.
|
|
701
821
|
"""
|
|
702
|
-
|
|
703
|
-
name
|
|
704
|
-
|
|
822
|
+
_label = f"_{label}" if label is not None else ""
|
|
823
|
+
name = (
|
|
824
|
+
f"camera-efficiency-table-{site}-{telescope_model_name}-"
|
|
825
|
+
f"za{round(zenith_angle):03}deg_azm{round(azimuth_angle):03}deg"
|
|
826
|
+
f"{_label}.ecsv"
|
|
827
|
+
)
|
|
705
828
|
return name
|
|
706
829
|
|
|
707
830
|
|
|
708
|
-
def camera_efficiency_simtel_file_name(
|
|
831
|
+
def camera_efficiency_simtel_file_name(
|
|
832
|
+
site, telescope_model_name, zenith_angle, azimuth_angle, label
|
|
833
|
+
):
|
|
709
834
|
"""
|
|
710
835
|
Camera efficiency simtel output file name.
|
|
711
836
|
|
|
@@ -717,6 +842,8 @@ def camera_efficiency_simtel_file_name(site, telescope_model_name, zenith_angle,
|
|
|
717
842
|
LST-1, MST-FlashCam-D, ...
|
|
718
843
|
zenith_angle: float
|
|
719
844
|
Zenith angle (deg).
|
|
845
|
+
azimuth_angle: float
|
|
846
|
+
Azimuth angle (deg).
|
|
720
847
|
label: str
|
|
721
848
|
Instance label.
|
|
722
849
|
|
|
@@ -725,13 +852,16 @@ def camera_efficiency_simtel_file_name(site, telescope_model_name, zenith_angle,
|
|
|
725
852
|
str
|
|
726
853
|
File name.
|
|
727
854
|
"""
|
|
728
|
-
|
|
729
|
-
name
|
|
730
|
-
|
|
855
|
+
_label = f"_{label}" if label is not None else ""
|
|
856
|
+
name = (
|
|
857
|
+
f"camera-efficiency-{site}-{telescope_model_name}-"
|
|
858
|
+
f"za{round(zenith_angle):03}deg_azm{round(azimuth_angle):03}deg"
|
|
859
|
+
f"{_label}.dat"
|
|
860
|
+
)
|
|
731
861
|
return name
|
|
732
862
|
|
|
733
863
|
|
|
734
|
-
def camera_efficiency_log_file_name(site, telescope_model_name, zenith_angle, label):
|
|
864
|
+
def camera_efficiency_log_file_name(site, telescope_model_name, zenith_angle, azimuth_angle, label):
|
|
735
865
|
"""
|
|
736
866
|
Camera efficiency log file name.
|
|
737
867
|
|
|
@@ -743,6 +873,8 @@ def camera_efficiency_log_file_name(site, telescope_model_name, zenith_angle, la
|
|
|
743
873
|
LST-1, MST-FlashCam-D, ...
|
|
744
874
|
zenith_angle: float
|
|
745
875
|
Zenith angle (deg).
|
|
876
|
+
azimuth_angle: float
|
|
877
|
+
Azimuth angle (deg).
|
|
746
878
|
label: str
|
|
747
879
|
Instance label.
|
|
748
880
|
|
|
@@ -751,15 +883,18 @@ def camera_efficiency_log_file_name(site, telescope_model_name, zenith_angle, la
|
|
|
751
883
|
str
|
|
752
884
|
File name.
|
|
753
885
|
"""
|
|
754
|
-
|
|
755
|
-
name
|
|
756
|
-
|
|
886
|
+
_label = f"_{label}" if label is not None else ""
|
|
887
|
+
name = (
|
|
888
|
+
f"camera-efficiency-{site}-{telescope_model_name}"
|
|
889
|
+
f"-za{round(zenith_angle):03}deg_azm{round(azimuth_angle):03}deg"
|
|
890
|
+
f"{_label}.log"
|
|
891
|
+
)
|
|
757
892
|
return name
|
|
758
893
|
|
|
759
894
|
|
|
760
|
-
def
|
|
895
|
+
def get_telescope_class(telescope_name):
|
|
761
896
|
"""
|
|
762
|
-
Guess telescope
|
|
897
|
+
Guess telescope class from name, e.g. "LST", "MST", ...
|
|
763
898
|
|
|
764
899
|
Parameters
|
|
765
900
|
----------
|
|
@@ -772,47 +907,24 @@ def get_telescope_type(telescope_name):
|
|
|
772
907
|
Telescope type.
|
|
773
908
|
"""
|
|
774
909
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
if _class[0:3] in all_telescope_class_names:
|
|
778
|
-
return _class[0:3]
|
|
779
|
-
|
|
780
|
-
except IndexError:
|
|
781
|
-
pass
|
|
782
|
-
|
|
783
|
-
return ""
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
def translate_corsika_to_simtools(corsika_par):
|
|
787
|
-
"""
|
|
788
|
-
Translate the name of a CORSIKA parameter to the name used in simtools.
|
|
789
|
-
|
|
790
|
-
Parameters
|
|
791
|
-
----------
|
|
792
|
-
corsika_par: str
|
|
793
|
-
Name of the corsika parameter to be translated.
|
|
794
|
-
|
|
795
|
-
"""
|
|
796
|
-
|
|
797
|
-
try:
|
|
798
|
-
return corsika_to_simtools_names[corsika_par]
|
|
799
|
-
except KeyError:
|
|
800
|
-
msg = f"Translation not found. We will proceed with the original parameter name:\
|
|
801
|
-
{corsika_par}."
|
|
802
|
-
_logger.debug(msg)
|
|
803
|
-
return corsika_par
|
|
910
|
+
_tel_class, _, _ = split_telescope_model_name(telescope_name)
|
|
911
|
+
return _tel_class
|
|
804
912
|
|
|
805
913
|
|
|
806
914
|
def translate_simtools_to_corsika(simtools_par):
|
|
807
915
|
"""
|
|
808
916
|
Translate the name of a simtools parameter to the name used in CORSIKA.
|
|
809
917
|
|
|
918
|
+
TODO - this will go with the new simulation model
|
|
919
|
+
|
|
810
920
|
Parameters
|
|
811
921
|
----------
|
|
812
922
|
simtools_par: str
|
|
813
923
|
Name of the simtools parameter to be translated.
|
|
814
924
|
"""
|
|
815
925
|
|
|
926
|
+
corsika_to_simtools_names = {"OBSLEV": "corsika_obs_level"}
|
|
927
|
+
|
|
816
928
|
simtools_to_corsika_names = {
|
|
817
929
|
new_key: new_value for new_value, new_key in corsika_to_simtools_names.items()
|
|
818
930
|
}
|
|
@@ -823,3 +935,43 @@ def translate_simtools_to_corsika(simtools_par):
|
|
|
823
935
|
{simtools_par}."
|
|
824
936
|
_logger.debug(msg)
|
|
825
937
|
return simtools_par
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
def sanitize_name(name):
|
|
941
|
+
"""
|
|
942
|
+
Sanitize name to be a valid Python identifier.
|
|
943
|
+
|
|
944
|
+
- Replaces spaces with underscores
|
|
945
|
+
- Converts to lowercase
|
|
946
|
+
- Removes characters that are not alphanumerics or underscores
|
|
947
|
+
- If the name starts with a number, prepend an underscore
|
|
948
|
+
|
|
949
|
+
Parameters
|
|
950
|
+
----------
|
|
951
|
+
name: str
|
|
952
|
+
name to be sanitized.
|
|
953
|
+
|
|
954
|
+
Returns
|
|
955
|
+
-------
|
|
956
|
+
str:
|
|
957
|
+
Sanitized name.
|
|
958
|
+
|
|
959
|
+
Raises
|
|
960
|
+
------
|
|
961
|
+
ValueError:
|
|
962
|
+
if the string `name` can not be sanitized.
|
|
963
|
+
"""
|
|
964
|
+
|
|
965
|
+
# Convert to lowercase
|
|
966
|
+
sanitized = name.lower()
|
|
967
|
+
|
|
968
|
+
# Replace spaces with underscores
|
|
969
|
+
sanitized = sanitized.replace(" ", "_")
|
|
970
|
+
|
|
971
|
+
# Remove characters that are not alphanumerics or underscores
|
|
972
|
+
sanitized = re.sub(r"\W|^(?=\d)", "_", sanitized)
|
|
973
|
+
if not sanitized.isidentifier():
|
|
974
|
+
msg = f"The string {name} could not be sanitized."
|
|
975
|
+
_logger.error(msg)
|
|
976
|
+
raise ValueError
|
|
977
|
+
return sanitized
|