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
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
3
|
r"""
|
|
4
|
-
|
|
4
|
+
Derive CORSIKA configuration limits for energy, core distance, and viewcone radius.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
This tool determines configuration limits based on triggered events from broad-range
|
|
7
|
+
simulations. It supports setting:
|
|
8
|
+
|
|
9
|
+
- **ERANGE**: Derives the lower energy limit; upper limit is user-defined.
|
|
10
|
+
- **CSCAT**: Derives the upper core distance; lower limit is user-defined.
|
|
11
|
+
- **VIEWCONE**: Derives the viewcone radius; lower limit is user-defined.
|
|
12
|
+
|
|
13
|
+
Limits are computed based on a configurable maximum event loss fraction.
|
|
14
|
+
Results are provided as a table with the following columns:
|
|
15
|
+
|
|
16
|
+
- particle_type: Particle type (e.g., gamma, proton, electron).
|
|
17
|
+
- telescope_ids: List of telescope IDs used in the simulation.
|
|
18
|
+
- zenith: Zenith angle.
|
|
19
|
+
- azimuth: Azimuth angle.
|
|
20
|
+
- nsb: Night sky background level
|
|
21
|
+
- layout: Layout of the telescope array used in the simulation.
|
|
22
|
+
- lower_energy_limit: Derived lower energy limit.
|
|
23
|
+
- upper_radius_limit: Derived upper radial distance limit.
|
|
24
|
+
- viewcone_radius: Derived upper viewcone radius limit.
|
|
25
|
+
|
|
26
|
+
The input event data files are generated using the application simtools-generate-simtel-event-data
|
|
27
|
+
and are required for each point in the lookup table.
|
|
7
28
|
|
|
8
29
|
Command line arguments
|
|
9
30
|
----------------------
|
|
10
31
|
event_data_files (str, required)
|
|
11
|
-
Path to a file containing event data
|
|
32
|
+
Path to a file containing event data files derived with 'simtools-generate-simtel-event-data'.
|
|
12
33
|
telescope_ids (str, required)
|
|
13
34
|
Path to a file containing telescope configurations.
|
|
14
35
|
loss_fraction (float, required)
|
|
15
|
-
|
|
36
|
+
Maximum event-loss fraction for limit computation.
|
|
16
37
|
plot_histograms (bool, optional)
|
|
17
38
|
Plot histograms of the event data.
|
|
18
39
|
output_file (str, optional)
|
|
@@ -32,46 +53,17 @@ Derive limits for a given file with a specified loss fraction.
|
|
|
32
53
|
--output_file corsika_simulation_limits_lookup.ecsv
|
|
33
54
|
"""
|
|
34
55
|
|
|
35
|
-
import datetime
|
|
36
56
|
import logging
|
|
37
|
-
import re
|
|
38
|
-
|
|
39
|
-
import numpy as np
|
|
40
|
-
from astropy.table import Table
|
|
41
57
|
|
|
42
58
|
import simtools.utils.general as gen
|
|
43
59
|
from simtools.configuration import configurator
|
|
44
|
-
from simtools.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
_logger = logging.getLogger(__name__)
|
|
60
|
+
from simtools.production_configuration.derive_corsika_limits_grid import (
|
|
61
|
+
generate_corsika_limits_grid,
|
|
62
|
+
)
|
|
49
63
|
|
|
50
64
|
|
|
51
65
|
def _parse():
|
|
52
|
-
"""
|
|
53
|
-
Parse command line configuration.
|
|
54
|
-
|
|
55
|
-
Parameters
|
|
56
|
-
----------
|
|
57
|
-
event_data_files: str
|
|
58
|
-
Path to a file listing event data file paths. These files contain the
|
|
59
|
-
simulation data used for deriving the limits.
|
|
60
|
-
loss_fraction: float
|
|
61
|
-
Fraction of events to be excluded during limit computation. Determines
|
|
62
|
-
thresholds for energy, radial distance, and viewcone.
|
|
63
|
-
telescope_ids: str
|
|
64
|
-
Path to a file defining telescope configurations. Specifies telescope
|
|
65
|
-
arrays or IDs used to filter events during processing.
|
|
66
|
-
plot_histograms: bool
|
|
67
|
-
If True, generates and saves histograms of the event data to visualize
|
|
68
|
-
the computed limits and distributions.
|
|
69
|
-
|
|
70
|
-
Returns
|
|
71
|
-
-------
|
|
72
|
-
CommandLineParser
|
|
73
|
-
Command line parser object
|
|
74
|
-
"""
|
|
66
|
+
"""Parse command line configuration."""
|
|
75
67
|
config = configurator.Configurator(
|
|
76
68
|
description="Derive limits for energy, radial distance, and viewcone."
|
|
77
69
|
)
|
|
@@ -88,7 +80,10 @@ def _parse():
|
|
|
88
80
|
help="Path to a file containing telescope configurations.",
|
|
89
81
|
)
|
|
90
82
|
config.parser.add_argument(
|
|
91
|
-
"--loss_fraction",
|
|
83
|
+
"--loss_fraction",
|
|
84
|
+
type=float,
|
|
85
|
+
required=True,
|
|
86
|
+
help="Maximum event-loss fraction for limit computation.",
|
|
92
87
|
)
|
|
93
88
|
config.parser.add_argument(
|
|
94
89
|
"--plot_histograms",
|
|
@@ -96,161 +91,7 @@ def _parse():
|
|
|
96
91
|
action="store_true",
|
|
97
92
|
default=False,
|
|
98
93
|
)
|
|
99
|
-
config.
|
|
100
|
-
"--output_file",
|
|
101
|
-
type=str,
|
|
102
|
-
default="corsika_simulation_limits_lookup.ecsv",
|
|
103
|
-
help="Output file for the derived limits (default: "
|
|
104
|
-
"'corsika_simulation_limits_lookup.ecsv').",
|
|
105
|
-
)
|
|
106
|
-
return config.initialize(db_config=False)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def process_file(file_path, telescope_ids, loss_fraction, plot_histograms):
|
|
110
|
-
"""
|
|
111
|
-
Process a single file and compute limits.
|
|
112
|
-
|
|
113
|
-
Parameters
|
|
114
|
-
----------
|
|
115
|
-
file_path : str
|
|
116
|
-
Path to the event data file.
|
|
117
|
-
telescope_ids : list[int]
|
|
118
|
-
List of telescope IDs to filter the events.
|
|
119
|
-
loss_fraction : float
|
|
120
|
-
Fraction of events to be lost.
|
|
121
|
-
plot_histograms : bool
|
|
122
|
-
Whether to plot histograms.
|
|
123
|
-
|
|
124
|
-
Returns
|
|
125
|
-
-------
|
|
126
|
-
dict
|
|
127
|
-
Dictionary containing the computed limits and metadata.
|
|
128
|
-
"""
|
|
129
|
-
# Extract zenith and azimuth from the file path
|
|
130
|
-
match = re.search(r"za(\d+)deg.*azm(\d+)deg", file_path)
|
|
131
|
-
if not match:
|
|
132
|
-
raise ValueError(f"Could not extract zenith and azimuth from file path: {file_path}")
|
|
133
|
-
zenith = int(match.group(1))
|
|
134
|
-
azimuth = int(match.group(2))
|
|
135
|
-
|
|
136
|
-
if "dark" in file_path:
|
|
137
|
-
nsb = 1
|
|
138
|
-
elif "halfmoon" in file_path:
|
|
139
|
-
nsb = 5
|
|
140
|
-
elif "moon" in file_path:
|
|
141
|
-
nsb = 19
|
|
142
|
-
else:
|
|
143
|
-
_logger.warning(f"Could not determine NSB from file path: {file_path}")
|
|
144
|
-
nsb = None
|
|
145
|
-
|
|
146
|
-
if "gamma-diffuse" in file_path:
|
|
147
|
-
particle_type = "gamma-diffuse"
|
|
148
|
-
elif "gamma" in file_path:
|
|
149
|
-
particle_type = "gamma"
|
|
150
|
-
elif "proton" in file_path:
|
|
151
|
-
particle_type = "proton"
|
|
152
|
-
elif "electron" in file_path:
|
|
153
|
-
particle_type = "electron"
|
|
154
|
-
else:
|
|
155
|
-
_logger.warning(f"Could not determine particle type from file path: {file_path}")
|
|
156
|
-
particle_type = "unknown"
|
|
157
|
-
|
|
158
|
-
calculator = LimitCalculator(file_path, telescope_list=telescope_ids)
|
|
159
|
-
|
|
160
|
-
lower_energy_limit = calculator.compute_lower_energy_limit(loss_fraction)
|
|
161
|
-
upper_radial_distance = calculator.compute_upper_radial_distance(loss_fraction)
|
|
162
|
-
viewcone = calculator.compute_viewcone(loss_fraction)
|
|
163
|
-
|
|
164
|
-
if plot_histograms:
|
|
165
|
-
_logger.info(
|
|
166
|
-
f"Plotting histograms written to {io_handler.IOHandler().get_output_directory()}"
|
|
167
|
-
)
|
|
168
|
-
calculator.plot_data(
|
|
169
|
-
lower_energy_limit,
|
|
170
|
-
upper_radial_distance,
|
|
171
|
-
viewcone,
|
|
172
|
-
io_handler.IOHandler().get_output_directory(),
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
"particle_type": particle_type,
|
|
177
|
-
"telescope_ids": telescope_ids,
|
|
178
|
-
"zenith": zenith,
|
|
179
|
-
"azimuth": azimuth,
|
|
180
|
-
"nsb": nsb,
|
|
181
|
-
"lower_energy_threshold": lower_energy_limit,
|
|
182
|
-
"upper_radius_threshold": upper_radial_distance,
|
|
183
|
-
"viewcone_radius": viewcone,
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def create_results_table(results, loss_fraction):
|
|
188
|
-
"""
|
|
189
|
-
Create an Astropy Table from the results.
|
|
190
|
-
|
|
191
|
-
Parameters
|
|
192
|
-
----------
|
|
193
|
-
results : list[dict]
|
|
194
|
-
List of dictionaries containing the computed limits for each file
|
|
195
|
-
and telescope configuration.
|
|
196
|
-
loss_fraction : float
|
|
197
|
-
Fraction of events to be lost, added as metadata to the table.
|
|
198
|
-
|
|
199
|
-
Returns
|
|
200
|
-
-------
|
|
201
|
-
astropy.table.Table
|
|
202
|
-
An Astropy Table containing the results with appropriate units and metadata.
|
|
203
|
-
"""
|
|
204
|
-
print("results", results)
|
|
205
|
-
table = Table(
|
|
206
|
-
rows=[
|
|
207
|
-
(
|
|
208
|
-
res["particle_type"],
|
|
209
|
-
res["telescope_ids"],
|
|
210
|
-
res["zenith"],
|
|
211
|
-
res["azimuth"],
|
|
212
|
-
res["nsb"],
|
|
213
|
-
res["lower_energy_threshold"].value,
|
|
214
|
-
res["upper_radius_threshold"].value,
|
|
215
|
-
res["viewcone_radius"].value,
|
|
216
|
-
)
|
|
217
|
-
for res in results
|
|
218
|
-
],
|
|
219
|
-
names=[
|
|
220
|
-
"particle_type",
|
|
221
|
-
"telescope_ids",
|
|
222
|
-
"zenith",
|
|
223
|
-
"azimuth",
|
|
224
|
-
"nsb",
|
|
225
|
-
"lower_energy_threshold",
|
|
226
|
-
"upper_radius_threshold",
|
|
227
|
-
"viewcone_radius",
|
|
228
|
-
],
|
|
229
|
-
dtype=[
|
|
230
|
-
"S64",
|
|
231
|
-
object,
|
|
232
|
-
np.float64,
|
|
233
|
-
np.float64,
|
|
234
|
-
object,
|
|
235
|
-
np.float64,
|
|
236
|
-
np.float64,
|
|
237
|
-
np.float64,
|
|
238
|
-
],
|
|
239
|
-
)
|
|
240
|
-
table["zenith"].unit = "deg"
|
|
241
|
-
table["azimuth"].unit = "deg"
|
|
242
|
-
table["lower_energy_threshold"].unit = "TeV"
|
|
243
|
-
table["upper_radius_threshold"].unit = "m"
|
|
244
|
-
table["viewcone_radius"].unit = "deg"
|
|
245
|
-
|
|
246
|
-
table.meta["created"] = datetime.datetime.now().isoformat()
|
|
247
|
-
table.meta["description"] = (
|
|
248
|
-
"Lookup table for CORSIKA limits computed from gamma-ray shower simulations "
|
|
249
|
-
"using simtool production_derive_corsika_limits"
|
|
250
|
-
)
|
|
251
|
-
table.meta["loss_fraction"] = loss_fraction
|
|
252
|
-
|
|
253
|
-
return table
|
|
94
|
+
return config.initialize(db_config=False, output=True)
|
|
254
95
|
|
|
255
96
|
|
|
256
97
|
def main():
|
|
@@ -260,33 +101,7 @@ def main():
|
|
|
260
101
|
logger = logging.getLogger()
|
|
261
102
|
logger.setLevel(gen.get_log_level_from_user(args_dict.get("log_level", "info")))
|
|
262
103
|
|
|
263
|
-
|
|
264
|
-
telescope_configs = gen.collect_data_from_file(args_dict["telescope_ids"])["telescope_configs"]
|
|
265
|
-
|
|
266
|
-
results = []
|
|
267
|
-
for file_path in event_data_files:
|
|
268
|
-
for array_name, telescope_ids in telescope_configs.items():
|
|
269
|
-
_logger.info(f"Processing file: {file_path} with telescope config: {array_name}")
|
|
270
|
-
result = process_file(
|
|
271
|
-
file_path,
|
|
272
|
-
telescope_ids,
|
|
273
|
-
args_dict["loss_fraction"],
|
|
274
|
-
args_dict["plot_histograms"],
|
|
275
|
-
)
|
|
276
|
-
result["layout"] = array_name
|
|
277
|
-
results.append(result)
|
|
278
|
-
|
|
279
|
-
table = create_results_table(results, args_dict["loss_fraction"])
|
|
280
|
-
|
|
281
|
-
output_dir = io_handler.IOHandler().get_output_directory("corsika_limits")
|
|
282
|
-
output_file = f"{output_dir}/{args_dict['output_file']}"
|
|
283
|
-
|
|
284
|
-
table.write(output_file, format="ascii.ecsv", overwrite=True)
|
|
285
|
-
_logger.info(f"Results saved to {output_file}")
|
|
286
|
-
|
|
287
|
-
metadata_file = f"{output_dir}/metadata.yml"
|
|
288
|
-
MetadataCollector.dump(args_dict, metadata_file)
|
|
289
|
-
_logger.info(f"Metadata saved to {metadata_file}")
|
|
104
|
+
generate_corsika_limits_grid(args_dict)
|
|
290
105
|
|
|
291
106
|
|
|
292
107
|
if __name__ == "__main__":
|
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
3
|
r"""
|
|
4
|
-
|
|
4
|
+
Derive the required number of events for MC productions for a grid of observational conditions.
|
|
5
5
|
|
|
6
|
-
This application evaluates statistical uncertainties from
|
|
7
|
-
|
|
8
|
-
for
|
|
6
|
+
This application evaluates statistical uncertainties from the analysis of events after the
|
|
7
|
+
application of loose gamma/hadron separation cuts, then interpolates the derived number of required
|
|
8
|
+
events for the specified grid points provided in a file. The resulting grid points will have the
|
|
9
|
+
derived number of required events added.
|
|
10
|
+
|
|
11
|
+
The metric for the required uncertainty is pre-defined and must be configured via the metrics file.
|
|
9
12
|
|
|
10
13
|
Command line arguments
|
|
11
14
|
----------------------
|
|
12
|
-
|
|
13
|
-
Path to the
|
|
14
|
-
|
|
15
|
-
List of zenith angles to consider.
|
|
16
|
-
camera_offsets (list of int, required)
|
|
17
|
-
List of offsets in degrees.
|
|
18
|
-
query_point (list of float, required)
|
|
19
|
-
Query point for interpolation. The query point must contain exactly 5 values:
|
|
20
|
-
- Energy (TeV)
|
|
21
|
-
- Azimuth (degrees)
|
|
22
|
-
- Zenith (degrees)
|
|
23
|
-
- NSB (MHz)
|
|
24
|
-
- Offset (degrees)
|
|
25
|
-
output_file (str, optional)
|
|
26
|
-
Output file to store the results. Default: 'interpolated_production_statistics.json'.
|
|
15
|
+
grid_points_production_file (str, required)
|
|
16
|
+
Path to the file containing grid points. Each grid point should include azimuth, zenith, NSB,
|
|
17
|
+
offset.
|
|
27
18
|
metrics_file (str, optional)
|
|
28
19
|
Path to the metrics definition file. Default: 'production_simulation_config_metrics.yml'.
|
|
20
|
+
base_path (str, required)
|
|
21
|
+
Path to the directory containing the event files for interpolation (after loose gamma/hadron
|
|
22
|
+
cuts).
|
|
29
23
|
file_name_template (str, optional)
|
|
30
|
-
Template for the file name. Default:
|
|
24
|
+
Template for the event file name. Default:
|
|
31
25
|
'prod6_LaPalma-{zenith}deg_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits'.
|
|
26
|
+
plot_production_statistics (flag, optional)
|
|
27
|
+
If provided, plots the production statistics. Default: False.
|
|
32
28
|
|
|
33
29
|
Example
|
|
34
30
|
-------
|
|
@@ -36,22 +32,33 @@ To evaluate statistical uncertainties and perform interpolation, run the command
|
|
|
36
32
|
|
|
37
33
|
.. code-block:: console
|
|
38
34
|
|
|
39
|
-
simtools-production-derive-statistics
|
|
40
|
-
--
|
|
35
|
+
simtools-production-derive-statistics \\
|
|
36
|
+
--grid_points_production_file path/to/grid_points_production.json \\
|
|
41
37
|
--metrics_file "path/to/metrics.yaml" \\
|
|
42
|
-
--
|
|
43
|
-
--
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
--base_path path/to/production_event_files/ \\
|
|
39
|
+
--file_name_template "prod6_LaPalma-{zenith}deg\\
|
|
40
|
+
_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits" \\
|
|
41
|
+
--zeniths 20 40 52 60 \\
|
|
42
|
+
--offsets 0 \\
|
|
43
|
+
--azimuths 180 \\
|
|
44
|
+
--nsb 0.0 \\
|
|
45
|
+
--plot_production_statistics
|
|
46
|
+
|
|
47
|
+
Output
|
|
48
|
+
------
|
|
49
|
+
The output will be a file containing the grid points with the derived number of required events
|
|
50
|
+
added.
|
|
47
51
|
"""
|
|
48
52
|
|
|
53
|
+
import logging
|
|
49
54
|
from pathlib import Path
|
|
50
55
|
|
|
51
56
|
from simtools.configuration import configurator
|
|
57
|
+
from simtools.io_operations import io_handler
|
|
52
58
|
from simtools.production_configuration.derive_production_statistics_handler import (
|
|
53
59
|
ProductionStatisticsHandler,
|
|
54
60
|
)
|
|
61
|
+
from simtools.utils import general as gen
|
|
55
62
|
|
|
56
63
|
|
|
57
64
|
def _parse(label, description):
|
|
@@ -65,59 +72,86 @@ def _parse(label, description):
|
|
|
65
72
|
"""
|
|
66
73
|
config = configurator.Configurator(label=label, description=description)
|
|
67
74
|
|
|
75
|
+
config.parser.add_argument(
|
|
76
|
+
"--grid_points_production_file",
|
|
77
|
+
type=str,
|
|
78
|
+
required=True,
|
|
79
|
+
help="Path to the JSON file containing grid points for a production.",
|
|
80
|
+
)
|
|
81
|
+
config.parser.add_argument(
|
|
82
|
+
"--metrics_file",
|
|
83
|
+
required=True,
|
|
84
|
+
type=str,
|
|
85
|
+
default=None,
|
|
86
|
+
help="Metrics definition file. (default: production_simulation_config_metrics.yml)",
|
|
87
|
+
)
|
|
68
88
|
config.parser.add_argument(
|
|
69
89
|
"--base_path",
|
|
70
90
|
type=str,
|
|
71
91
|
required=True,
|
|
72
92
|
help="Path to the DL2 MC event files for interpolation.",
|
|
73
93
|
)
|
|
94
|
+
config.parser.add_argument(
|
|
95
|
+
"--file_name_template",
|
|
96
|
+
required=False,
|
|
97
|
+
type=str,
|
|
98
|
+
default=("prod6_LaPalma-{zenith}deg_gamma_cone.N.Am-4LSTs09MSTs_ID0_reduced.fits"),
|
|
99
|
+
help=("Template for the DL2 MC event file name."),
|
|
100
|
+
)
|
|
74
101
|
config.parser.add_argument(
|
|
75
102
|
"--zeniths",
|
|
76
103
|
required=True,
|
|
77
104
|
nargs="+",
|
|
78
105
|
type=float,
|
|
79
|
-
help="List of zenith angles.",
|
|
106
|
+
help="List of zenith angles in deg that describe the supplied DL2 files.",
|
|
80
107
|
)
|
|
81
108
|
config.parser.add_argument(
|
|
82
|
-
"--
|
|
109
|
+
"--azimuths",
|
|
83
110
|
required=True,
|
|
84
111
|
nargs="+",
|
|
85
112
|
type=float,
|
|
86
|
-
help="List of
|
|
113
|
+
help="List of azimuth angles in deg that describe the supplied DL2 files.",
|
|
87
114
|
)
|
|
88
115
|
config.parser.add_argument(
|
|
89
|
-
"--
|
|
116
|
+
"--nsb",
|
|
90
117
|
required=True,
|
|
91
|
-
nargs=
|
|
118
|
+
nargs="+",
|
|
92
119
|
type=float,
|
|
93
|
-
help="
|
|
120
|
+
help="List of nsb values that describe the supplied DL2 files.",
|
|
94
121
|
)
|
|
95
122
|
config.parser.add_argument(
|
|
96
|
-
"--
|
|
97
|
-
required=
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
help="
|
|
123
|
+
"--offsets",
|
|
124
|
+
required=True,
|
|
125
|
+
nargs="+",
|
|
126
|
+
type=float,
|
|
127
|
+
help="List of camera offsets in deg that describe the supplied DL2 files.",
|
|
101
128
|
)
|
|
102
129
|
config.parser.add_argument(
|
|
103
|
-
"--
|
|
130
|
+
"--plot_production_statistics",
|
|
104
131
|
required=False,
|
|
105
|
-
|
|
106
|
-
default=
|
|
107
|
-
help=
|
|
132
|
+
action="store_true",
|
|
133
|
+
default=False,
|
|
134
|
+
help="Plot production statistics.",
|
|
108
135
|
)
|
|
136
|
+
|
|
109
137
|
return config.initialize(db_config=False, output=True)
|
|
110
138
|
|
|
111
139
|
|
|
112
140
|
def main():
|
|
113
141
|
"""Run the ProductionStatisticsHandler."""
|
|
114
142
|
label = Path(__file__).stem
|
|
143
|
+
|
|
115
144
|
args_dict, _ = _parse(
|
|
116
145
|
label,
|
|
117
146
|
"Evaluate statistical uncertainties from DL2 MC event files and interpolate results.",
|
|
118
147
|
)
|
|
148
|
+
logger = logging.getLogger()
|
|
149
|
+
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
150
|
+
|
|
151
|
+
_io_handler = io_handler.IOHandler()
|
|
152
|
+
output_path = _io_handler.get_output_directory(label, sub_dir="")
|
|
119
153
|
|
|
120
|
-
manager = ProductionStatisticsHandler(args_dict)
|
|
154
|
+
manager = ProductionStatisticsHandler(args_dict, output_path=output_path)
|
|
121
155
|
manager.run()
|
|
122
156
|
|
|
123
157
|
|
|
@@ -115,6 +115,16 @@ def _parse(description=None):
|
|
|
115
115
|
required=False,
|
|
116
116
|
default=False,
|
|
117
117
|
)
|
|
118
|
+
config.parser.add_argument(
|
|
119
|
+
"--save_reduced_event_lists",
|
|
120
|
+
help=(
|
|
121
|
+
"Save reduced event lists with event data on simulated and triggered events. "
|
|
122
|
+
"Saved with the same name as the sim_telarray output file (different extension). "
|
|
123
|
+
),
|
|
124
|
+
action="store_true",
|
|
125
|
+
required=False,
|
|
126
|
+
default=False,
|
|
127
|
+
)
|
|
118
128
|
config.parser.add_argument(
|
|
119
129
|
"--corsika_test_seeds",
|
|
120
130
|
help="Use predefined random seeds for CORSIKA for testing purposes.",
|
|
@@ -122,6 +132,15 @@ def _parse(description=None):
|
|
|
122
132
|
required=False,
|
|
123
133
|
default=False,
|
|
124
134
|
)
|
|
135
|
+
config.parser.add_argument(
|
|
136
|
+
"--sequential",
|
|
137
|
+
help=(
|
|
138
|
+
"Enables single-core mode (as far as possible); "
|
|
139
|
+
"otherwise, CORSIKA and sim_telarray run in parallel."
|
|
140
|
+
),
|
|
141
|
+
action="store_true",
|
|
142
|
+
default=False,
|
|
143
|
+
)
|
|
125
144
|
sim_telarray_seed_group = config.parser.add_argument_group(
|
|
126
145
|
title="Random seeds for sim_telarray instrument setup",
|
|
127
146
|
)
|
|
@@ -144,7 +163,6 @@ def _parse(description=None):
|
|
|
144
163
|
)
|
|
145
164
|
return config.initialize(
|
|
146
165
|
db_config=True,
|
|
147
|
-
job_submission=True,
|
|
148
166
|
simulation_model=["site", "layout", "telescope", "model_version"],
|
|
149
167
|
simulation_configuration={"software": None, "corsika_configuration": ["all"]},
|
|
150
168
|
)
|
|
@@ -163,23 +181,17 @@ def main(): # noqa: D103
|
|
|
163
181
|
simulator.simulate()
|
|
164
182
|
simulator.validate_metadata()
|
|
165
183
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
logger.info("Production run submitted to the workload manager")
|
|
178
|
-
if args_dict["pack_for_grid_register"] or args_dict["save_file_lists"]:
|
|
179
|
-
logger.warning(
|
|
180
|
-
"Packing for grid register or saving file lists not supported for "
|
|
181
|
-
f"{simulator.submit_engine}."
|
|
182
|
-
)
|
|
184
|
+
logger.info(
|
|
185
|
+
f"Production run complete for primary {args_dict['primary']} showers "
|
|
186
|
+
f"from {args_dict['azimuth_angle']} azimuth and {args_dict['zenith_angle']} zenith "
|
|
187
|
+
f"at {args_dict['site']} site, using {args_dict['model_version']} model."
|
|
188
|
+
)
|
|
189
|
+
if args_dict["save_reduced_event_lists"]:
|
|
190
|
+
simulator.save_reduced_event_lists()
|
|
191
|
+
if args_dict.get("pack_for_grid_register"):
|
|
192
|
+
simulator.pack_for_register(args_dict["pack_for_grid_register"])
|
|
193
|
+
if args_dict["save_file_lists"]:
|
|
194
|
+
simulator.save_file_lists()
|
|
183
195
|
|
|
184
196
|
|
|
185
197
|
if __name__ == "__main__":
|
|
@@ -76,7 +76,6 @@ def _parse(description=None):
|
|
|
76
76
|
)
|
|
77
77
|
return config.initialize(
|
|
78
78
|
db_config=False,
|
|
79
|
-
job_submission=False,
|
|
80
79
|
simulation_model=["site", "layout", "telescope", "model_version"],
|
|
81
80
|
simulation_configuration={"software": None, "corsika_configuration": ["all"]},
|
|
82
81
|
)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
|
|
3
|
+
r"""
|
|
4
|
+
Submit array-layouts definition and corresponding metadata and validate list of telescopes.
|
|
5
|
+
|
|
6
|
+
Includes validation that all defined telescope exists.
|
|
7
|
+
|
|
8
|
+
Command line arguments
|
|
9
|
+
----------------------
|
|
10
|
+
array_layouts (str, required)
|
|
11
|
+
Array layouts file.
|
|
12
|
+
updated_parameter_version (str, optional)
|
|
13
|
+
Updated parameter version.
|
|
14
|
+
input_meta (str, optional)
|
|
15
|
+
Input meta data file(s) associated to input data (wildcards or list of files allowed).
|
|
16
|
+
model_version (str, required)
|
|
17
|
+
Model version.
|
|
18
|
+
|
|
19
|
+
Example
|
|
20
|
+
-------
|
|
21
|
+
|
|
22
|
+
Submit a new array layout dictionary:
|
|
23
|
+
|
|
24
|
+
.. code-block:: console
|
|
25
|
+
|
|
26
|
+
simtools-submit-array-layouts \
|
|
27
|
+
--array_layouts array_layouts.json \\
|
|
28
|
+
--model_version 6.0.0 \\
|
|
29
|
+
--updated_parameter_version 0.1.0 \\
|
|
30
|
+
--input_meta array_layouts.metadata.yml
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
import logging
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
|
|
38
|
+
import simtools.utils.general as gen
|
|
39
|
+
from simtools.configuration import configurator
|
|
40
|
+
from simtools.db import db_handler
|
|
41
|
+
from simtools.layout.array_layout_utils import validate_array_layouts_with_db, write_array_layouts
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _parse(label, description):
|
|
45
|
+
"""Parse command line configuration."""
|
|
46
|
+
config = configurator.Configurator(label=label, description=description)
|
|
47
|
+
|
|
48
|
+
config.parser.add_argument(
|
|
49
|
+
"--array_layouts",
|
|
50
|
+
type=str,
|
|
51
|
+
required=True,
|
|
52
|
+
help="Array layout dictionary file.",
|
|
53
|
+
)
|
|
54
|
+
config.parser.add_argument(
|
|
55
|
+
"--updated_parameter_version",
|
|
56
|
+
help="Updated parameter version.",
|
|
57
|
+
type=str,
|
|
58
|
+
required=False,
|
|
59
|
+
)
|
|
60
|
+
config.parser.add_argument(
|
|
61
|
+
"--input_meta",
|
|
62
|
+
help="meta data file(s) associated to input data (wildcards or list of files allowed)",
|
|
63
|
+
type=str,
|
|
64
|
+
nargs="+",
|
|
65
|
+
required=False,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return config.initialize(output=True, db_config=True, simulation_model=["model_version"])
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main(): # noqa: D103
|
|
72
|
+
args_dict, db_config = _parse(
|
|
73
|
+
label=Path(__file__).stem,
|
|
74
|
+
description="Submit and validate array layouts.",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
logger = logging.getLogger()
|
|
78
|
+
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
79
|
+
|
|
80
|
+
db = db_handler.DatabaseHandler(mongo_db_config=db_config)
|
|
81
|
+
|
|
82
|
+
array_layouts = validate_array_layouts_with_db(
|
|
83
|
+
production_table=db.read_production_table_from_mongo_db(
|
|
84
|
+
collection_name="telescopes", model_version=args_dict["model_version"]
|
|
85
|
+
),
|
|
86
|
+
array_layouts=gen.collect_data_from_file(args_dict["array_layouts"]),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
write_array_layouts(array_layouts=array_layouts, args_dict=args_dict, db_config=db_config)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
main()
|