gammasimtools 0.26.0__py3-none-any.whl → 0.27.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.26.0.dist-info → gammasimtools-0.27.0.dist-info}/METADATA +5 -1
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/RECORD +70 -66
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/entry_points.txt +1 -1
- simtools/_version.py +2 -2
- simtools/applications/convert_geo_coordinates_of_array_elements.py +2 -1
- simtools/applications/db_get_array_layouts_from_db.py +1 -1
- simtools/applications/{calculate_incident_angles.py → derive_incident_angle.py} +16 -16
- simtools/applications/derive_mirror_rnda.py +111 -177
- simtools/applications/generate_corsika_histograms.py +38 -1
- simtools/applications/generate_regular_arrays.py +73 -36
- simtools/applications/simulate_flasher.py +3 -13
- simtools/applications/simulate_illuminator.py +2 -10
- simtools/applications/simulate_pedestals.py +1 -1
- simtools/applications/simulate_prod.py +8 -7
- simtools/applications/submit_data_from_external.py +2 -1
- simtools/applications/validate_camera_efficiency.py +28 -27
- simtools/applications/validate_cumulative_psf.py +1 -3
- simtools/applications/validate_optics.py +2 -1
- simtools/atmosphere.py +83 -0
- simtools/camera/camera_efficiency.py +171 -48
- simtools/camera/single_photon_electron_spectrum.py +6 -6
- simtools/configuration/commandline_parser.py +47 -9
- simtools/constants.py +5 -0
- simtools/corsika/corsika_config.py +88 -185
- simtools/corsika/corsika_histograms.py +246 -69
- simtools/data_model/model_data_writer.py +46 -49
- simtools/data_model/schema.py +2 -0
- simtools/db/db_handler.py +4 -2
- simtools/db/mongo_db.py +2 -2
- simtools/io/ascii_handler.py +51 -3
- simtools/io/io_handler.py +23 -12
- simtools/job_execution/job_manager.py +154 -79
- simtools/job_execution/process_pool.py +137 -0
- simtools/layout/array_layout.py +0 -1
- simtools/layout/array_layout_utils.py +143 -21
- simtools/model/array_model.py +22 -50
- simtools/model/calibration_model.py +4 -4
- simtools/model/model_parameter.py +123 -73
- simtools/model/model_utils.py +40 -1
- simtools/model/site_model.py +4 -4
- simtools/model/telescope_model.py +4 -5
- simtools/ray_tracing/incident_angles.py +87 -6
- simtools/ray_tracing/mirror_panel_psf.py +337 -217
- simtools/ray_tracing/psf_analysis.py +57 -42
- simtools/ray_tracing/psf_parameter_optimisation.py +3 -2
- simtools/ray_tracing/ray_tracing.py +37 -10
- simtools/runners/corsika_runner.py +52 -191
- simtools/runners/corsika_simtel_runner.py +74 -100
- simtools/runners/runner_services.py +214 -213
- simtools/runners/simtel_runner.py +27 -155
- simtools/runners/simtools_runner.py +9 -69
- simtools/schemas/application_workflow.metaschema.yml +8 -0
- simtools/settings.py +19 -0
- simtools/simtel/simtel_config_writer.py +0 -55
- simtools/simtel/simtel_seeds.py +184 -0
- simtools/simtel/simulator_array.py +115 -103
- simtools/simtel/simulator_camera_efficiency.py +66 -42
- simtools/simtel/simulator_light_emission.py +110 -123
- simtools/simtel/simulator_ray_tracing.py +78 -63
- simtools/simulator.py +135 -346
- simtools/testing/sim_telarray_metadata.py +13 -11
- simtools/testing/validate_output.py +87 -19
- simtools/utils/general.py +6 -17
- simtools/utils/random.py +36 -0
- simtools/visualization/plot_corsika_histograms.py +2 -0
- simtools/visualization/plot_incident_angles.py +48 -1
- simtools/visualization/plot_psf.py +160 -18
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/top_level.txt +0 -0
|
@@ -1,130 +1,168 @@
|
|
|
1
1
|
"""Base service methods for simulation runners."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
|
|
5
|
+
from simtools.corsika.corsika_config import CorsikaConfig
|
|
6
6
|
from simtools.io import io_handler
|
|
7
7
|
|
|
8
8
|
_logger = logging.getLogger(__name__)
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
FILES_AND_PATHS = {
|
|
12
|
+
# CORSIKA
|
|
13
|
+
"corsika_input": {
|
|
14
|
+
"suffix": ".corsika.input",
|
|
15
|
+
"sub_dir_type": "run_number",
|
|
16
|
+
},
|
|
17
|
+
"corsika_output": {
|
|
18
|
+
"suffix": ".corsika.zst",
|
|
19
|
+
"sub_dir_type": "run_number",
|
|
20
|
+
},
|
|
21
|
+
"corsika_log": {
|
|
22
|
+
"suffix": ".corsika.log.gz",
|
|
23
|
+
"sub_dir_type": "run_number",
|
|
24
|
+
},
|
|
25
|
+
# Generic iact output
|
|
26
|
+
"iact_output": {
|
|
27
|
+
"suffix": ".iact.gz",
|
|
28
|
+
"sub_dir_type": "run_number",
|
|
29
|
+
},
|
|
30
|
+
# sim_telarray
|
|
31
|
+
"sim_telarray_output": {
|
|
32
|
+
"suffix": ".simtel.zst",
|
|
33
|
+
"sub_dir_type": "run_number",
|
|
34
|
+
},
|
|
35
|
+
"sim_telarray_histogram": {
|
|
36
|
+
"suffix": ".hdata.zst",
|
|
37
|
+
"sub_dir_type": "run_number",
|
|
38
|
+
},
|
|
39
|
+
"sim_telarray_log": {
|
|
40
|
+
"suffix": ".simtel.log.gz",
|
|
41
|
+
"sub_dir_type": "run_number",
|
|
42
|
+
},
|
|
43
|
+
"sim_telarray_event_data": {
|
|
44
|
+
"suffix": ".reduced_event_data.hdf5",
|
|
45
|
+
"sub_dir_type": "run_number",
|
|
46
|
+
},
|
|
47
|
+
# multipipe
|
|
48
|
+
"multi_pipe_config": {
|
|
49
|
+
"suffix": ".multi_pipe.cfg",
|
|
50
|
+
"sub_dir_type": "run_number",
|
|
51
|
+
},
|
|
52
|
+
"multi_pipe_script": {
|
|
53
|
+
"suffix": ".multi_pipe.sh",
|
|
54
|
+
"sub_dir_type": "run_number",
|
|
55
|
+
},
|
|
56
|
+
# job submission
|
|
57
|
+
"sub_out": {
|
|
58
|
+
"suffix": ".out",
|
|
59
|
+
"sub_dir_type": "sub",
|
|
60
|
+
},
|
|
61
|
+
"sub_err": {
|
|
62
|
+
"suffix": ".err",
|
|
63
|
+
"sub_dir_type": "sub",
|
|
64
|
+
},
|
|
65
|
+
"sub_log": {
|
|
66
|
+
"suffix": ".log",
|
|
67
|
+
"sub_dir_type": "sub",
|
|
68
|
+
},
|
|
69
|
+
"sub_script": {
|
|
70
|
+
"suffix": ".sh",
|
|
71
|
+
"sub_dir_type": "sub",
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def validate_corsika_run_number(run_number):
|
|
77
|
+
"""
|
|
78
|
+
Validate run number and return it.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
run_number: int
|
|
83
|
+
Run number.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
int
|
|
88
|
+
Run number.
|
|
89
|
+
|
|
90
|
+
Raises
|
|
91
|
+
------
|
|
92
|
+
ValueError
|
|
93
|
+
If run_number is not a valid value (< 1 or > 999999).
|
|
94
|
+
"""
|
|
95
|
+
if not float(run_number).is_integer() or run_number < 1 or run_number > 999999:
|
|
96
|
+
raise ValueError(
|
|
97
|
+
f"Invalid type of run number ({run_number}) - it must be an uint < 1000000."
|
|
98
|
+
)
|
|
99
|
+
return run_number
|
|
100
|
+
|
|
101
|
+
|
|
11
102
|
class RunnerServices:
|
|
12
103
|
"""
|
|
13
|
-
Base
|
|
104
|
+
Base service methods for simulation runners.
|
|
105
|
+
|
|
106
|
+
Includes file naming and directory management.
|
|
14
107
|
|
|
15
108
|
Parameters
|
|
16
109
|
----------
|
|
17
|
-
|
|
18
|
-
Configuration parameters
|
|
110
|
+
config: CorsikaConfig, dict
|
|
111
|
+
Configuration parameters.
|
|
112
|
+
run_type : str
|
|
113
|
+
Type of simulation runner.
|
|
19
114
|
label : str
|
|
20
115
|
Label.
|
|
21
116
|
"""
|
|
22
117
|
|
|
23
|
-
def __init__(self,
|
|
118
|
+
def __init__(self, config, run_type, label=None):
|
|
24
119
|
"""Initialize RunnerServices."""
|
|
25
120
|
self._logger = logging.getLogger(__name__)
|
|
26
|
-
self._logger.debug("Init RunnerServices")
|
|
27
121
|
self.label = label
|
|
28
|
-
self.
|
|
29
|
-
self.
|
|
122
|
+
self.config = config
|
|
123
|
+
self.run_type = run_type
|
|
124
|
+
self.directory = self.load_data_directory()
|
|
30
125
|
|
|
31
|
-
def
|
|
126
|
+
def load_data_directory(self):
|
|
32
127
|
"""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Parameters
|
|
36
|
-
----------
|
|
37
|
-
run_number : int
|
|
38
|
-
Run number.
|
|
39
|
-
calibration_run_mode: str
|
|
40
|
-
Calibration run mode.
|
|
128
|
+
Create and return directory for the given run type.
|
|
41
129
|
|
|
42
130
|
Returns
|
|
43
131
|
-------
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"""
|
|
47
|
-
_vc_high = self.corsika_config.get_config_parameter("VIEWCONE")[1]
|
|
48
|
-
if calibration_run_mode is not None and calibration_run_mode != "":
|
|
49
|
-
primary_name = calibration_run_mode
|
|
50
|
-
else:
|
|
51
|
-
primary_name = self.corsika_config.primary
|
|
52
|
-
if primary_name == "gamma" and _vc_high > 0:
|
|
53
|
-
primary_name = "gamma_diffuse"
|
|
54
|
-
return {
|
|
55
|
-
"run_number": self.corsika_config.validate_run_number(run_number),
|
|
56
|
-
"primary": primary_name,
|
|
57
|
-
"array_name": self.corsika_config.array_model.layout_name,
|
|
58
|
-
"site": self.corsika_config.array_model.site,
|
|
59
|
-
"label": self.label,
|
|
60
|
-
"model_version": self.corsika_config.array_model.model_version,
|
|
61
|
-
"zenith": self.corsika_config.zenith_angle,
|
|
62
|
-
"azimuth": self.corsika_config.azimuth_angle,
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@staticmethod
|
|
66
|
-
def _get_simulation_software_list(simulation_software):
|
|
132
|
+
Path
|
|
133
|
+
Path to the created directory.
|
|
67
134
|
"""
|
|
68
|
-
|
|
135
|
+
ioh = io_handler.IOHandler()
|
|
136
|
+
directory = ioh.get_output_directory(self.run_type)
|
|
137
|
+
self._logger.debug(f"Data directories for {self.run_type}: {directory}")
|
|
69
138
|
|
|
70
|
-
|
|
71
|
-
simulation_software: String representing the desired software.
|
|
139
|
+
return directory
|
|
72
140
|
|
|
73
|
-
|
|
74
|
-
-------
|
|
75
|
-
List of simulation software names.
|
|
141
|
+
def load_files(self, run_number=None):
|
|
76
142
|
"""
|
|
77
|
-
|
|
78
|
-
"corsika": ["corsika"],
|
|
79
|
-
"sim_telarray": ["sim_telarray"],
|
|
80
|
-
"corsika_sim_telarray": ["corsika", "sim_telarray"],
|
|
81
|
-
}
|
|
82
|
-
return software_map.get(simulation_software.lower(), [])
|
|
83
|
-
|
|
84
|
-
def load_data_directories(self, simulation_software):
|
|
85
|
-
"""
|
|
86
|
-
Create and return directories for output, data, log and input.
|
|
143
|
+
Load files required for the simulation run.
|
|
87
144
|
|
|
88
145
|
Parameters
|
|
89
146
|
----------
|
|
90
|
-
|
|
91
|
-
|
|
147
|
+
run_number: int
|
|
148
|
+
Run number.
|
|
92
149
|
|
|
93
150
|
Returns
|
|
94
151
|
-------
|
|
95
152
|
dict
|
|
96
|
-
Dictionary containing paths
|
|
97
|
-
"""
|
|
98
|
-
ioh = io_handler.IOHandler()
|
|
99
|
-
self.directory["output"] = ioh.get_output_directory()
|
|
100
|
-
_logger.debug(f"Creating output dir {self.directory['output']}")
|
|
101
|
-
for dir_name in ["sub_scripts", "sub_logs"]:
|
|
102
|
-
self.directory[dir_name] = ioh.get_output_directory(dir_name)
|
|
103
|
-
for _simulation_software in self._get_simulation_software_list(simulation_software):
|
|
104
|
-
for dir_name in ["data", "inputs", "logs"]:
|
|
105
|
-
self.directory[dir_name] = ioh.get_output_directory(
|
|
106
|
-
[_simulation_software, dir_name]
|
|
107
|
-
)
|
|
108
|
-
self._logger.debug(f"Data directories for {simulation_software}: {self.directory}")
|
|
109
|
-
return self.directory
|
|
110
|
-
|
|
111
|
-
def has_file(self, file_type, run_number=None, mode="out"):
|
|
153
|
+
Dictionary containing paths to files required for the simulation run.
|
|
112
154
|
"""
|
|
113
|
-
|
|
155
|
+
run_files = {}
|
|
156
|
+
for key in FILES_AND_PATHS:
|
|
157
|
+
if key.startswith(self.run_type.lower()):
|
|
158
|
+
run_files[key] = self.get_file_name(file_type=key, run_number=run_number)
|
|
114
159
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
file_type: str
|
|
118
|
-
File type to check.
|
|
119
|
-
run_number: int
|
|
120
|
-
Run number.
|
|
160
|
+
for key, file_path in run_files.items():
|
|
161
|
+
self._logger.debug(f"{key}: {file_path}")
|
|
121
162
|
|
|
122
|
-
|
|
123
|
-
run_sub_file = self.get_file_name(file_type, run_number=run_number, mode=mode)
|
|
124
|
-
_logger.debug(f"Checking if {run_sub_file} exists")
|
|
125
|
-
return Path(run_sub_file).is_file()
|
|
163
|
+
return run_files
|
|
126
164
|
|
|
127
|
-
def _get_file_basename(self, run_number,
|
|
165
|
+
def _get_file_basename(self, run_number, is_multi_pipe=False):
|
|
128
166
|
"""
|
|
129
167
|
Get the base name for the simulation files.
|
|
130
168
|
|
|
@@ -132,118 +170,87 @@ class RunnerServices:
|
|
|
132
170
|
----------
|
|
133
171
|
run_number: int
|
|
134
172
|
Run number.
|
|
135
|
-
|
|
136
|
-
|
|
173
|
+
file_type: str
|
|
174
|
+
File type.
|
|
137
175
|
|
|
138
176
|
Returns
|
|
139
177
|
-------
|
|
140
178
|
str
|
|
141
179
|
Base name for the simulation files.
|
|
142
180
|
"""
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
)
|
|
181
|
+
if isinstance(self.config, CorsikaConfig):
|
|
182
|
+
return self._get_file_base_name_from_corsika_config(run_number, is_multi_pipe)
|
|
183
|
+
if isinstance(self.config, dict):
|
|
184
|
+
return self._get_file_base_name_from_core_config()
|
|
185
|
+
raise ValueError(f"Invalid configuration type: {type(self.config)}")
|
|
186
|
+
|
|
187
|
+
def _get_file_base_name_from_core_config(self):
|
|
188
|
+
"""Get file base name from core configuration."""
|
|
189
|
+
cfg = self.config
|
|
190
|
+
zenith_angle = cfg.get("zenith_angle")
|
|
191
|
+
azimuth_angle = cfg.get("azimuth_angle")
|
|
192
|
+
|
|
193
|
+
parts = [
|
|
194
|
+
f"{cfg['run_mode']}_" if cfg.get("run_mode") else "",
|
|
195
|
+
f"{self._get_run_number_string(cfg.get('run_number'))}_" if "run_number" in cfg else "",
|
|
196
|
+
f"za{round(zenith_angle):02}deg_" if isinstance(zenith_angle, (int, float)) else "",
|
|
197
|
+
f"azm{round(azimuth_angle):03}deg_" if isinstance(azimuth_angle, (int, float)) else "",
|
|
198
|
+
f"{cfg['site']}_" if cfg.get("site") else "",
|
|
199
|
+
f"{cfg['layout']}_" if cfg.get("layout") else "",
|
|
200
|
+
cfg.get("model_version", ""),
|
|
201
|
+
f"_{self.label}" if self.label else "",
|
|
202
|
+
]
|
|
203
|
+
return "".join(parts)
|
|
204
|
+
|
|
205
|
+
def _get_file_base_name_from_corsika_config(self, run_number, is_multi_pipe=False):
|
|
206
|
+
"""Get file base name from CORSIKA configuration."""
|
|
207
|
+
zenith = self.config.get_config_parameter("THETAP")[0]
|
|
208
|
+
vc_high = self.config.get_config_parameter("VIEWCONE")[1]
|
|
209
|
+
|
|
210
|
+
if self.config.run_mode is not None and self.config.run_mode != "":
|
|
211
|
+
primary_name = self.config.run_mode
|
|
212
|
+
else:
|
|
213
|
+
primary_name = self.config.primary_particle.name
|
|
214
|
+
if primary_name == "gamma" and vc_high > 0:
|
|
215
|
+
primary_name = "gamma_diffuse"
|
|
216
|
+
|
|
217
|
+
file_label = f"_{self.label}" if self.label else ""
|
|
218
|
+
run_number_string = self._get_run_number_string(run_number)
|
|
219
|
+
|
|
220
|
+
prefix = f"{primary_name}_{run_number_string}_" if primary_name else f"{run_number_string}_"
|
|
153
221
|
return (
|
|
154
222
|
prefix
|
|
155
|
-
+ f"za{round(zenith):02}
|
|
156
|
-
+ f"{
|
|
157
|
-
+ f"{
|
|
223
|
+
+ f"za{round(zenith):02}deg_"
|
|
224
|
+
+ f"azm{self.config.azimuth_angle:03}deg_"
|
|
225
|
+
+ f"{self.config.array_model.site}_"
|
|
226
|
+
+ f"{self.config.array_model.layout_name}_"
|
|
227
|
+
+ (self.config.array_model.model_version if not is_multi_pipe else "")
|
|
228
|
+
+ file_label
|
|
158
229
|
)
|
|
159
230
|
|
|
160
|
-
def
|
|
161
|
-
"""
|
|
162
|
-
Return path for log files.
|
|
163
|
-
|
|
164
|
-
Parameters
|
|
165
|
-
----------
|
|
166
|
-
file_type : str
|
|
167
|
-
File type.
|
|
168
|
-
file_name : str
|
|
169
|
-
File name.
|
|
170
|
-
|
|
171
|
-
Returns
|
|
172
|
-
-------
|
|
173
|
-
Path
|
|
174
|
-
Path for log files.
|
|
175
|
-
"""
|
|
176
|
-
log_suffixes = {
|
|
177
|
-
"log": ".log.gz",
|
|
178
|
-
"histogram": ".hdata.zst",
|
|
179
|
-
"corsika_log": ".corsika.log.gz",
|
|
180
|
-
}
|
|
181
|
-
return self.directory["logs"].joinpath(f"{file_name}{log_suffixes[file_type]}")
|
|
182
|
-
|
|
183
|
-
def _get_data_file_path(self, file_type, file_name, run_number):
|
|
231
|
+
def _get_sub_directory(self, run_number, dir_path):
|
|
184
232
|
"""
|
|
185
|
-
Return
|
|
233
|
+
Return sub directory with / without run number.
|
|
186
234
|
|
|
187
235
|
Parameters
|
|
188
236
|
----------
|
|
189
|
-
|
|
190
|
-
File type.
|
|
191
|
-
file_name : str
|
|
192
|
-
File name.
|
|
193
|
-
run_number : int
|
|
237
|
+
run_number: int
|
|
194
238
|
Run number.
|
|
239
|
+
dir_path: Path
|
|
240
|
+
Parent directory path.
|
|
195
241
|
|
|
196
242
|
Returns
|
|
197
243
|
-------
|
|
198
244
|
Path
|
|
199
|
-
|
|
200
|
-
"""
|
|
201
|
-
data_suffixes = {
|
|
202
|
-
"output": ".zst",
|
|
203
|
-
"corsika_output": ".corsika.zst",
|
|
204
|
-
"simtel_output": ".simtel.zst",
|
|
205
|
-
"event_data": ".reduced_event_data.hdf5",
|
|
206
|
-
}
|
|
207
|
-
run_dir = self._get_run_number_string(run_number)
|
|
208
|
-
data_run_dir = self.directory["data"].joinpath(run_dir)
|
|
209
|
-
data_run_dir.mkdir(parents=True, exist_ok=True)
|
|
210
|
-
return data_run_dir.joinpath(f"{file_name}{data_suffixes[file_type]}")
|
|
211
|
-
|
|
212
|
-
def _get_sub_file_path(self, file_type, file_name, mode):
|
|
245
|
+
Child directory path.
|
|
213
246
|
"""
|
|
214
|
-
|
|
247
|
+
sub_dir = dir_path / self._get_run_number_string(run_number)
|
|
248
|
+
sub_dir.mkdir(parents=True, exist_ok=True)
|
|
249
|
+
return sub_dir
|
|
215
250
|
|
|
216
|
-
|
|
217
|
-
----------
|
|
218
|
-
file_type : str
|
|
219
|
-
File type.
|
|
220
|
-
file_name : str
|
|
221
|
-
File name.
|
|
222
|
-
mode : str
|
|
223
|
-
Mode (out or err).
|
|
224
|
-
|
|
225
|
-
Returns
|
|
226
|
-
-------
|
|
227
|
-
Path
|
|
228
|
-
Path for submission files.
|
|
229
|
-
"""
|
|
230
|
-
suffix = ".log" if file_type == "sub_log" else ".sh"
|
|
231
|
-
if mode and mode != "":
|
|
232
|
-
suffix = f".{mode}"
|
|
233
|
-
sub_log_file_dir = self.directory["output"].joinpath(f"{file_type}s")
|
|
234
|
-
sub_log_file_dir.mkdir(parents=True, exist_ok=True)
|
|
235
|
-
return sub_log_file_dir.joinpath(f"sub_{file_name}{suffix}")
|
|
236
|
-
|
|
237
|
-
def get_file_name(
|
|
238
|
-
self,
|
|
239
|
-
file_type,
|
|
240
|
-
run_number=None,
|
|
241
|
-
mode=None,
|
|
242
|
-
calibration_run_mode=None,
|
|
243
|
-
_model_version_index=0,
|
|
244
|
-
): # pylint: disable=unused-argument
|
|
251
|
+
def get_file_name(self, file_type, run_number=None):
|
|
245
252
|
"""
|
|
246
|
-
Get a
|
|
253
|
+
Get a file name depending on file type and run number.
|
|
247
254
|
|
|
248
255
|
Parameters
|
|
249
256
|
----------
|
|
@@ -251,15 +258,6 @@ class RunnerServices:
|
|
|
251
258
|
The type of file (determines the file suffix).
|
|
252
259
|
run_number : int
|
|
253
260
|
Run number.
|
|
254
|
-
mode: str
|
|
255
|
-
out or err (optional, relevant only for sub_log).
|
|
256
|
-
calibration_run_mode: str
|
|
257
|
-
Calibration run mode.
|
|
258
|
-
model_version_index: int
|
|
259
|
-
Index of the model version.
|
|
260
|
-
This is not used here, but in other implementations of this function is
|
|
261
|
-
used to select the correct simulator_array instance in case
|
|
262
|
-
multiple array models are simulated.
|
|
263
261
|
|
|
264
262
|
Returns
|
|
265
263
|
-------
|
|
@@ -271,23 +269,23 @@ class RunnerServices:
|
|
|
271
269
|
ValueError
|
|
272
270
|
If file_type is unknown.
|
|
273
271
|
"""
|
|
274
|
-
file_name = self._get_file_basename(run_number,
|
|
275
|
-
|
|
276
|
-
if file_type in ["log", "histogram", "corsika_log"]:
|
|
277
|
-
return self._get_log_file_path(file_type, file_name)
|
|
278
|
-
|
|
279
|
-
if file_type in ["output", "corsika_output", "simtel_output", "event_data"]:
|
|
280
|
-
return self._get_data_file_path(file_type, file_name, run_number)
|
|
272
|
+
file_name = self._get_file_basename(run_number, file_type.startswith("multi_pipe"))
|
|
281
273
|
|
|
282
|
-
|
|
283
|
-
|
|
274
|
+
try:
|
|
275
|
+
desc = FILES_AND_PATHS[file_type]
|
|
276
|
+
except KeyError as exc:
|
|
277
|
+
raise ValueError(f"Unknown file type: {file_type}") from exc
|
|
284
278
|
|
|
285
|
-
|
|
279
|
+
if desc["sub_dir_type"] == "run_number":
|
|
280
|
+
dir_path = self._get_sub_directory(run_number, self.directory)
|
|
281
|
+
else:
|
|
282
|
+
dir_path = self.directory
|
|
283
|
+
return dir_path / f"{file_name}{desc['suffix']}"
|
|
286
284
|
|
|
287
285
|
@staticmethod
|
|
288
286
|
def _get_run_number_string(run_number):
|
|
289
287
|
"""
|
|
290
|
-
Get run number string as used for the simulation file names(ex. run000014).
|
|
288
|
+
Get run number string as used for the simulation file names (ex. run000014).
|
|
291
289
|
|
|
292
290
|
Parameters
|
|
293
291
|
----------
|
|
@@ -299,37 +297,40 @@ class RunnerServices:
|
|
|
299
297
|
str
|
|
300
298
|
Run number string.
|
|
301
299
|
"""
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
return "run" + nn.zfill(6)
|
|
300
|
+
if run_number is None:
|
|
301
|
+
return ""
|
|
302
|
+
return f"run{validate_corsika_run_number(run_number):06d}"
|
|
306
303
|
|
|
307
|
-
def get_resources(self,
|
|
304
|
+
def get_resources(self, sub_out_file):
|
|
308
305
|
"""
|
|
309
306
|
Read run time of job from last line of submission log file.
|
|
310
307
|
|
|
311
308
|
Parameters
|
|
312
309
|
----------
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
sub_out_file: str or Path
|
|
311
|
+
Path to the submission output file.
|
|
315
312
|
|
|
316
313
|
Returns
|
|
317
314
|
-------
|
|
318
315
|
dict
|
|
319
316
|
run time and number of simulated events
|
|
320
317
|
"""
|
|
321
|
-
|
|
322
|
-
_logger.debug(f"Reading resources from {sub_log_file}")
|
|
318
|
+
_logger.debug(f"Reading resources from {sub_out_file}")
|
|
323
319
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
for line in reversed(list(file)):
|
|
320
|
+
runtime = None
|
|
321
|
+
with open(sub_out_file, encoding="utf-8") as f:
|
|
322
|
+
for line in reversed(f.readlines()):
|
|
328
323
|
if "RUNTIME" in line:
|
|
329
|
-
|
|
324
|
+
runtime = int(line.split()[1])
|
|
330
325
|
break
|
|
331
326
|
|
|
332
|
-
if
|
|
327
|
+
if runtime is None:
|
|
333
328
|
_logger.debug("RUNTIME was not found in run log file")
|
|
334
|
-
|
|
335
|
-
|
|
329
|
+
|
|
330
|
+
if isinstance(self.config, CorsikaConfig):
|
|
331
|
+
return {
|
|
332
|
+
"runtime": runtime,
|
|
333
|
+
"n_events": int(self.config.get_config_parameter("NSHOW")),
|
|
334
|
+
}
|
|
335
|
+
self._logger.warning("Number of events cannot be determined from non-CORSIKA config.")
|
|
336
|
+
return {"runtime": runtime, "n_events": None}
|