gammasimtools 0.8.2__py3-none-any.whl → 0.9.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.8.2.dist-info → gammasimtools-0.9.0.dist-info}/METADATA +3 -3
- {gammasimtools-0.8.2.dist-info → gammasimtools-0.9.0.dist-info}/RECORD +64 -59
- {gammasimtools-0.8.2.dist-info → gammasimtools-0.9.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.8.2.dist-info → gammasimtools-0.9.0.dist-info}/entry_points.txt +2 -0
- simtools/_version.py +2 -2
- simtools/applications/convert_all_model_parameters_from_simtel.py +1 -1
- simtools/applications/convert_geo_coordinates_of_array_elements.py +8 -9
- simtools/applications/convert_model_parameter_from_simtel.py +1 -1
- simtools/applications/db_add_model_parameters_from_repository_to_db.py +2 -10
- simtools/applications/db_add_value_from_json_to_db.py +1 -9
- simtools/applications/db_get_array_layouts_from_db.py +3 -1
- simtools/applications/db_get_parameter_from_db.py +1 -1
- simtools/applications/derive_mirror_rnda.py +10 -1
- simtools/applications/derive_psf_parameters.py +1 -1
- simtools/applications/generate_array_config.py +1 -5
- simtools/applications/generate_regular_arrays.py +9 -6
- simtools/applications/plot_array_layout.py +3 -1
- simtools/applications/plot_tabular_data.py +84 -0
- simtools/applications/production_scale_events.py +1 -2
- simtools/applications/simulate_light_emission.py +2 -2
- simtools/applications/simulate_prod.py +24 -59
- simtools/applications/simulate_prod_htcondor_generator.py +95 -0
- simtools/applications/submit_data_from_external.py +1 -1
- simtools/applications/validate_camera_efficiency.py +1 -1
- simtools/applications/validate_camera_fov.py +3 -7
- simtools/applications/validate_cumulative_psf.py +3 -7
- simtools/applications/validate_file_using_schema.py +31 -21
- simtools/applications/validate_optics.py +3 -4
- simtools/camera_efficiency.py +1 -4
- simtools/configuration/commandline_parser.py +7 -13
- simtools/configuration/configurator.py +6 -19
- simtools/data_model/metadata_collector.py +18 -0
- simtools/data_model/metadata_model.py +18 -5
- simtools/data_model/model_data_writer.py +1 -1
- simtools/data_model/validate_data.py +67 -10
- simtools/db/db_handler.py +92 -315
- simtools/io_operations/legacy_data_handler.py +61 -0
- simtools/job_execution/htcondor_script_generator.py +133 -0
- simtools/job_execution/job_manager.py +77 -50
- simtools/model/camera.py +4 -2
- simtools/model/model_parameter.py +40 -10
- simtools/model/site_model.py +1 -1
- simtools/ray_tracing/mirror_panel_psf.py +47 -27
- simtools/runners/corsika_runner.py +14 -3
- simtools/runners/runner_services.py +3 -3
- simtools/runners/simtel_runner.py +27 -8
- simtools/schemas/integration_tests_config.metaschema.yml +15 -5
- simtools/schemas/model_parameter.metaschema.yml +90 -2
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +31 -1
- simtools/simtel/simtel_table_reader.py +410 -0
- simtools/simtel/simulator_camera_efficiency.py +6 -4
- simtools/simtel/simulator_light_emission.py +2 -2
- simtools/simtel/simulator_ray_tracing.py +1 -2
- simtools/simulator.py +80 -33
- simtools/testing/configuration.py +12 -8
- simtools/testing/helpers.py +5 -5
- simtools/testing/validate_output.py +26 -26
- simtools/utils/general.py +50 -3
- simtools/utils/names.py +2 -2
- simtools/utils/value_conversion.py +9 -1
- simtools/visualization/plot_tables.py +106 -0
- simtools/visualization/visualize.py +43 -5
- simtools/db/db_from_repo_handler.py +0 -106
- {gammasimtools-0.8.2.dist-info → gammasimtools-0.9.0.dist-info}/LICENSE +0 -0
- {gammasimtools-0.8.2.dist-info → gammasimtools-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
3
|
r"""
|
|
4
|
-
Generate simulation configuration and run simulations
|
|
4
|
+
Generate simulation configuration and run simulations.
|
|
5
5
|
|
|
6
6
|
Multipipe scripts will be produced as part of this application.
|
|
7
7
|
Allows to run array layout simulation including shower and detector simulations
|
|
@@ -43,9 +43,9 @@ r"""
|
|
|
43
43
|
The location of the output directories corsika-data and simtel-data.
|
|
44
44
|
the label is added to the data_directory, such that the output
|
|
45
45
|
will be written to data_directory/label/simtel-data.
|
|
46
|
-
pack_for_grid_register (
|
|
46
|
+
pack_for_grid_register (str, optional)
|
|
47
47
|
Set whether to prepare a tarball for registering the output files on the grid.
|
|
48
|
-
The files are written to the
|
|
48
|
+
The files are written to the specified directory.
|
|
49
49
|
log_level (str, optional)
|
|
50
50
|
Log level to print.
|
|
51
51
|
|
|
@@ -68,9 +68,6 @@ r"""
|
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
70
|
import logging
|
|
71
|
-
import shutil
|
|
72
|
-
import tarfile
|
|
73
|
-
from pathlib import Path
|
|
74
71
|
|
|
75
72
|
import simtools.utils.general as gen
|
|
76
73
|
from simtools.configuration import configurator
|
|
@@ -106,10 +103,10 @@ def _parse(description=None):
|
|
|
106
103
|
)
|
|
107
104
|
config.parser.add_argument(
|
|
108
105
|
"--pack_for_grid_register",
|
|
109
|
-
help="
|
|
110
|
-
|
|
106
|
+
help="Directory for a tarball for registering the output files on the grid.",
|
|
107
|
+
type=str,
|
|
111
108
|
required=False,
|
|
112
|
-
default=
|
|
109
|
+
default=None,
|
|
113
110
|
)
|
|
114
111
|
config.parser.add_argument(
|
|
115
112
|
"--save_file_lists",
|
|
@@ -137,49 +134,11 @@ def _parse(description=None):
|
|
|
137
134
|
return config.initialize(
|
|
138
135
|
db_config=True,
|
|
139
136
|
job_submission=True,
|
|
140
|
-
simulation_model=["site", "layout", "telescope"],
|
|
137
|
+
simulation_model=["site", "layout", "telescope", "model_version"],
|
|
141
138
|
simulation_configuration={"software": None, "corsika_configuration": ["all"]},
|
|
142
139
|
)
|
|
143
140
|
|
|
144
141
|
|
|
145
|
-
def pack_for_register(logger, simulator, args_dict):
|
|
146
|
-
"""
|
|
147
|
-
Pack the output files for registering on the grid.
|
|
148
|
-
|
|
149
|
-
Parameters
|
|
150
|
-
----------
|
|
151
|
-
logger: logging.Logger
|
|
152
|
-
Logger object.
|
|
153
|
-
simulator: Simulator
|
|
154
|
-
Simulator object.
|
|
155
|
-
|
|
156
|
-
"""
|
|
157
|
-
logger.info("Packing the output files for registering on the grid")
|
|
158
|
-
output_files = simulator.get_file_list(file_type="output")
|
|
159
|
-
log_files = simulator.get_file_list(file_type="log")
|
|
160
|
-
histogram_files = simulator.get_file_list(file_type="hist")
|
|
161
|
-
tar_file_name = Path(log_files[0]).name.replace("log.gz", "log_hist.tar.gz")
|
|
162
|
-
directory_for_grid_upload = Path(args_dict.get("output_path")).joinpath(
|
|
163
|
-
"directory_for_grid_upload"
|
|
164
|
-
)
|
|
165
|
-
directory_for_grid_upload.mkdir(parents=True, exist_ok=True)
|
|
166
|
-
tar_file_name = directory_for_grid_upload.joinpath(tar_file_name)
|
|
167
|
-
|
|
168
|
-
with tarfile.open(tar_file_name, "w:gz") as tar:
|
|
169
|
-
files_to_tar = log_files[:1] + histogram_files[:1]
|
|
170
|
-
for file_to_tar in files_to_tar:
|
|
171
|
-
tar.add(file_to_tar, arcname=Path(file_to_tar).name)
|
|
172
|
-
|
|
173
|
-
for file_to_move in [*output_files]:
|
|
174
|
-
source_file = Path(file_to_move)
|
|
175
|
-
destination_file = directory_for_grid_upload / source_file.name
|
|
176
|
-
# Note that this will overwrite previous files which exist in the directory
|
|
177
|
-
# It should be fine for normal production since each run is on a separate node
|
|
178
|
-
# so no files are expected there.
|
|
179
|
-
shutil.move(source_file, destination_file)
|
|
180
|
-
logger.info(f"Output files for the grid placed in {directory_for_grid_upload!s}")
|
|
181
|
-
|
|
182
|
-
|
|
183
142
|
def main(): # noqa: D103
|
|
184
143
|
args_dict, db_config = _parse(description="Run simulations for productions")
|
|
185
144
|
|
|
@@ -192,17 +151,23 @@ def main(): # noqa: D103
|
|
|
192
151
|
|
|
193
152
|
simulator.simulate()
|
|
194
153
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
154
|
+
if simulator.submit_engine == "local":
|
|
155
|
+
logger.info(
|
|
156
|
+
f"Production run complete for primary {args_dict['primary']} showers "
|
|
157
|
+
f"from {args_dict['azimuth_angle']} azimuth and {args_dict['zenith_angle']} zenith "
|
|
158
|
+
f"at {args_dict['site']} site, using {args_dict['model_version']} model."
|
|
159
|
+
)
|
|
160
|
+
if args_dict.get("pack_for_grid_register"):
|
|
161
|
+
simulator.pack_for_register(args_dict["pack_for_grid_register"])
|
|
162
|
+
if args_dict["save_file_lists"]:
|
|
163
|
+
simulator.save_file_lists()
|
|
164
|
+
else:
|
|
165
|
+
logger.info("Production run submitted to the workload manager")
|
|
166
|
+
if args_dict["pack_for_grid_register"] or args_dict["save_file_lists"]:
|
|
167
|
+
logger.warning(
|
|
168
|
+
"Packing for grid register or saving file lists not supported for "
|
|
169
|
+
f"{simulator.submit_engine}."
|
|
170
|
+
)
|
|
206
171
|
|
|
207
172
|
|
|
208
173
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
|
|
3
|
+
r"""
|
|
4
|
+
Generate a run script and submit file for HT Condor job submission of a simulation production.
|
|
5
|
+
|
|
6
|
+
This tool facilitates the submission of multiple simulations to the HT Condor batch system,
|
|
7
|
+
enabling:
|
|
8
|
+
|
|
9
|
+
- Execution of simulations using the "simtools-simulate-prod" application.
|
|
10
|
+
- 'number_of_runs' jobs are submitted to the HT Condor batch system.
|
|
11
|
+
- Utilization of an Apptainer image containing the SimPipe simulation software and tools.
|
|
12
|
+
- Packaging of data and histogram files, and writing them to a specified directory.
|
|
13
|
+
|
|
14
|
+
This tool is intended for use in an HT Condor environment. Jobs run in a container universe
|
|
15
|
+
using the Apptainer image specified in the command line ('--apptainer_image'). Output is written
|
|
16
|
+
to the 'output_path' directory, with 'simtools-output' and 'logs' subdirectories.
|
|
17
|
+
|
|
18
|
+
Requirements for the 'simtools-simulate-prod-htcondor-generator' application:
|
|
19
|
+
|
|
20
|
+
- Availability of an Apptainer image 'simtools-prod' (obtainable from the package registry on
|
|
21
|
+
GitHub, e.g., via 'apptainer pull --force docker://ghcr.io/gammasim/simtools-prod:latest').
|
|
22
|
+
- Environment parameters required to run CORSIKA and sim_telarray, as well as DB access
|
|
23
|
+
credentials. These should be listed similarly to a '.env' file and copied to
|
|
24
|
+
'output_path/env.txt'. Ensure that the path to the simulation software is correctly set to
|
|
25
|
+
'SIMTOOLS_SIMTEL_PATH=/workdir/sim_telarray'.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Command line arguments
|
|
29
|
+
----------------------
|
|
30
|
+
output_path (str, required)
|
|
31
|
+
Directory where the output and the simulation data files will be written.
|
|
32
|
+
apptainer_image (str, optional)
|
|
33
|
+
Apptainer image to use for the simulation (full path).
|
|
34
|
+
priority (int, optional)
|
|
35
|
+
Job priority (default: 1).
|
|
36
|
+
|
|
37
|
+
(all other command line arguments are identical to those of :ref:`simulate_prod`).
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
import logging
|
|
42
|
+
|
|
43
|
+
import simtools.utils.general as gen
|
|
44
|
+
from simtools.configuration import configurator
|
|
45
|
+
from simtools.job_execution import htcondor_script_generator
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _parse(description=None):
|
|
49
|
+
"""
|
|
50
|
+
Parse command line configuration.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
description: str
|
|
55
|
+
Application description.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
CommandLineParser
|
|
60
|
+
Command line parser object.
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
config = configurator.Configurator(description=description)
|
|
64
|
+
config.parser.add_argument(
|
|
65
|
+
"--apptainer_image",
|
|
66
|
+
help="Apptainer image to use for the simulation (full path).",
|
|
67
|
+
type=str,
|
|
68
|
+
required=False,
|
|
69
|
+
)
|
|
70
|
+
config.parser.add_argument(
|
|
71
|
+
"--priority",
|
|
72
|
+
help="Job priority.",
|
|
73
|
+
type=int,
|
|
74
|
+
required=False,
|
|
75
|
+
default=1,
|
|
76
|
+
)
|
|
77
|
+
return config.initialize(
|
|
78
|
+
db_config=False,
|
|
79
|
+
job_submission=False,
|
|
80
|
+
simulation_model=["site", "layout", "telescope", "model_version"],
|
|
81
|
+
simulation_configuration={"software": None, "corsika_configuration": ["all"]},
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def main(): # noqa: D103
|
|
86
|
+
args_dict, _ = _parse(description="Prepare simulations production for HT Condor job submission")
|
|
87
|
+
|
|
88
|
+
logger = logging.getLogger()
|
|
89
|
+
logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
|
|
90
|
+
|
|
91
|
+
htcondor_script_generator.generate_submission_script(args_dict)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
main()
|
|
@@ -86,7 +86,7 @@ def _parse(label):
|
|
|
86
86
|
)
|
|
87
87
|
_args_dict, _db_config = config.initialize(
|
|
88
88
|
db_config=True,
|
|
89
|
-
simulation_model="telescope",
|
|
89
|
+
simulation_model=["telescope", "model_version"],
|
|
90
90
|
simulation_configuration={"corsika_configuration": ["zenith_angle", "azimuth_angle"]},
|
|
91
91
|
)
|
|
92
92
|
if _args_dict["site"] is None or _args_dict["telescope"] is None:
|
|
@@ -54,7 +54,7 @@ import simtools.utils.general as gen
|
|
|
54
54
|
from simtools.configuration import configurator
|
|
55
55
|
from simtools.io_operations import io_handler
|
|
56
56
|
from simtools.model.telescope_model import TelescopeModel
|
|
57
|
-
from simtools.visualization import plot_camera
|
|
57
|
+
from simtools.visualization import plot_camera, visualize
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
def _parse():
|
|
@@ -83,7 +83,7 @@ def _parse():
|
|
|
83
83
|
),
|
|
84
84
|
default=50,
|
|
85
85
|
)
|
|
86
|
-
return config.initialize(db_config=True, simulation_model="telescope")
|
|
86
|
+
return config.initialize(db_config=True, simulation_model=["telescope", "model_version"])
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def main(): # noqa: D103
|
|
@@ -133,11 +133,7 @@ def main(): # noqa: D103
|
|
|
133
133
|
) from exc
|
|
134
134
|
fig = plot_camera.plot_pixel_layout(camera, args_dict["camera_in_sky_coor"], pixel_ids_to_print)
|
|
135
135
|
plot_file_prefix = output_dir.joinpath(f"{label}_{tel_model.name}_pixel_layout")
|
|
136
|
-
|
|
137
|
-
file_name = f"{plot_file_prefix!s}.{suffix}"
|
|
138
|
-
fig.savefig(file_name, format=suffix, bbox_inches="tight")
|
|
139
|
-
print(f"\nSaved camera plot in {file_name}\n")
|
|
140
|
-
fig.clf()
|
|
136
|
+
visualize.save_figure(fig, f"{plot_file_prefix!s}", log_title="camera")
|
|
141
137
|
|
|
142
138
|
|
|
143
139
|
if __name__ == "__main__":
|
|
@@ -110,7 +110,7 @@ def _parse(label):
|
|
|
110
110
|
help="Data file name with the measured PSF vs radius [cm]",
|
|
111
111
|
type=str,
|
|
112
112
|
)
|
|
113
|
-
return config.initialize(db_config=True, simulation_model="telescope")
|
|
113
|
+
return config.initialize(db_config=True, simulation_model=["telescope", "model_version"])
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
def load_data(datafile):
|
|
@@ -182,9 +182,7 @@ def main(): # noqa: D103
|
|
|
182
182
|
|
|
183
183
|
plot_file_name = label + "_" + tel_model.name + "_cumulative_PSF"
|
|
184
184
|
plot_file = output_dir.joinpath(plot_file_name)
|
|
185
|
-
|
|
186
|
-
plt.savefig(str(plot_file) + "." + f, format=f, bbox_inches="tight")
|
|
187
|
-
fig.clf()
|
|
185
|
+
visualize.save_figure(fig, plot_file)
|
|
188
186
|
|
|
189
187
|
# Plotting image
|
|
190
188
|
data_to_plot = im.get_image_data()
|
|
@@ -195,9 +193,7 @@ def main(): # noqa: D103
|
|
|
195
193
|
|
|
196
194
|
plot_file_name = label + "_" + tel_model.name + "_image"
|
|
197
195
|
plot_file = output_dir.joinpath(plot_file_name)
|
|
198
|
-
|
|
199
|
-
fig.savefig(str(plot_file) + "." + f, format=f, bbox_inches="tight")
|
|
200
|
-
fig.clf()
|
|
196
|
+
visualize.save_figure(fig, plot_file)
|
|
201
197
|
|
|
202
198
|
|
|
203
199
|
if __name__ == "__main__":
|
|
@@ -33,11 +33,14 @@ r"""
|
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
35
|
import logging
|
|
36
|
-
|
|
36
|
+
import re
|
|
37
37
|
from pathlib import Path
|
|
38
38
|
|
|
39
|
+
import jsonschema
|
|
40
|
+
|
|
39
41
|
import simtools.utils.general as gen
|
|
40
42
|
from simtools.configuration import configurator
|
|
43
|
+
from simtools.constants import MODEL_PARAMETER_SCHEMA_PATH
|
|
41
44
|
from simtools.data_model import metadata_collector, metadata_model, validate_data
|
|
42
45
|
|
|
43
46
|
|
|
@@ -62,13 +65,12 @@ def _parse(label, description):
|
|
|
62
65
|
group = config.parser.add_mutually_exclusive_group(required=True)
|
|
63
66
|
group.add_argument("--file_name", help="File to be validated")
|
|
64
67
|
group.add_argument(
|
|
65
|
-
"--
|
|
68
|
+
"--file_directory",
|
|
66
69
|
help=(
|
|
67
|
-
"Directory with json files
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"and data_type=model_parameter is always used."
|
|
70
|
+
"Directory with json files to be validated. "
|
|
71
|
+
"If no schema file is provided, the assumption is that model "
|
|
72
|
+
"parameters are validated and the schema files are taken from "
|
|
73
|
+
f"{MODEL_PARAMETER_SCHEMA_PATH}."
|
|
72
74
|
),
|
|
73
75
|
)
|
|
74
76
|
config.parser.add_argument("--schema", help="Json schema file", required=False)
|
|
@@ -116,31 +118,39 @@ def _get_schema_file_name(args_dict, data_dict=None):
|
|
|
116
118
|
|
|
117
119
|
def validate_schema(args_dict, logger):
|
|
118
120
|
"""
|
|
119
|
-
Validate a schema file given in yaml or json format.
|
|
121
|
+
Validate a schema file (or several files) given in yaml or json format.
|
|
120
122
|
|
|
121
123
|
Schema is either given as command line argument, read from the meta_schema_url or from
|
|
122
124
|
the metadata section of the data dictionary.
|
|
123
125
|
|
|
124
126
|
"""
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
if args_dict.get("file_directory") is not None:
|
|
128
|
+
file_list = list(Path(args_dict["file_directory"]).rglob("*.json"))
|
|
129
|
+
else:
|
|
130
|
+
file_list = [args_dict["file_name"]]
|
|
131
|
+
for file_name in file_list:
|
|
132
|
+
try:
|
|
133
|
+
data = gen.collect_data_from_file(file_name=file_name)
|
|
134
|
+
except FileNotFoundError as exc:
|
|
135
|
+
logger.error(f"Error reading schema file from {file_name}")
|
|
136
|
+
raise exc
|
|
137
|
+
try:
|
|
138
|
+
metadata_model.validate_schema(data, _get_schema_file_name(args_dict, data))
|
|
139
|
+
except jsonschema.exceptions.ValidationError as exc:
|
|
140
|
+
logger.error(f"Failed validation of file {file_name}")
|
|
141
|
+
raise exc
|
|
142
|
+
logger.info(f"Successful validation of file {file_name}")
|
|
132
143
|
|
|
133
144
|
|
|
134
145
|
def validate_data_files(args_dict, logger):
|
|
135
146
|
"""Validate data files."""
|
|
136
|
-
|
|
137
|
-
if
|
|
147
|
+
file_directory = args_dict.get("file_directory")
|
|
148
|
+
if file_directory is not None:
|
|
138
149
|
tmp_args_dict = {}
|
|
139
|
-
for file_name in Path(
|
|
150
|
+
for file_name in Path(file_directory).rglob("*.json"):
|
|
140
151
|
tmp_args_dict["file_name"] = file_name
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)
|
|
152
|
+
parameter_name = re.sub(r"-\d+\.\d+\.\d+", "", file_name.stem)
|
|
153
|
+
schema_file = MODEL_PARAMETER_SCHEMA_PATH / f"{parameter_name}.schema.yml"
|
|
144
154
|
tmp_args_dict["schema"] = schema_file
|
|
145
155
|
tmp_args_dict["data_type"] = "model_parameter"
|
|
146
156
|
tmp_args_dict["require_exact_data_type"] = args_dict["require_exact_data_type"]
|
|
@@ -78,6 +78,7 @@ from simtools.configuration import configurator
|
|
|
78
78
|
from simtools.io_operations import io_handler
|
|
79
79
|
from simtools.model.telescope_model import TelescopeModel
|
|
80
80
|
from simtools.ray_tracing.ray_tracing import RayTracing
|
|
81
|
+
from simtools.visualization import visualize
|
|
81
82
|
|
|
82
83
|
|
|
83
84
|
def _parse(label):
|
|
@@ -114,7 +115,7 @@ def _parse(label):
|
|
|
114
115
|
help="Produce a multiple pages pdf file with the image plots.",
|
|
115
116
|
action="store_true",
|
|
116
117
|
)
|
|
117
|
-
return config.initialize(db_config=True, simulation_model=["telescope"])
|
|
118
|
+
return config.initialize(db_config=True, simulation_model=["telescope", "model_version"])
|
|
118
119
|
|
|
119
120
|
|
|
120
121
|
def main(): # noqa: D103
|
|
@@ -171,9 +172,7 @@ def main(): # noqa: D103
|
|
|
171
172
|
|
|
172
173
|
plot_file_name = "_".join((label, tel_model.name, key))
|
|
173
174
|
plot_file = output_dir.joinpath(plot_file_name)
|
|
174
|
-
|
|
175
|
-
plt.savefig(str(plot_file) + ".png", format="png", bbox_inches="tight")
|
|
176
|
-
plt.clf()
|
|
175
|
+
visualize.save_figure(plt, plot_file)
|
|
177
176
|
|
|
178
177
|
# Plotting images
|
|
179
178
|
if args_dict["plot_images"]:
|
simtools/camera_efficiency.py
CHANGED
|
@@ -514,7 +514,4 @@ class CameraEfficiency:
|
|
|
514
514
|
plot_file = self.output_dir.joinpath(
|
|
515
515
|
self.label + "_" + self.telescope_model.name + "_" + plot_title
|
|
516
516
|
)
|
|
517
|
-
|
|
518
|
-
fig.savefig(str(plot_file) + "." + f, format=f, bbox_inches="tight")
|
|
519
|
-
self._logger.info(f"Plotted {plot_title} efficiency in {plot_file}")
|
|
520
|
-
fig.clf()
|
|
517
|
+
visualize.save_figure(fig, plot_file, log_title=f"{plot_title} efficiency")
|
|
@@ -198,13 +198,6 @@ class CommandLineParser(argparse.ArgumentParser):
|
|
|
198
198
|
required=False,
|
|
199
199
|
default=None,
|
|
200
200
|
)
|
|
201
|
-
_job_group.add_argument(
|
|
202
|
-
"--db_simulation_model_url",
|
|
203
|
-
help="simulation model repository URL",
|
|
204
|
-
type=str,
|
|
205
|
-
required=False,
|
|
206
|
-
default=None,
|
|
207
|
-
)
|
|
208
201
|
|
|
209
202
|
def initialize_job_submission_arguments(self):
|
|
210
203
|
"""Initialize job submission arguments for simulator."""
|
|
@@ -243,12 +236,13 @@ class CommandLineParser(argparse.ArgumentParser):
|
|
|
243
236
|
return
|
|
244
237
|
|
|
245
238
|
_job_group = self.add_argument_group("simulation model")
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
239
|
+
if "model_version" in model_options:
|
|
240
|
+
_job_group.add_argument(
|
|
241
|
+
"--model_version",
|
|
242
|
+
help="model version",
|
|
243
|
+
type=str,
|
|
244
|
+
default=None,
|
|
245
|
+
)
|
|
252
246
|
if any(
|
|
253
247
|
option in model_options for option in ["site", "telescope", "layout", "layout_file"]
|
|
254
248
|
):
|
|
@@ -10,6 +10,7 @@ import astropy.units as u
|
|
|
10
10
|
from dotenv import load_dotenv
|
|
11
11
|
|
|
12
12
|
import simtools.configuration.commandline_parser as argparser
|
|
13
|
+
from simtools.db.db_handler import jsonschema_db_dict
|
|
13
14
|
from simtools.io_operations import io_handler
|
|
14
15
|
from simtools.utils import general as gen
|
|
15
16
|
|
|
@@ -438,24 +439,10 @@ class Configurator:
|
|
|
438
439
|
"""
|
|
439
440
|
Return parameters for DB configuration.
|
|
440
441
|
|
|
441
|
-
|
|
442
|
-
|
|
442
|
+
Returns
|
|
443
|
+
-------
|
|
443
444
|
dict
|
|
444
|
-
Dictionary with DB parameters
|
|
445
|
+
Dictionary with DB parameters.
|
|
445
446
|
"""
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
"db_api_user",
|
|
449
|
-
"db_api_pw",
|
|
450
|
-
"db_api_port",
|
|
451
|
-
"db_server",
|
|
452
|
-
"db_simulation_model",
|
|
453
|
-
"db_simulation_model_url",
|
|
454
|
-
)
|
|
455
|
-
try:
|
|
456
|
-
for _para in _db_para:
|
|
457
|
-
_db_dict[_para] = self.config[_para]
|
|
458
|
-
except KeyError:
|
|
459
|
-
pass
|
|
460
|
-
|
|
461
|
-
return _db_dict
|
|
447
|
+
db_params = jsonschema_db_dict["properties"].keys()
|
|
448
|
+
return {param: self.config.get(param) for param in db_params if param in self.config}
|
|
@@ -86,6 +86,24 @@ class MetadataCollector:
|
|
|
86
86
|
except AttributeError:
|
|
87
87
|
self._logger.debug(f"Method _fill_{meta_type}_meta not implemented")
|
|
88
88
|
|
|
89
|
+
def get_top_level_metadata(self):
|
|
90
|
+
"""
|
|
91
|
+
Return top level metadata dictionary (with updated activity end time).
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
dict
|
|
96
|
+
Top level metadata dictionary.
|
|
97
|
+
|
|
98
|
+
"""
|
|
99
|
+
try:
|
|
100
|
+
self.top_level_meta[self.observatory]["activity"][
|
|
101
|
+
"end"
|
|
102
|
+
] = datetime.datetime.now().isoformat(timespec="seconds")
|
|
103
|
+
except KeyError:
|
|
104
|
+
pass
|
|
105
|
+
return self.top_level_meta
|
|
106
|
+
|
|
89
107
|
def get_data_model_schema_file_name(self):
|
|
90
108
|
"""
|
|
91
109
|
Return data model schema file name.
|
|
@@ -38,7 +38,10 @@ def validate_schema(data, schema_file):
|
|
|
38
38
|
if validation fails
|
|
39
39
|
|
|
40
40
|
"""
|
|
41
|
-
schema, schema_file = _load_schema(
|
|
41
|
+
schema, schema_file = _load_schema(
|
|
42
|
+
schema_file,
|
|
43
|
+
data.get("schema_version", "0.1.0"), # default version to ensure backward compatibility
|
|
44
|
+
)
|
|
42
45
|
|
|
43
46
|
try:
|
|
44
47
|
jsonschema.validate(data, schema=schema, format_checker=format_checkers.format_checker)
|
|
@@ -72,17 +75,17 @@ def get_default_metadata_dict(schema_file=None, observatory="CTA"):
|
|
|
72
75
|
return _fill_defaults(schema["definitions"], observatory)
|
|
73
76
|
|
|
74
77
|
|
|
75
|
-
def _load_schema(schema_file=None):
|
|
78
|
+
def _load_schema(schema_file=None, schema_version=None):
|
|
76
79
|
"""
|
|
77
80
|
Load parameter schema from file from simpipe metadata schema.
|
|
78
81
|
|
|
79
82
|
Returns
|
|
80
83
|
-------
|
|
81
|
-
schema_file
|
|
82
|
-
Schema used for validation.
|
|
83
|
-
schema_file str
|
|
84
|
+
schema_file: str
|
|
84
85
|
File name schema is loaded from. If schema_file is not given,
|
|
85
86
|
the default schema file name is returned.
|
|
87
|
+
schema_version: str
|
|
88
|
+
Schema version.
|
|
86
89
|
|
|
87
90
|
Raises
|
|
88
91
|
------
|
|
@@ -98,6 +101,16 @@ def _load_schema(schema_file=None):
|
|
|
98
101
|
except FileNotFoundError:
|
|
99
102
|
schema_file = files("simtools").joinpath("schemas") / schema_file
|
|
100
103
|
schema = gen.collect_data_from_file(file_name=schema_file)
|
|
104
|
+
|
|
105
|
+
if isinstance(schema, list): # schema file with several schemas defined
|
|
106
|
+
if schema_version is None:
|
|
107
|
+
raise ValueError(f"Schema version not given in {schema_file}.")
|
|
108
|
+
schema = next((doc for doc in schema if doc.get("version") == schema_version), None)
|
|
109
|
+
if schema is None:
|
|
110
|
+
raise ValueError(f"Schema version {schema_version} not found in {schema_file}.")
|
|
111
|
+
elif schema_version is not None and schema_version != schema.get("version"):
|
|
112
|
+
_logger.warning(f"Schema version {schema_version} does not match {schema.get('version')}")
|
|
113
|
+
|
|
101
114
|
_logger.debug(f"Loading schema from {schema_file}")
|
|
102
115
|
_add_array_elements("InstrumentTypeElement", schema)
|
|
103
116
|
|
|
@@ -170,7 +170,7 @@ class ModelDataWriter:
|
|
|
170
170
|
metadata_input_dict["output_file"] = output_file
|
|
171
171
|
metadata_input_dict["output_file_format"] = Path(output_file).suffix.lstrip(".")
|
|
172
172
|
writer.write_metadata_to_yml(
|
|
173
|
-
metadata=MetadataCollector(args_dict=metadata_input_dict).
|
|
173
|
+
metadata=MetadataCollector(args_dict=metadata_input_dict).get_top_level_metadata(),
|
|
174
174
|
yml_file=output_path / f"{Path(output_file).stem}",
|
|
175
175
|
)
|
|
176
176
|
return _json_dict
|