gammasimtools 0.16.0__py3-none-any.whl → 0.17.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.17.0.dist-info}/METADATA +4 -2
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.17.0.dist-info}/RECORD +60 -54
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.17.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.17.0.dist-info}/entry_points.txt +3 -1
- simtools/_version.py +2 -2
- simtools/applications/derive_ctao_array_layouts.py +5 -5
- simtools/applications/generate_simtel_event_data.py +36 -46
- simtools/applications/merge_tables.py +104 -0
- simtools/applications/plot_array_layout.py +145 -258
- simtools/applications/production_derive_corsika_limits.py +35 -220
- 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 +28 -34
- simtools/configuration/configurator.py +0 -4
- simtools/corsika/corsika_config.py +17 -12
- simtools/corsika/primary_particle.py +46 -13
- simtools/data_model/metadata_collector.py +7 -3
- simtools/db/db_handler.py +11 -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 +385 -0
- simtools/model/array_model.py +5 -0
- 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 +189 -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/runners/corsika_simtel_runner.py +4 -1
- simtools/runners/runner_services.py +5 -4
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +41 -0
- 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 +207 -227
- simtools/simtel/simtel_io_file_info.py +9 -4
- simtools/simtel/simtel_io_metadata.py +20 -5
- 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 -1
- simtools/utils/names.py +5 -5
- simtools/visualization/plot_array_layout.py +242 -0
- simtools/visualization/plot_pixels.py +681 -0
- 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.17.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.17.0.dist-info}/top_level.txt +0 -0
|
@@ -12,11 +12,13 @@ from pathlib import Path
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
|
|
14
14
|
from simtools.db import db_handler
|
|
15
|
+
from simtools.io_operations import io_handler
|
|
15
16
|
from simtools.model.telescope_model import TelescopeModel
|
|
17
|
+
from simtools.utils import general as gen
|
|
16
18
|
from simtools.utils import names
|
|
19
|
+
from simtools.visualization import plot_pixels
|
|
17
20
|
|
|
18
21
|
logger = logging.getLogger()
|
|
19
|
-
IMAGE_PATH = "../../_images"
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class ReadParameters:
|
|
@@ -62,41 +64,61 @@ class ReadParameters:
|
|
|
62
64
|
)
|
|
63
65
|
self._model_version = model_version
|
|
64
66
|
|
|
65
|
-
def _convert_to_md(self, parameter, input_file):
|
|
67
|
+
def _convert_to_md(self, parameter, parameter_version, input_file):
|
|
66
68
|
"""Convert a file to a Markdown file, preserving formatting."""
|
|
67
69
|
input_file = Path(input_file)
|
|
70
|
+
|
|
68
71
|
output_data_path = Path(self.output_path / "_data_files")
|
|
69
72
|
output_data_path.mkdir(parents=True, exist_ok=True)
|
|
70
73
|
output_file_name = Path(input_file.stem + ".md")
|
|
71
74
|
output_file = output_data_path / output_file_name
|
|
75
|
+
image_name = f"{self.array_element}_{parameter}_{self.model_version.replace('.', '-')}"
|
|
76
|
+
outpath = Path(io_handler.IOHandler().get_output_directory().parent / "_images")
|
|
77
|
+
outpath.mkdir(parents=True, exist_ok=True)
|
|
78
|
+
image_path = Path(f"{outpath}/{image_name}")
|
|
79
|
+
|
|
80
|
+
if parameter == "camera_config_file" and parameter_version:
|
|
81
|
+
image_path = Path(f"{outpath}/{input_file.stem.replace('.', '-')}")
|
|
82
|
+
if not (image_path.with_suffix(".png")).exists():
|
|
83
|
+
logger.info("Plotting camera configuration file: %s", input_file.name)
|
|
84
|
+
plot_config = {
|
|
85
|
+
"file_name": input_file.name,
|
|
86
|
+
"telescope": self.array_element,
|
|
87
|
+
"parameter_version": parameter_version,
|
|
88
|
+
"site": self.site,
|
|
89
|
+
"model_version": self.model_version,
|
|
90
|
+
"parameter": parameter,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
plot_pixels.plot(
|
|
94
|
+
config=plot_config,
|
|
95
|
+
output_file=image_path,
|
|
96
|
+
db_config=self.db_config,
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
logger.info(
|
|
100
|
+
"Camera configuration file plot already exists: %s",
|
|
101
|
+
image_path.with_suffix(".png"),
|
|
102
|
+
)
|
|
72
103
|
|
|
73
104
|
try:
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
with input_file.open("r", encoding="utf-8") as infile:
|
|
77
|
-
file_contents = infile.read()
|
|
78
|
-
except UnicodeDecodeError:
|
|
79
|
-
# If utf-8 fails, try with latin-1 (which can read any byte sequence)
|
|
80
|
-
with input_file.open("r", encoding="latin-1") as infile:
|
|
81
|
-
file_contents = infile.read()
|
|
105
|
+
# with input_file.open("r", encoding="utf-8") as infile:
|
|
106
|
+
file_contents = gen.read_file_encoded_in_utf_or_latin(input_file)
|
|
82
107
|
|
|
83
108
|
if self.model_version is not None:
|
|
84
109
|
with output_file.open("w", encoding="utf-8") as outfile:
|
|
85
110
|
outfile.write(f"# {input_file.stem}\n")
|
|
111
|
+
outfile.write(f"\n\n")
|
|
86
112
|
outfile.write(
|
|
87
|
-
"
|
|
113
|
+
"\n\nThe full file can be found in the Simulation Model repository [here]"
|
|
88
114
|
"(https://gitlab.cta-observatory.org/cta-science/simulations/"
|
|
89
115
|
"simulation-model/simulation-models/-/blob/main/simulation-models/"
|
|
90
116
|
f"model_parameters/Files/{input_file.name}).\n\n"
|
|
91
117
|
)
|
|
92
|
-
outfile.write(
|
|
93
|
-
f"}.png)\n"
|
|
95
|
-
)
|
|
96
118
|
outfile.write("\n\n")
|
|
97
119
|
outfile.write("The first 30 lines of the file are:\n")
|
|
98
120
|
outfile.write("```\n")
|
|
99
|
-
first_30_lines = "
|
|
121
|
+
first_30_lines = "".join(file_contents[:30])
|
|
100
122
|
outfile.write(first_30_lines)
|
|
101
123
|
outfile.write("\n```")
|
|
102
124
|
|
|
@@ -106,11 +128,19 @@ class ReadParameters:
|
|
|
106
128
|
|
|
107
129
|
return f"_data_files/{output_file_name}"
|
|
108
130
|
|
|
109
|
-
def _format_parameter_value(
|
|
131
|
+
def _format_parameter_value(
|
|
132
|
+
self, parameter, value_data, unit, file_flag, parameter_version=None
|
|
133
|
+
):
|
|
110
134
|
"""Format parameter value based on type."""
|
|
111
135
|
if file_flag:
|
|
112
136
|
input_file_name = f"{self.output_path}/model/{value_data}"
|
|
113
|
-
|
|
137
|
+
if parameter_version is None:
|
|
138
|
+
return (
|
|
139
|
+
f"[{Path(value_data).name}](https://gitlab.cta-observatory.org/"
|
|
140
|
+
"cta-science/simulations/simulation-model/simulation-models/-/blob/main/"
|
|
141
|
+
f"simulation-models/model_parameters/Files/{value_data})"
|
|
142
|
+
).strip()
|
|
143
|
+
output_file_name = self._convert_to_md(parameter, parameter_version, input_file_name)
|
|
114
144
|
return f"[{Path(value_data).name}]({output_file_name})".strip()
|
|
115
145
|
if isinstance(value_data, (str | int | float)):
|
|
116
146
|
return f"{value_data} {unit}".strip()
|
|
@@ -217,8 +247,10 @@ class ReadParameters:
|
|
|
217
247
|
continue
|
|
218
248
|
|
|
219
249
|
file_flag = parameter_data.get("file", False)
|
|
220
|
-
value = self._format_parameter_value(parameter_name, value_data, unit, file_flag)
|
|
221
250
|
parameter_version = parameter_data.get("parameter_version")
|
|
251
|
+
value = self._format_parameter_value(
|
|
252
|
+
parameter_name, value_data, unit, file_flag, parameter_version=None
|
|
253
|
+
)
|
|
222
254
|
model_version = version
|
|
223
255
|
|
|
224
256
|
# Group the data by parameter version and store model versions as a list
|
|
@@ -234,25 +266,28 @@ class ReadParameters:
|
|
|
234
266
|
return self._group_model_versions_by_parameter_version(grouped_data)
|
|
235
267
|
|
|
236
268
|
def get_all_parameter_descriptions(self, collection="telescopes"):
|
|
237
|
-
"""
|
|
238
|
-
Get descriptions for all model parameters.
|
|
269
|
+
"""Get descriptions for all model parameters.
|
|
239
270
|
|
|
240
271
|
Returns
|
|
241
272
|
-------
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
273
|
+
dict
|
|
274
|
+
Nested dictionaries with first key as the parameter name and
|
|
275
|
+
the following dictionary as the value:
|
|
276
|
+
- key: description, value: description of the parameter.
|
|
277
|
+
- key: short_description, value: short description of the parameter.
|
|
278
|
+
- key: inst_class, value: class, for eg. Structure, Camera, etc.
|
|
246
279
|
"""
|
|
247
|
-
|
|
280
|
+
parameter_dict = {}
|
|
248
281
|
|
|
249
282
|
for instrument_class in names.db_collection_to_instrument_class_key(collection):
|
|
250
283
|
for parameter, details in names.model_parameters(instrument_class).items():
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
284
|
+
parameter_dict[parameter] = {
|
|
285
|
+
"description": details.get("description"),
|
|
286
|
+
"short_description": details.get("short_description"),
|
|
287
|
+
"inst_class": instrument_class,
|
|
288
|
+
}
|
|
254
289
|
|
|
255
|
-
return
|
|
290
|
+
return parameter_dict
|
|
256
291
|
|
|
257
292
|
def get_array_element_parameter_data(self, telescope_model, collection="telescopes"):
|
|
258
293
|
"""
|
|
@@ -292,13 +327,15 @@ class ReadParameters:
|
|
|
292
327
|
continue
|
|
293
328
|
|
|
294
329
|
file_flag = parameter_data.get("file", False)
|
|
295
|
-
value = self._format_parameter_value(
|
|
330
|
+
value = self._format_parameter_value(
|
|
331
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
332
|
+
)
|
|
296
333
|
|
|
297
|
-
description = parameter_descriptions
|
|
298
|
-
short_description =
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
inst_class = parameter_descriptions
|
|
334
|
+
description = parameter_descriptions.get(parameter).get("description")
|
|
335
|
+
short_description = (
|
|
336
|
+
parameter_descriptions.get(parameter).get("short_description") or description
|
|
337
|
+
)
|
|
338
|
+
inst_class = parameter_descriptions.get(parameter).get("inst_class")
|
|
302
339
|
|
|
303
340
|
matching_instrument = parameter_data["instrument"] == telescope_model.name
|
|
304
341
|
if not names.is_design_type(telescope_model.name) and matching_instrument:
|
|
@@ -376,8 +413,10 @@ class ReadParameters:
|
|
|
376
413
|
|
|
377
414
|
data = []
|
|
378
415
|
for parameter, parameter_data in param_dict.items():
|
|
379
|
-
description = parameter_descriptions
|
|
380
|
-
short_description = parameter_descriptions
|
|
416
|
+
description = parameter_descriptions.get(parameter).get("description")
|
|
417
|
+
short_description = parameter_descriptions.get(parameter).get(
|
|
418
|
+
"short_description", description
|
|
419
|
+
)
|
|
381
420
|
value_data = parameter_data.get("value")
|
|
382
421
|
|
|
383
422
|
if value_data is None:
|
|
@@ -386,7 +425,9 @@ class ReadParameters:
|
|
|
386
425
|
unit = parameter_data.get("unit") or " "
|
|
387
426
|
file_flag = parameter_data.get("file", False)
|
|
388
427
|
parameter_version = parameter_data.get("parameter_version")
|
|
389
|
-
value = self._format_parameter_value(
|
|
428
|
+
value = self._format_parameter_value(
|
|
429
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
430
|
+
)
|
|
390
431
|
|
|
391
432
|
data.append(
|
|
392
433
|
[
|
|
@@ -508,10 +549,12 @@ class ReadParameters:
|
|
|
508
549
|
continue
|
|
509
550
|
|
|
510
551
|
output_filename = output_path / f"{parameter}.md"
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
)
|
|
552
|
+
|
|
553
|
+
parameter_descriptions = self.get_all_parameter_descriptions(collection=collection).get(
|
|
554
|
+
parameter
|
|
555
|
+
) or self.get_all_parameter_descriptions(collection="telescopes").get(parameter)
|
|
556
|
+
|
|
557
|
+
description = parameter_descriptions.get("description")
|
|
515
558
|
with output_filename.open("w", encoding="utf-8") as file:
|
|
516
559
|
# Write header
|
|
517
560
|
file.write(
|
|
@@ -534,14 +577,12 @@ class ReadParameters:
|
|
|
534
577
|
file.write(
|
|
535
578
|
f"| {item['parameter_version']} |"
|
|
536
579
|
f" {item['model_version']} |"
|
|
537
|
-
f"{item['value']
|
|
580
|
+
f"{item['value']} |\n"
|
|
538
581
|
)
|
|
539
582
|
|
|
540
583
|
file.write("\n")
|
|
541
584
|
if comparison_data.get(parameter)[0]["file_flag"]:
|
|
542
|
-
file.write(
|
|
543
|
-
f""
|
|
544
|
-
)
|
|
585
|
+
file.write(f"")
|
|
545
586
|
|
|
546
587
|
def _write_array_layouts_section(self, file, layouts):
|
|
547
588
|
"""Write the array layouts section of the report."""
|
|
@@ -556,7 +597,7 @@ class ReadParameters:
|
|
|
556
597
|
file.write("\n")
|
|
557
598
|
version = self.model_version.replace(".", "-")
|
|
558
599
|
filename = f"OBS-{self.site}_{layout_name}_{version}.png"
|
|
559
|
-
image_path = f"
|
|
600
|
+
image_path = f"/_images/{filename}"
|
|
560
601
|
file.write(f"\n\n")
|
|
561
602
|
file.write("\n")
|
|
562
603
|
|
|
@@ -606,7 +647,9 @@ class ReadParameters:
|
|
|
606
647
|
f"(#array-trigger-configurations) | {parameter_version} |\n"
|
|
607
648
|
)
|
|
608
649
|
else:
|
|
609
|
-
formatted_value = self._format_parameter_value(
|
|
650
|
+
formatted_value = self._format_parameter_value(
|
|
651
|
+
param_name, value, unit, file_flag, parameter_version
|
|
652
|
+
)
|
|
610
653
|
file.write(f"| {param_name} | {formatted_value} | {parameter_version} |\n")
|
|
611
654
|
file.write("\n")
|
|
612
655
|
|
|
@@ -645,7 +688,7 @@ class ReadParameters:
|
|
|
645
688
|
|
|
646
689
|
def get_calibration_data(self, all_parameter_data, array_element):
|
|
647
690
|
"""Get calibration data and descriptions for a given array element."""
|
|
648
|
-
|
|
691
|
+
calibration_descriptions = self.get_all_parameter_descriptions(
|
|
649
692
|
collection="calibration_devices"
|
|
650
693
|
)
|
|
651
694
|
# get descriptions of array element positions from the telescope collection
|
|
@@ -654,6 +697,10 @@ class ReadParameters:
|
|
|
654
697
|
class_grouped_data = {}
|
|
655
698
|
|
|
656
699
|
for parameter in all_parameter_data.keys():
|
|
700
|
+
parameter_descriptions = calibration_descriptions.get(
|
|
701
|
+
parameter
|
|
702
|
+
) or telescope_descriptions.get(parameter)
|
|
703
|
+
|
|
657
704
|
parameter_data = all_parameter_data.get(parameter)
|
|
658
705
|
parameter_version = parameter_data.get("parameter_version")
|
|
659
706
|
unit = parameter_data.get("unit") or " "
|
|
@@ -663,19 +710,15 @@ class ReadParameters:
|
|
|
663
710
|
continue
|
|
664
711
|
|
|
665
712
|
file_flag = parameter_data.get("file", False)
|
|
666
|
-
value = self._format_parameter_value(
|
|
667
|
-
|
|
668
|
-
description = parameter_descriptions[0].get(
|
|
669
|
-
parameter, telescope_descriptions[0].get(parameter)
|
|
670
|
-
)
|
|
671
|
-
short_description = (
|
|
672
|
-
parameter_descriptions[1].get(parameter, telescope_descriptions[1].get(parameter))
|
|
673
|
-
or description
|
|
674
|
-
)
|
|
675
|
-
inst_class = parameter_descriptions[2].get(
|
|
676
|
-
parameter, telescope_descriptions[2].get(parameter)
|
|
713
|
+
value = self._format_parameter_value(
|
|
714
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
677
715
|
)
|
|
678
716
|
|
|
717
|
+
description = parameter_descriptions.get("description")
|
|
718
|
+
short_description = parameter_descriptions.get("short_description") or description
|
|
719
|
+
|
|
720
|
+
inst_class = parameter_descriptions.get("inst_class")
|
|
721
|
+
|
|
679
722
|
matching_instrument = parameter_data["instrument"] == array_element
|
|
680
723
|
if not names.is_design_type(array_element) and matching_instrument:
|
|
681
724
|
parameter = f"***{parameter}***"
|
|
@@ -764,5 +807,4 @@ class ReadParameters:
|
|
|
764
807
|
for calibration_device in array_elements:
|
|
765
808
|
self.site = names.get_site_from_array_element_name(calibration_device)
|
|
766
809
|
self.array_element = calibration_device
|
|
767
|
-
print("cal: ", calibration_device)
|
|
768
810
|
self.produce_model_parameter_reports(collection="calibration_devices")
|
|
@@ -42,6 +42,7 @@ class CorsikaSimtelRunner:
|
|
|
42
42
|
keep_seeds=False,
|
|
43
43
|
use_multipipe=False,
|
|
44
44
|
sim_telarray_seeds=None,
|
|
45
|
+
sequential=False,
|
|
45
46
|
):
|
|
46
47
|
self._logger = logging.getLogger(__name__)
|
|
47
48
|
self.corsika_config = (
|
|
@@ -53,6 +54,7 @@ class CorsikaSimtelRunner:
|
|
|
53
54
|
self._simtel_path = simtel_path
|
|
54
55
|
self.sim_telarray_seeds = sim_telarray_seeds
|
|
55
56
|
self.label = label
|
|
57
|
+
self.sequential = "--sequential" if sequential else ""
|
|
56
58
|
|
|
57
59
|
self.base_corsika_config.set_output_file_and_directory(use_multipipe)
|
|
58
60
|
self.corsika_runner = CorsikaRunner(
|
|
@@ -167,7 +169,8 @@ class CorsikaSimtelRunner:
|
|
|
167
169
|
)
|
|
168
170
|
with open(multipipe_script, "w", encoding="utf-8") as file:
|
|
169
171
|
multipipe_command = Path(self._simtel_path).joinpath(
|
|
170
|
-
f"sim_telarray/bin/multipipe_corsika -c {multipipe_file}
|
|
172
|
+
f"sim_telarray/bin/multipipe_corsika -c {multipipe_file} {self.sequential} "
|
|
173
|
+
"|| echo 'Fan-out failed'"
|
|
171
174
|
)
|
|
172
175
|
file.write(f"{multipipe_command}")
|
|
173
176
|
|
|
@@ -138,9 +138,9 @@ class RunnerServices:
|
|
|
138
138
|
file_label = f"_{info_for_file_name['label']}" if info_for_file_name.get("label") else ""
|
|
139
139
|
zenith = self.corsika_config.get_config_parameter("THETAP")[0]
|
|
140
140
|
azimuth = self.corsika_config.azimuth_angle
|
|
141
|
-
|
|
141
|
+
run_number_string = self._get_run_number_string(info_for_file_name["run_number"])
|
|
142
142
|
return (
|
|
143
|
-
f"{
|
|
143
|
+
f"{info_for_file_name['primary']}_{run_number_string}_"
|
|
144
144
|
f"za{round(zenith):02}deg_azm{azimuth:03}deg_"
|
|
145
145
|
f"{info_for_file_name['site']}_{info_for_file_name['array_name']}_"
|
|
146
146
|
f"{info_for_file_name['model_version']}{file_label}"
|
|
@@ -189,8 +189,9 @@ class RunnerServices:
|
|
|
189
189
|
"""
|
|
190
190
|
data_suffixes = {
|
|
191
191
|
"output": ".zst",
|
|
192
|
-
"corsika_output": ".zst",
|
|
192
|
+
"corsika_output": ".corsika.zst",
|
|
193
193
|
"simtel_output": ".simtel.zst",
|
|
194
|
+
"event_data": ".reduced_event_data.hdf5",
|
|
194
195
|
}
|
|
195
196
|
run_dir = self._get_run_number_string(run_number)
|
|
196
197
|
data_run_dir = self.directory["data"].joinpath(run_dir)
|
|
@@ -261,7 +262,7 @@ class RunnerServices:
|
|
|
261
262
|
if file_type in ["log", "histogram", "corsika_log"]:
|
|
262
263
|
return self._get_log_file_path(file_type, file_name)
|
|
263
264
|
|
|
264
|
-
if file_type in ["output", "corsika_output", "simtel_output"]:
|
|
265
|
+
if file_type in ["output", "corsika_output", "simtel_output", "event_data"]:
|
|
265
266
|
return self._get_data_file_path(file_type, file_name, run_number)
|
|
266
267
|
|
|
267
268
|
if file_type in ("sub_log", "sub_script"):
|
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
%YAML 1.2
|
|
2
2
|
---
|
|
3
3
|
title: Schema for dsum_threshold model parameter
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
meta_schema: simpipe-schema
|
|
6
|
+
meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/model_parameter_and_data_schema.metaschema.yml
|
|
7
|
+
meta_schema_version: 0.1.0
|
|
8
|
+
name: dsum_threshold
|
|
9
|
+
description: |-
|
|
10
|
+
The amplitude level above pedestal sum above which a
|
|
11
|
+
digital sum leads to a telescope trigger.
|
|
12
|
+
Note that, like for discriminator/comparator and analog sum, the signal
|
|
13
|
+
must exceed (\'>\') the threshold here before we declare the telescope
|
|
14
|
+
triggered. The assigned threshold value would have to be one count lower
|
|
15
|
+
than in a camera-internal trigger implementation (like MSTx-FlashCam) where
|
|
16
|
+
reaching (\'>=\') the threshold is enough.
|
|
17
|
+
short_description: Amplitude level above which a digital sum leads to a telescope
|
|
18
|
+
trigger.
|
|
19
|
+
data:
|
|
20
|
+
- type: int64
|
|
21
|
+
unit: count
|
|
22
|
+
default: 0
|
|
23
|
+
allowed_range:
|
|
24
|
+
min: 0
|
|
25
|
+
condition: default_trigger==DigitalSum
|
|
26
|
+
instrument:
|
|
27
|
+
class: Camera
|
|
28
|
+
type:
|
|
29
|
+
- MSTx-NectarCam
|
|
30
|
+
- MSTx-FlashCam
|
|
31
|
+
activity:
|
|
32
|
+
setting:
|
|
33
|
+
- SetParameterFromExternal
|
|
34
|
+
- SetTriggerThresholdsFromRateScan
|
|
35
|
+
validation:
|
|
36
|
+
- ValidateParameterByExpert
|
|
37
|
+
- ValidateTriggerPerformance
|
|
38
|
+
source:
|
|
39
|
+
- Observation execution
|
|
40
|
+
simulation_software:
|
|
41
|
+
- name: sim_telarray
|
|
42
|
+
...
|
|
43
|
+
---
|
|
44
|
+
title: Schema for dsum_threshold model parameter
|
|
4
45
|
version: 0.1.0
|
|
5
46
|
meta_schema: simpipe-schema
|
|
6
47
|
meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/model_parameter_and_data_schema.metaschema.yml
|
|
@@ -29,12 +29,12 @@ definitions:
|
|
|
29
29
|
description:
|
|
30
30
|
type: string
|
|
31
31
|
description: Description of the error metric.
|
|
32
|
-
|
|
32
|
+
target_uncertainty:
|
|
33
33
|
$ref: '#/definitions/TargetError'
|
|
34
34
|
energy_range:
|
|
35
35
|
$ref: '#/definitions/EnergyRange'
|
|
36
36
|
required:
|
|
37
|
-
-
|
|
37
|
+
- target_uncertainty
|
|
38
38
|
- energy_range
|
|
39
39
|
|
|
40
40
|
TargetError:
|
|
@@ -54,12 +54,20 @@ class SimtelConfigWriter:
|
|
|
54
54
|
Layout name.
|
|
55
55
|
label: str
|
|
56
56
|
Instance label. Important for output file naming.
|
|
57
|
+
simtel_path: str or Path
|
|
58
|
+
Path to the sim_telarray installation directory.
|
|
57
59
|
"""
|
|
58
60
|
|
|
59
61
|
TAB = " " * 3
|
|
60
62
|
|
|
61
63
|
def __init__(
|
|
62
|
-
self,
|
|
64
|
+
self,
|
|
65
|
+
site,
|
|
66
|
+
model_version,
|
|
67
|
+
layout_name=None,
|
|
68
|
+
telescope_model_name=None,
|
|
69
|
+
label=None,
|
|
70
|
+
simtel_path=None,
|
|
63
71
|
):
|
|
64
72
|
"""Initialize SimtelConfigWriter."""
|
|
65
73
|
self._logger = logging.getLogger(__name__)
|
|
@@ -70,10 +78,9 @@ class SimtelConfigWriter:
|
|
|
70
78
|
self._label = label
|
|
71
79
|
self._layout_name = layout_name
|
|
72
80
|
self._telescope_model_name = telescope_model_name
|
|
81
|
+
self._simtel_path = simtel_path
|
|
73
82
|
|
|
74
|
-
def write_telescope_config_file(
|
|
75
|
-
self, config_file_path, parameters, telescope_name=None, write_dummy_config=False
|
|
76
|
-
):
|
|
83
|
+
def write_telescope_config_file(self, config_file_path, parameters, telescope_name=None):
|
|
77
84
|
"""
|
|
78
85
|
Write the sim_telarray config file for a single telescope.
|
|
79
86
|
|
|
@@ -85,8 +92,6 @@ class SimtelConfigWriter:
|
|
|
85
92
|
Model parameters
|
|
86
93
|
telescope_name: str
|
|
87
94
|
Name of the telescope (use self._telescope_model_name if None)
|
|
88
|
-
write_dummy_config: bool
|
|
89
|
-
Flag to write a dummy telescope configuration file.
|
|
90
95
|
"""
|
|
91
96
|
self._logger.debug(f"Writing telescope config file {config_file_path}")
|
|
92
97
|
|
|
@@ -97,8 +102,6 @@ class SimtelConfigWriter:
|
|
|
97
102
|
file.write("#ifdef TELESCOPE\n")
|
|
98
103
|
file.write(f" echo Configuration for {telescope_name} - TELESCOPE $(TELESCOPE)\n")
|
|
99
104
|
file.write("#endif\n\n")
|
|
100
|
-
if write_dummy_config:
|
|
101
|
-
file.write("#define DUMMY_CONFIG 1\n")
|
|
102
105
|
|
|
103
106
|
for par, value in parameters.items():
|
|
104
107
|
simtel_name, value = self._convert_model_parameters_to_simtel_format(
|
|
@@ -252,6 +255,8 @@ class SimtelConfigWriter:
|
|
|
252
255
|
file.write(self.TAB + f"echo ModelVersion: {self._model_version}\n")
|
|
253
256
|
file.write(self.TAB + "echo *****************************\n\n")
|
|
254
257
|
|
|
258
|
+
self._write_simtools_parameters(file)
|
|
259
|
+
|
|
255
260
|
self._write_site_parameters(
|
|
256
261
|
file,
|
|
257
262
|
site_model.parameters,
|
|
@@ -392,6 +397,23 @@ class SimtelConfigWriter:
|
|
|
392
397
|
header += f"{comment_char}\n"
|
|
393
398
|
file.write(header)
|
|
394
399
|
|
|
400
|
+
def _write_simtools_parameters(self, file):
|
|
401
|
+
"""Write simtools-specific parameters."""
|
|
402
|
+
meta_items = {
|
|
403
|
+
"simtools_version": simtools.version.__version__,
|
|
404
|
+
"simtools_model_production_version": self._model_version,
|
|
405
|
+
}
|
|
406
|
+
try:
|
|
407
|
+
build_opts = gen.collect_data_from_file(Path(self._simtel_path) / "build_opts.yml")
|
|
408
|
+
for key, value in build_opts.items():
|
|
409
|
+
meta_items[f"simtools_{key}"] = value
|
|
410
|
+
except (FileNotFoundError, TypeError):
|
|
411
|
+
pass # don't expect build_opts.yml to be present on all systems
|
|
412
|
+
|
|
413
|
+
file.write(f"{self.TAB}% Simtools parameters\n")
|
|
414
|
+
for key, value in meta_items.items():
|
|
415
|
+
file.write(f"{self.TAB}metaparam global set {key} = {value}\n")
|
|
416
|
+
|
|
395
417
|
def _write_site_parameters(
|
|
396
418
|
self, file, site_parameters, model_path, telescope_model, sim_telarray_seeds=None
|
|
397
419
|
):
|
|
@@ -556,9 +578,9 @@ class SimtelConfigWriter:
|
|
|
556
578
|
"disc_bins": 10,
|
|
557
579
|
"fadc_sum_bins": 10,
|
|
558
580
|
"fadc_sum_offset": 0,
|
|
559
|
-
"asum_threshold":
|
|
560
|
-
"dsum_threshold":
|
|
561
|
-
"discriminator_threshold":
|
|
581
|
+
"asum_threshold": 9999,
|
|
582
|
+
"dsum_threshold": 9999,
|
|
583
|
+
"discriminator_threshold": 9999,
|
|
562
584
|
"fadc_amplitude": 1.0,
|
|
563
585
|
"discriminator_amplitude": 1.0,
|
|
564
586
|
}
|
|
@@ -567,9 +589,7 @@ class SimtelConfigWriter:
|
|
|
567
589
|
if key in parameters:
|
|
568
590
|
parameters[key]["value"] = val
|
|
569
591
|
|
|
570
|
-
self.write_telescope_config_file(
|
|
571
|
-
config_file_path, parameters, telescope_name, write_dummy_config=True
|
|
572
|
-
)
|
|
592
|
+
self.write_telescope_config_file(config_file_path, parameters, telescope_name)
|
|
573
593
|
|
|
574
594
|
config_file_directory = Path(config_file_path).parent
|
|
575
595
|
self._write_dummy_mirror_list_files(config_file_directory, telescope_name)
|