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
|
@@ -2,61 +2,80 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Summary
|
|
4
4
|
-------
|
|
5
|
-
|
|
6
|
-
systems.
|
|
5
|
+
Convert and print a list of array element positions in different coordinate \
|
|
6
|
+
systems relevant for CTAO.
|
|
7
|
+
|
|
8
|
+
Description
|
|
9
|
+
-----------
|
|
10
|
+
|
|
11
|
+
This application converts a list of array element positions in different CTAO \
|
|
12
|
+
coordinate systems.
|
|
7
13
|
|
|
8
14
|
Available coordinate systems are:
|
|
15
|
+
|
|
9
16
|
1. UTM system
|
|
10
|
-
2.
|
|
17
|
+
2. ground system (similar to sim_telarray system with x-axis pointing toward \
|
|
18
|
+
geographic north and y-axis pointing towards the west)
|
|
11
19
|
3. Mercator system
|
|
12
20
|
|
|
13
21
|
Command line arguments
|
|
14
22
|
----------------------
|
|
15
|
-
|
|
16
|
-
File name with list of array element positions
|
|
23
|
+
input (str)
|
|
24
|
+
File name with list of array element positions
|
|
17
25
|
compact (str)
|
|
18
|
-
Compact output
|
|
26
|
+
Compact output in requested coordinate system; possible are corsika,utm,mercator
|
|
19
27
|
export (str)
|
|
20
|
-
Export array element list to file
|
|
21
|
-
possible are
|
|
28
|
+
Export array element list to file in requested coordinate system; \
|
|
29
|
+
possible are ground, utm, mercator
|
|
22
30
|
use_corsika_telescope_height (bool)
|
|
23
|
-
Use CORSIKA coordinates for telescope heights (requires CORSIKA
|
|
31
|
+
Use CORSIKA coordinates for telescope heights (requires CORSIKA observation level)
|
|
32
|
+
select_assets (str)
|
|
33
|
+
Select a subset of array elements / telescopes (e.g., MSTN, LSTN)
|
|
24
34
|
|
|
25
35
|
|
|
26
36
|
Example
|
|
27
37
|
-------
|
|
28
38
|
Print a list of array elements using a list of telescope positions in UTM coordinates.
|
|
29
39
|
|
|
30
|
-
Example:
|
|
31
|
-
|
|
32
|
-
Run the application:
|
|
33
|
-
|
|
34
40
|
.. code-block:: console
|
|
35
41
|
|
|
36
|
-
simtools-print-array-elements
|
|
37
|
-
--
|
|
38
|
-
--compact
|
|
42
|
+
simtools-print-array-elements \\
|
|
43
|
+
--input tests/resources/telescope_positions-South-4MST.ecsv \\
|
|
44
|
+
--compact ground
|
|
39
45
|
|
|
40
46
|
Expected final print-out message:
|
|
41
47
|
|
|
42
48
|
.. code-block:: console
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
telescope_name pos_x pos_y altitude
|
|
51
|
+
MST-01 -0.02 -0.00 2162.00
|
|
52
|
+
MST-02 1.43 151.02 2163.00
|
|
53
|
+
MST-03 -1.47 -151.02 2169.00
|
|
54
|
+
MST-04 150.72 73.57 2159.00
|
|
49
55
|
|
|
56
|
+
The following example converts a list of telescope positions in UTM coordinates \
|
|
57
|
+
and writes the output to a file in ground (sim_telarray) coordinates. Also selects \
|
|
58
|
+
only a subset of the array elements (telescopes; ignore calibration devices):
|
|
50
59
|
|
|
60
|
+
.. code-block:: console
|
|
61
|
+
|
|
62
|
+
simtools-print-array-elements \\
|
|
63
|
+
--input tests/resources/telescope_positions-North-utm.ecsv \\
|
|
64
|
+
--export ground --use_corsika_telescope_height \\
|
|
65
|
+
--select_assets LSTN, MSTN, SSTN
|
|
66
|
+
|
|
67
|
+
Expected output is a ecsv file in the directory printed to the screen.
|
|
51
68
|
|
|
52
69
|
"""
|
|
53
70
|
|
|
54
71
|
import logging
|
|
55
72
|
from pathlib import Path
|
|
56
73
|
|
|
74
|
+
import simtools.data_model.model_data_writer as writer
|
|
57
75
|
import simtools.utils.general as gen
|
|
58
76
|
from simtools.configuration import configurator
|
|
59
|
-
from simtools.
|
|
77
|
+
from simtools.data_model.metadata_collector import MetadataCollector
|
|
78
|
+
from simtools.layout import array_layout
|
|
60
79
|
|
|
61
80
|
|
|
62
81
|
def _parse(label=None, description=None):
|
|
@@ -80,9 +99,15 @@ def _parse(label=None, description=None):
|
|
|
80
99
|
config = configurator.Configurator(label=label, description=description)
|
|
81
100
|
|
|
82
101
|
config.parser.add_argument(
|
|
83
|
-
"--
|
|
84
|
-
help="list of array element positions
|
|
85
|
-
required=
|
|
102
|
+
"--input",
|
|
103
|
+
help="list of array element positions",
|
|
104
|
+
required=False,
|
|
105
|
+
)
|
|
106
|
+
config.parser.add_argument(
|
|
107
|
+
"--input_meta",
|
|
108
|
+
help="meta data file associated to input data",
|
|
109
|
+
type=str,
|
|
110
|
+
required=False,
|
|
86
111
|
)
|
|
87
112
|
config.parser.add_argument(
|
|
88
113
|
"--compact",
|
|
@@ -90,7 +115,7 @@ def _parse(label=None, description=None):
|
|
|
90
115
|
required=False,
|
|
91
116
|
default="",
|
|
92
117
|
choices=[
|
|
93
|
-
"
|
|
118
|
+
"ground",
|
|
94
119
|
"utm",
|
|
95
120
|
"mercator",
|
|
96
121
|
],
|
|
@@ -101,14 +126,14 @@ def _parse(label=None, description=None):
|
|
|
101
126
|
required=False,
|
|
102
127
|
default=None,
|
|
103
128
|
choices=[
|
|
104
|
-
"
|
|
129
|
+
"ground",
|
|
105
130
|
"utm",
|
|
106
131
|
"mercator",
|
|
107
132
|
],
|
|
108
133
|
)
|
|
109
134
|
config.parser.add_argument(
|
|
110
135
|
"--use_corsika_telescope_height",
|
|
111
|
-
help="Use CORSIKA coordinates for telescope heights (requires CORSIKA
|
|
136
|
+
help="Use CORSIKA coordinates for telescope heights (requires CORSIKA observation level)",
|
|
112
137
|
required=False,
|
|
113
138
|
default=False,
|
|
114
139
|
action="store_true",
|
|
@@ -120,23 +145,45 @@ def _parse(label=None, description=None):
|
|
|
120
145
|
default=None,
|
|
121
146
|
nargs="+",
|
|
122
147
|
)
|
|
123
|
-
|
|
148
|
+
config.parser.add_argument(
|
|
149
|
+
"--skip_input_validation",
|
|
150
|
+
help="skip input data validation against schema",
|
|
151
|
+
default=False,
|
|
152
|
+
required=False,
|
|
153
|
+
action="store_true",
|
|
154
|
+
)
|
|
155
|
+
return config.initialize(output=True, require_command_line=True)
|
|
124
156
|
|
|
125
157
|
|
|
126
158
|
def main():
|
|
127
159
|
label = Path(__file__).stem
|
|
128
|
-
|
|
160
|
+
data_model_name = "array_coordinates"
|
|
161
|
+
args_dict, _ = _parse(
|
|
162
|
+
label,
|
|
163
|
+
description=f"Print a list of array element positions ({data_model_name})",
|
|
164
|
+
)
|
|
129
165
|
|
|
130
166
|
_logger = logging.getLogger()
|
|
131
167
|
_logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
132
168
|
|
|
133
|
-
layout =
|
|
169
|
+
layout = array_layout.ArrayLayout(
|
|
170
|
+
telescope_list_file=args_dict["input"],
|
|
171
|
+
telescope_list_metadata_file=args_dict["input_meta"],
|
|
172
|
+
validate=not args_dict["skip_input_validation"],
|
|
173
|
+
)
|
|
134
174
|
layout.select_assets(args_dict["select_assets"])
|
|
135
175
|
layout.convert_coordinates()
|
|
176
|
+
|
|
136
177
|
if args_dict["export"] is not None:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
178
|
+
_metadata = MetadataCollector(args_dict=args_dict, data_model_name=data_model_name)
|
|
179
|
+
writer.ModelDataWriter.dump(
|
|
180
|
+
args_dict=args_dict,
|
|
181
|
+
metadata=_metadata.top_level_meta,
|
|
182
|
+
product_data=layout.export_telescope_list_table(
|
|
183
|
+
crs_name=args_dict["export"],
|
|
184
|
+
corsika_z=args_dict["use_corsika_telescope_height"],
|
|
185
|
+
),
|
|
186
|
+
validate_schema_file=_metadata.get_data_model_schema_file_name(),
|
|
140
187
|
)
|
|
141
188
|
else:
|
|
142
189
|
layout.print_telescope_list(
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
array_config (str, required)
|
|
66
66
|
Path to a yaml file with the array config data.
|
|
67
67
|
verbosity (str, optional)
|
|
68
|
-
Log level to print
|
|
68
|
+
Log level to print.
|
|
69
69
|
|
|
70
70
|
Example
|
|
71
71
|
-------
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
|
|
76
76
|
.. code-block:: console
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
simtools-get-file-from-db --file_name array_config_test.yml
|
|
79
79
|
|
|
80
80
|
Run the application. Runtime < 1 min.
|
|
81
81
|
|
|
@@ -43,9 +43,14 @@
|
|
|
43
43
|
If activated, no job will be submitted, but all configuration files \
|
|
44
44
|
and run scripts will be created.
|
|
45
45
|
data_directory (str, optional)
|
|
46
|
-
The location of the output directories corsika-data and simtel-data
|
|
46
|
+
The location of the output directories corsika-data and simtel-data.
|
|
47
|
+
corsika_files (str, optional)
|
|
48
|
+
The CORSIKA files to pass to simtel_array.
|
|
49
|
+
If it is provided, these CORSIKA files are used and the application does not search for them
|
|
50
|
+
in the data directory.
|
|
51
|
+
This option should only be used in combination with the `showers_only` option.
|
|
47
52
|
verbosity (str, optional)
|
|
48
|
-
Log level to print
|
|
53
|
+
Log level to print.
|
|
49
54
|
|
|
50
55
|
Example
|
|
51
56
|
-------
|
|
@@ -55,7 +60,7 @@
|
|
|
55
60
|
|
|
56
61
|
.. code-block:: console
|
|
57
62
|
|
|
58
|
-
simtools-get-file-
|
|
63
|
+
simtools-get-file-from-db --file_name prod_config_test.yml
|
|
59
64
|
|
|
60
65
|
Run the application:
|
|
61
66
|
|
|
@@ -76,6 +81,7 @@
|
|
|
76
81
|
|
|
77
82
|
import logging
|
|
78
83
|
from copy import copy
|
|
84
|
+
from pathlib import Path
|
|
79
85
|
|
|
80
86
|
from astropy.io.misc import yaml
|
|
81
87
|
|
|
@@ -142,6 +148,13 @@ def _parse(description=None):
|
|
|
142
148
|
required=False,
|
|
143
149
|
default="./",
|
|
144
150
|
)
|
|
151
|
+
config.parser.add_argument(
|
|
152
|
+
"--corsika_files",
|
|
153
|
+
help="The CORSIKA files to pass to simtel_array.",
|
|
154
|
+
type=str,
|
|
155
|
+
required=False,
|
|
156
|
+
default=None,
|
|
157
|
+
)
|
|
145
158
|
group = config.parser.add_mutually_exclusive_group(required=True)
|
|
146
159
|
group.add_argument(
|
|
147
160
|
"--showers_only",
|
|
@@ -221,7 +234,6 @@ def _proccess_simulation_config_file(config_file, primary_config, logger):
|
|
|
221
234
|
for key, value in this_default.items():
|
|
222
235
|
config_showers[primary][key] = value
|
|
223
236
|
config_arrays[primary][key] = value
|
|
224
|
-
|
|
225
237
|
return label, config_showers, config_arrays
|
|
226
238
|
|
|
227
239
|
|
|
@@ -237,6 +249,11 @@ def main():
|
|
|
237
249
|
if args_dict["label"] is None:
|
|
238
250
|
args_dict["label"] = label
|
|
239
251
|
|
|
252
|
+
if args_dict["corsika_files"] is not None and args_dict["array_only"] is False:
|
|
253
|
+
msg = "`--corsika_files` option should be used only with `--array_only` argument."
|
|
254
|
+
logger.error(msg)
|
|
255
|
+
raise ValueError
|
|
256
|
+
|
|
240
257
|
shower_simulators = {}
|
|
241
258
|
for primary, config_data in shower_configs.items():
|
|
242
259
|
if "data_directory" in args_dict:
|
|
@@ -270,7 +287,24 @@ def main():
|
|
|
270
287
|
mongo_db_config=db_config,
|
|
271
288
|
)
|
|
272
289
|
for primary, array in array_simulators.items():
|
|
273
|
-
|
|
290
|
+
if args_dict["corsika_files"] is None:
|
|
291
|
+
input_list = shower_simulators[primary].get_list_of_output_files()
|
|
292
|
+
else:
|
|
293
|
+
if not isinstance(args_dict["corsika_files"], list):
|
|
294
|
+
args_dict["corsika_files"] = [args_dict["corsika_files"]]
|
|
295
|
+
input_list = args_dict["corsika_files"]
|
|
296
|
+
|
|
297
|
+
for corsika_file in input_list:
|
|
298
|
+
if not Path(corsika_file).exists():
|
|
299
|
+
msg = (
|
|
300
|
+
f"CORSIKA file {corsika_file} does not exist. Please run the "
|
|
301
|
+
"production with the `--showers_only` option first or point the "
|
|
302
|
+
"tool to the correct path to the corsika files with "
|
|
303
|
+
"`--corsika_directory`."
|
|
304
|
+
)
|
|
305
|
+
logger.error(msg)
|
|
306
|
+
raise FileNotFoundError
|
|
307
|
+
logger.info(f"Getting CORSIKA files: {input_list}.")
|
|
274
308
|
_task_function = getattr(array, args_dict["task"])
|
|
275
309
|
_task_function(input_file_list=input_list)
|
|
276
310
|
|
|
@@ -25,21 +25,22 @@
|
|
|
25
25
|
primary (str, required)
|
|
26
26
|
Name of the primary particle (proton, helium ...).
|
|
27
27
|
nruns (int, optional)
|
|
28
|
-
Number of runs to be simulated
|
|
28
|
+
Number of runs to be simulated.
|
|
29
29
|
nevents (int, optional)
|
|
30
|
-
Number of events simulated per run
|
|
30
|
+
Number of events simulated per run.
|
|
31
31
|
zenith (float, optional)
|
|
32
|
-
Zenith angle in deg
|
|
32
|
+
Zenith angle in deg.
|
|
33
33
|
azimuth (float, optional)
|
|
34
|
-
Azimuth angle in deg
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
the
|
|
34
|
+
Azimuth angle in deg.
|
|
35
|
+
data_directory (str, optional)
|
|
36
|
+
The location of the output directories corsika-data.
|
|
37
|
+
the label is added to the data_directory, such that the output
|
|
38
|
+
will be written to `data_directory/label/corsika-data`.
|
|
38
39
|
test (activation mode, optional)
|
|
39
40
|
If activated, no job will be submitted. Instead, an example of the \
|
|
40
41
|
run script will be printed.
|
|
41
42
|
verbosity (str, optional)
|
|
42
|
-
Log level to print
|
|
43
|
+
Log level to print.
|
|
43
44
|
|
|
44
45
|
Example
|
|
45
46
|
-------
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
|
|
48
49
|
.. code-block:: console
|
|
49
50
|
|
|
50
|
-
simtools-sim-showers-for-
|
|
51
|
+
simtools-sim-showers-for-trigger-rates --array 4LST --site North --primary \
|
|
51
52
|
proton --nruns 2 --nevents 10000 --test --submit_command local
|
|
52
53
|
|
|
53
54
|
The output is saved in simtools-output/sim_showers_for_trigger_rates.
|
|
@@ -68,8 +69,8 @@ from pathlib import Path
|
|
|
68
69
|
|
|
69
70
|
import astropy.units as u
|
|
70
71
|
|
|
71
|
-
from simtools import io_handler
|
|
72
72
|
from simtools.configuration import configurator
|
|
73
|
+
from simtools.io_operations import io_handler
|
|
73
74
|
from simtools.simulator import Simulator
|
|
74
75
|
from simtools.utils import general as gen
|
|
75
76
|
|
|
@@ -105,24 +106,20 @@ def _parse(label=None, description=None):
|
|
|
105
106
|
type=str,
|
|
106
107
|
required=True,
|
|
107
108
|
)
|
|
109
|
+
config.parser.add_argument("--nruns", help="Number of runs", type=int, default=100)
|
|
110
|
+
config.parser.add_argument("--nevents", help="Number of events/run", type=int, default=100000)
|
|
111
|
+
config.parser.add_argument("--zenith", help="Zenith angle in deg", type=float, default=20)
|
|
112
|
+
config.parser.add_argument("--azimuth", help="Azimuth angle in deg", type=float, default=0)
|
|
108
113
|
config.parser.add_argument(
|
|
109
|
-
"--
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
"--azimuth", help="Azimuth angle in deg (default=0)", type=float, default=0
|
|
119
|
-
)
|
|
120
|
-
# TODO confusing with output_path?
|
|
121
|
-
config.parser.add_argument(
|
|
122
|
-
"--output",
|
|
123
|
-
help="Path of the output directory where the simulations will be saved.",
|
|
124
|
-
type=str,
|
|
125
|
-
default=None,
|
|
114
|
+
"--data_directory",
|
|
115
|
+
help=(
|
|
116
|
+
"The directory where to save the corsika-data output directories."
|
|
117
|
+
"the label is added to the data_directory, such that the output"
|
|
118
|
+
"will be written to `data_directory/label/corsika-data`."
|
|
119
|
+
),
|
|
120
|
+
type=str.lower,
|
|
121
|
+
required=False,
|
|
122
|
+
default="./simtools-output/",
|
|
126
123
|
)
|
|
127
124
|
return config.initialize(telescope_model=True, job_submission=True, db_config=True)
|
|
128
125
|
|
|
@@ -138,10 +135,9 @@ def main():
|
|
|
138
135
|
|
|
139
136
|
# Output directory to save files related directly to this app
|
|
140
137
|
_io_handler = io_handler.IOHandler()
|
|
141
|
-
output_dir = _io_handler.get_output_directory(label,
|
|
142
|
-
print(output_dir)
|
|
138
|
+
output_dir = _io_handler.get_output_directory(label, sub_dir="application-plots")
|
|
143
139
|
shower_config_data = {
|
|
144
|
-
"data_directory": args_dict["
|
|
140
|
+
"data_directory": Path(args_dict["data_directory"]) / label,
|
|
145
141
|
"site": args_dict["site"],
|
|
146
142
|
"layout_name": args_dict["array"],
|
|
147
143
|
"run_range": [1, args_dict["nruns"] + 1],
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
The entire simulation chain is performed, i.e., shower simulations with CORSIKA
|
|
12
12
|
which are piped directly to sim_telarray using the sim_telarray multipipe mechanism.
|
|
13
|
-
This script
|
|
14
|
-
sim_telarray
|
|
13
|
+
This script produces all the necessary configuration files for CORSIKA and
|
|
14
|
+
sim_telarray before running simulation.
|
|
15
15
|
The multipipe scripts will be produced as part of this script.
|
|
16
16
|
|
|
17
17
|
This script does not provide a mechanism to submit jobs to a batch system like others
|
|
@@ -48,9 +48,14 @@
|
|
|
48
48
|
run (int, required)
|
|
49
49
|
Run number (actual run number will be 'start_run' + 'run').
|
|
50
50
|
data_directory (str, optional)
|
|
51
|
-
The location of the output directories corsika-data and simtel-data
|
|
51
|
+
The location of the output directories corsika-data and simtel-data.
|
|
52
|
+
the label is added to the data_directory, such that the output
|
|
53
|
+
will be written to `data_directory/label/simtel-data`.
|
|
54
|
+
pack_for_grid_register (bool, optional)
|
|
55
|
+
Set whether to prepare a tarball for registering the output files on the grid.
|
|
56
|
+
The files are written to the `output_path/directory_for_grid_upload` directory.
|
|
52
57
|
log_level (str, optional)
|
|
53
|
-
Log level to print
|
|
58
|
+
Log level to print.
|
|
54
59
|
|
|
55
60
|
Example
|
|
56
61
|
-------
|
|
@@ -61,20 +66,23 @@
|
|
|
61
66
|
simtools-simulate-prod \
|
|
62
67
|
--production_config tests/resources/prod_multi_config_test.yml --model_version Prod5 \
|
|
63
68
|
--site north --primary gamma --azimuth_angle north --zenith_angle 20 \
|
|
64
|
-
|
|
69
|
+
--start_run 0 --run 1
|
|
65
70
|
|
|
66
71
|
By default the configuration is saved in simtools-output/test-production
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
together with the actual simulation output in corsika-data and simtel-data within.
|
|
73
|
+
The location of the latter directories can be set
|
|
74
|
+
to a different location via the option --data_directory,
|
|
75
|
+
but the label is always added to the data_directory, such that the output
|
|
76
|
+
will be written to `data_directory/label/simtel-data`.
|
|
69
77
|
|
|
70
78
|
Expected final print-out message:
|
|
71
79
|
|
|
72
80
|
.. code-block:: console
|
|
73
81
|
|
|
74
|
-
INFO::
|
|
82
|
+
INFO::array_layout(l569)::read_telescope_list_file::Reading array elements from ...
|
|
75
83
|
WARNING::corsika_runner(l127)::_load_corsika_config_data::data_directory not given
|
|
76
84
|
in corsika_config - default output directory will be set.
|
|
77
|
-
INFO::
|
|
85
|
+
INFO::array_layout(l569)::read_telescope_list_file::Reading array elements from ...
|
|
78
86
|
INFO::corsika_config(l493)::_set_output_file_and_directory::Creating directory
|
|
79
87
|
INFO::simulator(l405)::simulate::Submission command: local
|
|
80
88
|
INFO::simulator(l410)::simulate::Starting submission for 1 run
|
|
@@ -87,8 +95,8 @@
|
|
|
87
95
|
"""
|
|
88
96
|
|
|
89
97
|
import logging
|
|
98
|
+
import shutil
|
|
90
99
|
import tarfile
|
|
91
|
-
from copy import copy
|
|
92
100
|
from pathlib import Path
|
|
93
101
|
|
|
94
102
|
from astropy.io.misc import yaml
|
|
@@ -184,10 +192,14 @@ def _parse(description=None):
|
|
|
184
192
|
)
|
|
185
193
|
config.parser.add_argument(
|
|
186
194
|
"--data_directory",
|
|
187
|
-
help=
|
|
195
|
+
help=(
|
|
196
|
+
"The directory where to save the corsika-data and simtel-data output directories."
|
|
197
|
+
"the label is added to the data_directory, such that the output"
|
|
198
|
+
"will be written to `data_directory/label/simtel-data`."
|
|
199
|
+
),
|
|
188
200
|
type=str.lower,
|
|
189
201
|
required=False,
|
|
190
|
-
default="./",
|
|
202
|
+
default="./simtools-output/",
|
|
191
203
|
)
|
|
192
204
|
config.parser.add_argument(
|
|
193
205
|
"--pack_for_grid_register",
|
|
@@ -199,112 +211,40 @@ def _parse(description=None):
|
|
|
199
211
|
return config.initialize(db_config=True, telescope_model=True)
|
|
200
212
|
|
|
201
213
|
|
|
202
|
-
def _proccess_simulation_config_file(config_file, primary_config, logger):
|
|
203
|
-
"""
|
|
204
|
-
Read the simulation configuration file with all the details
|
|
205
|
-
on shower and array simulations.
|
|
206
|
-
|
|
207
|
-
Parameters
|
|
208
|
-
----------
|
|
209
|
-
config_file: str
|
|
210
|
-
Name of simulation configuration file.
|
|
211
|
-
primary_config: str
|
|
212
|
-
Name of the primary selected from the configuration file.
|
|
213
|
-
logger: logging.logger
|
|
214
|
-
The logger to use to record log calls.
|
|
215
|
-
|
|
216
|
-
Returns
|
|
217
|
-
-------
|
|
218
|
-
str
|
|
219
|
-
Label of simulation configuration.
|
|
220
|
-
dict
|
|
221
|
-
Configuration of shower simulations.
|
|
222
|
-
dict
|
|
223
|
-
Configuration of array simulations.
|
|
224
|
-
|
|
225
|
-
Raises
|
|
226
|
-
------
|
|
227
|
-
FileNotFoundError
|
|
228
|
-
"""
|
|
229
|
-
|
|
230
|
-
try:
|
|
231
|
-
with open(config_file, encoding="utf-8") as file:
|
|
232
|
-
config_data = yaml.load(file)
|
|
233
|
-
except FileNotFoundError:
|
|
234
|
-
logger.error(f"Error loading simulation configuration file from {config_file}")
|
|
235
|
-
raise
|
|
236
|
-
|
|
237
|
-
label = config_data.pop("label", "test_run")
|
|
238
|
-
default_data = config_data.pop("default", {})
|
|
239
|
-
|
|
240
|
-
for primary, primary_data in config_data.items():
|
|
241
|
-
if primary_config is not None and primary != primary_config:
|
|
242
|
-
continue
|
|
243
|
-
|
|
244
|
-
this_default = copy(default_data)
|
|
245
|
-
|
|
246
|
-
config_showers = copy(this_default.pop("showers", {}))
|
|
247
|
-
config_arrays = copy(this_default.pop("array", {}))
|
|
248
|
-
|
|
249
|
-
# Grabbing common entries for showers and array
|
|
250
|
-
for key, value in primary_data.items():
|
|
251
|
-
if key in ["showers", "array"]:
|
|
252
|
-
continue
|
|
253
|
-
config_showers[key] = value
|
|
254
|
-
config_arrays[key] = value
|
|
255
|
-
|
|
256
|
-
# Grabbing showers entries
|
|
257
|
-
for key, value in primary_data.get("showers", {}).items():
|
|
258
|
-
config_showers[key] = value
|
|
259
|
-
config_showers["primary"] = primary
|
|
260
|
-
|
|
261
|
-
# Grabbing array entries
|
|
262
|
-
for key, value in primary_data.get("array", {}).items():
|
|
263
|
-
config_arrays[key] = value
|
|
264
|
-
config_arrays["primary"] = primary
|
|
265
|
-
|
|
266
|
-
# Filling in the remaining default keys
|
|
267
|
-
for key, value in this_default.items():
|
|
268
|
-
config_showers[key] = value
|
|
269
|
-
config_arrays[key] = value
|
|
270
|
-
|
|
271
|
-
config_arrays["data_directory"] = config_showers["data_directory"]
|
|
272
|
-
config_arrays["site"] = config_showers["site"]
|
|
273
|
-
config_arrays["layout_name"] = config_showers["layout_name"]
|
|
274
|
-
|
|
275
|
-
return label, config_showers, config_arrays
|
|
276
|
-
|
|
277
|
-
|
|
278
214
|
def main():
|
|
279
215
|
args_dict, db_config = _parse(description="Run simulations for productions")
|
|
280
216
|
|
|
281
217
|
logger = logging.getLogger()
|
|
282
218
|
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
283
219
|
|
|
284
|
-
|
|
285
|
-
args_dict["production_config"],
|
|
286
|
-
|
|
220
|
+
try:
|
|
221
|
+
with open(args_dict["production_config"], encoding="utf-8") as file:
|
|
222
|
+
config_data = yaml.load(file)
|
|
223
|
+
except FileNotFoundError:
|
|
224
|
+
logger.error(
|
|
225
|
+
f"Error loading simulation configuration file from {args_dict['production_config']}"
|
|
226
|
+
)
|
|
227
|
+
raise
|
|
287
228
|
|
|
288
229
|
# Overwrite default and optional settings
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
230
|
+
config_data["showers"]["run_list"] = args_dict["run"] + args_dict["start_run"]
|
|
231
|
+
config_data["showers"]["primary"] = args_dict["primary"]
|
|
232
|
+
config_data["common"]["site"] = args_dict["site"]
|
|
233
|
+
config_data["common"]["zenith"] = args_dict["zenith_angle"]
|
|
234
|
+
config_data["common"]["phi"] = args_dict["azimuth_angle"]
|
|
235
|
+
label = config_data["common"].pop("label", "test-production")
|
|
236
|
+
config_data["common"]["data_directory"] = Path(args_dict["data_directory"]) / label
|
|
293
237
|
|
|
294
238
|
if args_dict["nshow"] is not None:
|
|
295
|
-
|
|
239
|
+
config_data["showers"]["nshow"] = args_dict["nshow"]
|
|
296
240
|
if args_dict["label"] is not None:
|
|
297
241
|
label = args_dict["label"]
|
|
298
|
-
if "data_directory" in args_dict:
|
|
299
|
-
array_configs["data_directory"] = shower_configs["data_directory"] = args_dict[
|
|
300
|
-
"data_directory"
|
|
301
|
-
]
|
|
302
242
|
|
|
303
243
|
simulator = Simulator(
|
|
304
244
|
label=label,
|
|
305
245
|
simulator="corsika_simtel",
|
|
306
246
|
simulator_source_path=args_dict["simtel_path"],
|
|
307
|
-
config_data=
|
|
247
|
+
config_data=config_data,
|
|
308
248
|
submit_command="local",
|
|
309
249
|
test=args_dict["test"],
|
|
310
250
|
mongo_db_config=db_config,
|
|
@@ -313,10 +253,10 @@ def main():
|
|
|
313
253
|
simulator.simulate()
|
|
314
254
|
|
|
315
255
|
logger.info(
|
|
316
|
-
f"Production run is complete for primary {
|
|
317
|
-
f"coming from {
|
|
318
|
-
f"{
|
|
319
|
-
f"using the {
|
|
256
|
+
f"Production run is complete for primary {config_data['showers']['primary']} showers "
|
|
257
|
+
f"coming from {config_data['common']['phi']} azimuth and zenith angle of "
|
|
258
|
+
f"{config_data['common']['zenith']} at the {args_dict['site']} site, "
|
|
259
|
+
f"using the {config_data['array']['model_version']} telescope model."
|
|
320
260
|
)
|
|
321
261
|
|
|
322
262
|
if args_dict["pack_for_grid_register"]:
|
|
@@ -329,7 +269,9 @@ def main():
|
|
|
329
269
|
files_to_tar = log_files[:1] + histogram_files[:1]
|
|
330
270
|
for file_to_tar in files_to_tar:
|
|
331
271
|
tar.add(file_to_tar, arcname=Path(file_to_tar).name)
|
|
332
|
-
directory_for_grid_upload = Path("
|
|
272
|
+
directory_for_grid_upload = Path(args_dict.get("output_path")).joinpath(
|
|
273
|
+
"directory_for_grid_upload"
|
|
274
|
+
)
|
|
333
275
|
directory_for_grid_upload.mkdir(parents=True, exist_ok=True)
|
|
334
276
|
for file_to_move in [*output_files, tar_file_name]:
|
|
335
277
|
source_file = Path(file_to_move)
|
|
@@ -337,7 +279,7 @@ def main():
|
|
|
337
279
|
# Note that this will overwrite previous files which exist in the directory
|
|
338
280
|
# It should be fine for normal production since each run is on a separate node
|
|
339
281
|
# so no files are expected there.
|
|
340
|
-
|
|
282
|
+
shutil.move(source_file, destination_file)
|
|
341
283
|
logger.info(f"Output files for the grid placed in {str(directory_for_grid_upload)}")
|
|
342
284
|
|
|
343
285
|
|