gammasimtools 0.23.0__py3-none-any.whl → 0.24.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.23.0.dist-info → gammasimtools-0.24.0.dist-info}/METADATA +1 -1
- {gammasimtools-0.23.0.dist-info → gammasimtools-0.24.0.dist-info}/RECORD +59 -58
- simtools/_version.py +2 -2
- simtools/application_control.py +4 -4
- simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -1
- simtools/applications/db_add_file_to_db.py +2 -2
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
- simtools/applications/db_add_value_from_json_to_db.py +2 -2
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +1 -1
- simtools/applications/db_generate_compound_indexes.py +1 -1
- simtools/applications/db_get_array_layouts_from_db.py +2 -2
- simtools/applications/db_get_file_from_db.py +1 -1
- simtools/applications/db_get_parameter_from_db.py +1 -1
- simtools/applications/db_inspect_databases.py +4 -2
- simtools/applications/db_upload_model_repository.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +1 -1
- simtools/applications/generate_array_config.py +1 -1
- simtools/applications/maintain_simulation_model_add_production.py +11 -21
- simtools/applications/production_generate_grid.py +1 -1
- simtools/applications/submit_array_layouts.py +2 -2
- simtools/applications/validate_camera_fov.py +1 -1
- simtools/applications/validate_cumulative_psf.py +2 -2
- simtools/applications/validate_optics.py +1 -1
- simtools/configuration/commandline_parser.py +7 -9
- simtools/configuration/configurator.py +1 -1
- simtools/corsika/corsika_config.py +2 -4
- simtools/data_model/model_data_writer.py +1 -1
- simtools/data_model/schema.py +36 -34
- simtools/db/db_handler.py +61 -294
- simtools/db/db_model_upload.py +1 -1
- simtools/db/mongo_db.py +535 -0
- simtools/dependencies.py +33 -8
- simtools/layout/array_layout.py +7 -7
- simtools/layout/array_layout_utils.py +3 -3
- simtools/model/array_model.py +36 -67
- simtools/model/calibration_model.py +12 -9
- simtools/model/model_parameter.py +196 -159
- simtools/model/model_repository.py +159 -35
- simtools/model/model_utils.py +3 -3
- simtools/model/site_model.py +59 -27
- simtools/model/telescope_model.py +21 -13
- simtools/ray_tracing/mirror_panel_psf.py +4 -4
- simtools/ray_tracing/psf_parameter_optimisation.py +1 -1
- simtools/reporting/docs_auto_report_generator.py +1 -1
- simtools/reporting/docs_read_parameters.py +3 -2
- simtools/schemas/simulation_models_info.schema.yml +2 -1
- simtools/simtel/simtel_config_writer.py +97 -20
- simtools/simulator.py +2 -1
- simtools/testing/assertions.py +50 -6
- simtools/testing/validate_output.py +4 -8
- simtools/utils/value_conversion.py +10 -5
- simtools/version.py +24 -0
- simtools/visualization/plot_pixels.py +1 -1
- simtools/visualization/plot_psf.py +1 -1
- simtools/visualization/plot_tables.py +1 -1
- {gammasimtools-0.23.0.dist-info → gammasimtools-0.24.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.23.0.dist-info → gammasimtools-0.24.0.dist-info}/entry_points.txt +0 -0
- {gammasimtools-0.23.0.dist-info → gammasimtools-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.23.0.dist-info → gammasimtools-0.24.0.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
|
-
"""Base class for simulation model parameters."""
|
|
2
|
+
"""Base class for simulation model parameters (e.g., for SiteModel or TelescopeModel)."""
|
|
3
3
|
|
|
4
4
|
import logging
|
|
5
5
|
import shutil
|
|
6
|
-
from copy import copy
|
|
6
|
+
from copy import copy, deepcopy
|
|
7
7
|
|
|
8
8
|
import astropy.units as u
|
|
9
9
|
|
|
10
10
|
import simtools.utils.general as gen
|
|
11
|
+
from simtools.data_model import schema
|
|
11
12
|
from simtools.db import db_handler
|
|
12
13
|
from simtools.io import ascii_handler, io_handler
|
|
13
14
|
from simtools.simtel.simtel_config_writer import SimtelConfigWriter
|
|
14
|
-
from simtools.utils import names
|
|
15
|
+
from simtools.utils import names, value_conversion
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class InvalidModelParameterError(Exception):
|
|
@@ -27,8 +28,8 @@ class ModelParameter:
|
|
|
27
28
|
|
|
28
29
|
Parameters
|
|
29
30
|
----------
|
|
30
|
-
|
|
31
|
-
Database
|
|
31
|
+
db_config:
|
|
32
|
+
Database configuration dictionary.
|
|
32
33
|
model_version: str
|
|
33
34
|
Version of the model (ex. 5.0.0).
|
|
34
35
|
site: str
|
|
@@ -38,35 +39,37 @@ class ModelParameter:
|
|
|
38
39
|
collection: str
|
|
39
40
|
instrument class (e.g. telescopes, calibration_devices)
|
|
40
41
|
as stored under collection in the DB.
|
|
41
|
-
mongo_db_config: dict
|
|
42
|
-
MongoDB configuration.
|
|
43
42
|
label: str
|
|
43
|
+
Instance label. Used for output file naming.
|
|
44
|
+
overwrite_model_parameters: str, optional
|
|
45
|
+
File name to overwrite model parameters from DB with provided values.
|
|
44
46
|
Instance label. Important for output file naming.
|
|
45
|
-
|
|
47
|
+
ignore_software_version: bool
|
|
48
|
+
If True, ignore software version checks for deprecated parameters.
|
|
49
|
+
Useful for documentation generation.
|
|
46
50
|
"""
|
|
47
51
|
|
|
48
52
|
def __init__(
|
|
49
53
|
self,
|
|
50
|
-
|
|
54
|
+
db_config,
|
|
51
55
|
model_version,
|
|
52
56
|
site=None,
|
|
53
57
|
array_element_name=None,
|
|
54
58
|
collection="telescopes",
|
|
55
|
-
db=None,
|
|
56
59
|
label=None,
|
|
60
|
+
overwrite_model_parameters=None,
|
|
61
|
+
ignore_software_version=False,
|
|
57
62
|
):
|
|
58
63
|
self._logger = logging.getLogger(__name__)
|
|
59
|
-
self._extra_label = None
|
|
60
64
|
self.io_handler = io_handler.IOHandler()
|
|
61
|
-
self.db = (
|
|
62
|
-
db if db is not None else db_handler.DatabaseHandler(mongo_db_config=mongo_db_config)
|
|
63
|
-
)
|
|
65
|
+
self.db = db_handler.DatabaseHandler(db_config=db_config)
|
|
64
66
|
|
|
65
|
-
self.
|
|
67
|
+
self.parameters = {}
|
|
66
68
|
self._simulation_config_parameters = {sw: {} for sw in names.simulation_software()}
|
|
67
69
|
self.collection = collection
|
|
68
70
|
self.label = label
|
|
69
71
|
self.model_version = model_version
|
|
72
|
+
self.ignore_software_version = ignore_software_version
|
|
70
73
|
self.site = names.validate_site_name(site) if site is not None else None
|
|
71
74
|
self.name = (
|
|
72
75
|
names.validate_array_element_name(array_element_name)
|
|
@@ -78,56 +81,17 @@ class ModelParameter:
|
|
|
78
81
|
)
|
|
79
82
|
self._config_file_directory = None
|
|
80
83
|
self._config_file_path = None
|
|
81
|
-
self.
|
|
82
|
-
|
|
83
|
-
self.simtel_config_writer = None
|
|
84
|
+
self.overwrite_model_parameters = overwrite_model_parameters
|
|
84
85
|
self._added_parameter_files = None
|
|
85
|
-
self._is_config_file_up_to_date = False
|
|
86
86
|
self._is_exported_model_files_up_to_date = False
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
def model_version(self):
|
|
90
|
-
"""Model version."""
|
|
91
|
-
return self._model_version
|
|
92
|
-
|
|
93
|
-
@model_version.setter
|
|
94
|
-
def model_version(self, model_version):
|
|
95
|
-
"""
|
|
96
|
-
Set model version.
|
|
97
|
-
|
|
98
|
-
Parameters
|
|
99
|
-
----------
|
|
100
|
-
model_version: str or list
|
|
101
|
-
Model version (e.g., "6.0.0").
|
|
102
|
-
If a list is passed, it must contain exactly one element,
|
|
103
|
-
and only that element will be used.
|
|
104
|
-
|
|
105
|
-
Raises
|
|
106
|
-
------
|
|
107
|
-
ValueError
|
|
108
|
-
If more than one model version is passed.
|
|
109
|
-
"""
|
|
110
|
-
if isinstance(model_version, list):
|
|
111
|
-
raise ValueError(
|
|
112
|
-
f"Only one model version can be passed to {self.__class__.__name__}, not a list."
|
|
113
|
-
)
|
|
114
|
-
self._model_version = model_version
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def parameters(self):
|
|
118
|
-
"""
|
|
119
|
-
Model parameters dictionary.
|
|
88
|
+
self._load_parameters_from_db()
|
|
120
89
|
|
|
121
|
-
|
|
122
|
-
-------
|
|
123
|
-
dict
|
|
124
|
-
Dictionary containing all model parameters
|
|
125
|
-
"""
|
|
126
|
-
return self._parameters
|
|
90
|
+
self.simtel_config_writer = None
|
|
127
91
|
|
|
128
92
|
def _get_parameter_dict(self, par_name):
|
|
129
93
|
"""
|
|
130
|
-
Get model parameter dictionary as stored in the DB.
|
|
94
|
+
Get model parameter dictionary for a specific parameter as stored in the DB.
|
|
131
95
|
|
|
132
96
|
No conversion to values are applied for the use in simtools
|
|
133
97
|
(e.g., no conversion from the string representation of lists
|
|
@@ -155,7 +119,7 @@ class ModelParameter:
|
|
|
155
119
|
f"Parameter {par_name} was not found in the model {self.name}, {self.site}."
|
|
156
120
|
) from e
|
|
157
121
|
|
|
158
|
-
def get_parameter_value(self, par_name
|
|
122
|
+
def get_parameter_value(self, par_name):
|
|
159
123
|
"""
|
|
160
124
|
Get the value of a model parameter.
|
|
161
125
|
|
|
@@ -166,9 +130,6 @@ class ModelParameter:
|
|
|
166
130
|
----------
|
|
167
131
|
par_name: str
|
|
168
132
|
Name of the parameter.
|
|
169
|
-
parameter_dict: dict
|
|
170
|
-
Dictionary with complete DB entry for the given parameter
|
|
171
|
-
(including the 'value', 'units' fields).
|
|
172
133
|
|
|
173
134
|
Returns
|
|
174
135
|
-------
|
|
@@ -176,50 +137,28 @@ class ModelParameter:
|
|
|
176
137
|
|
|
177
138
|
Raises
|
|
178
139
|
------
|
|
179
|
-
|
|
140
|
+
InvalidModelParameterError
|
|
180
141
|
If par_name does not match any parameter in this model.
|
|
181
142
|
"""
|
|
182
|
-
parameter_dict = parameter_dict if parameter_dict else self._get_parameter_dict(par_name)
|
|
183
143
|
try:
|
|
184
|
-
|
|
144
|
+
value = self._get_parameter_dict(par_name)["value"]
|
|
185
145
|
except KeyError as exc:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if isinstance(
|
|
189
|
-
_is_float = False
|
|
146
|
+
raise InvalidModelParameterError(f"Parameter {par_name} does not have a value") from exc
|
|
147
|
+
|
|
148
|
+
if isinstance(value, str):
|
|
190
149
|
try:
|
|
191
150
|
_is_float = self.get_parameter_type(par_name).startswith("float")
|
|
192
|
-
except (
|
|
151
|
+
except (
|
|
152
|
+
InvalidModelParameterError,
|
|
153
|
+
TypeError,
|
|
154
|
+
AttributeError,
|
|
155
|
+
): # float - in case we don't know
|
|
193
156
|
_is_float = True
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return _parameter
|
|
198
|
-
|
|
199
|
-
def _create_quantity_for_value(self, value, unit):
|
|
200
|
-
"""
|
|
201
|
-
Create an astropy quantity for a single value and unit.
|
|
202
|
-
|
|
203
|
-
Parameters
|
|
204
|
-
----------
|
|
205
|
-
value: numeric or str
|
|
206
|
-
The value to create a quantity for.
|
|
207
|
-
unit: str or None
|
|
208
|
-
The unit string or None.
|
|
157
|
+
value = gen.convert_string_to_list(value, is_float=_is_float)
|
|
158
|
+
if len(value) == 1:
|
|
159
|
+
value = value[0]
|
|
209
160
|
|
|
210
|
-
|
|
211
|
-
-------
|
|
212
|
-
astropy.Quantity or original value
|
|
213
|
-
Astropy quantity for numeric values with units,
|
|
214
|
-
original value for non-numeric values.
|
|
215
|
-
"""
|
|
216
|
-
if not isinstance(value, int | float):
|
|
217
|
-
return value
|
|
218
|
-
|
|
219
|
-
if unit is None or unit == "null":
|
|
220
|
-
return value * u.dimensionless_unscaled
|
|
221
|
-
|
|
222
|
-
return value * u.Unit(unit)
|
|
161
|
+
return value
|
|
223
162
|
|
|
224
163
|
def get_parameter_value_with_unit(self, par_name):
|
|
225
164
|
"""
|
|
@@ -237,7 +176,7 @@ class ModelParameter:
|
|
|
237
176
|
|
|
238
177
|
"""
|
|
239
178
|
_parameter = self._get_parameter_dict(par_name)
|
|
240
|
-
_value = self.get_parameter_value(par_name
|
|
179
|
+
_value = self.get_parameter_value(par_name)
|
|
241
180
|
|
|
242
181
|
try:
|
|
243
182
|
if isinstance(_parameter.get("unit"), str):
|
|
@@ -251,7 +190,9 @@ class ModelParameter:
|
|
|
251
190
|
|
|
252
191
|
# Create list of quantities for multiple values with different units
|
|
253
192
|
return [
|
|
254
|
-
|
|
193
|
+
value_conversion.get_value_as_quantity(
|
|
194
|
+
_value[i], _unit[i] if i < len(_unit) else None
|
|
195
|
+
)
|
|
255
196
|
for i in range(len(_value))
|
|
256
197
|
]
|
|
257
198
|
|
|
@@ -272,13 +213,11 @@ class ModelParameter:
|
|
|
272
213
|
|
|
273
214
|
Returns
|
|
274
215
|
-------
|
|
275
|
-
str
|
|
276
|
-
type of the parameter
|
|
277
|
-
|
|
216
|
+
str
|
|
217
|
+
type of the parameter
|
|
278
218
|
"""
|
|
279
|
-
parameter_dict = self._get_parameter_dict(par_name)
|
|
280
219
|
try:
|
|
281
|
-
return
|
|
220
|
+
return self._get_parameter_dict(par_name)["type"]
|
|
282
221
|
except KeyError:
|
|
283
222
|
self._logger.debug(f"Parameter {par_name} does not have a type.")
|
|
284
223
|
return None
|
|
@@ -298,9 +237,8 @@ class ModelParameter:
|
|
|
298
237
|
True if file flag is set.
|
|
299
238
|
|
|
300
239
|
"""
|
|
301
|
-
parameter_dict = self._get_parameter_dict(par_name)
|
|
302
240
|
try:
|
|
303
|
-
return
|
|
241
|
+
return self._get_parameter_dict(par_name)["file"]
|
|
304
242
|
except KeyError:
|
|
305
243
|
self._logger.debug(f"Parameter {par_name} does not have a file associated with it.")
|
|
306
244
|
return False
|
|
@@ -321,11 +259,6 @@ class ModelParameter:
|
|
|
321
259
|
"""
|
|
322
260
|
return self._get_parameter_dict(par_name)["parameter_version"]
|
|
323
261
|
|
|
324
|
-
def print_parameters(self):
|
|
325
|
-
"""Print parameters and their values for debugging purposes."""
|
|
326
|
-
for par in self.parameters:
|
|
327
|
-
print(f"{par} = {self.get_parameter_value(par)}")
|
|
328
|
-
|
|
329
262
|
def _set_config_file_directory_and_name(self):
|
|
330
263
|
"""Set and create the directory and the name of the config file."""
|
|
331
264
|
if self.name is None and self.site is None:
|
|
@@ -341,7 +274,6 @@ class ModelParameter:
|
|
|
341
274
|
self.model_version,
|
|
342
275
|
telescope_model_name=self.name,
|
|
343
276
|
label=self.label,
|
|
344
|
-
extra_label=self._extra_label,
|
|
345
277
|
)
|
|
346
278
|
self._config_file_path = self.config_file_directory.joinpath(config_file_name)
|
|
347
279
|
|
|
@@ -379,34 +311,71 @@ class ModelParameter:
|
|
|
379
311
|
pass
|
|
380
312
|
|
|
381
313
|
def _load_parameters_from_db(self):
|
|
382
|
-
"""
|
|
314
|
+
"""
|
|
315
|
+
Read parameters from Database.
|
|
316
|
+
|
|
317
|
+
This is the main function to load the model parameters from the DB.
|
|
318
|
+
"""
|
|
383
319
|
if self.db is None:
|
|
384
320
|
return
|
|
385
321
|
|
|
386
322
|
if self.name or self.site:
|
|
387
|
-
|
|
388
|
-
|
|
323
|
+
# copy parameters dict, is it may be modified later on
|
|
324
|
+
self.parameters = deepcopy(
|
|
325
|
+
self.db.get_model_parameters(
|
|
326
|
+
self.site, self.name, self.collection, self.model_version
|
|
327
|
+
)
|
|
389
328
|
)
|
|
329
|
+
if self.overwrite_model_parameters:
|
|
330
|
+
self.overwrite_parameters_from_file(self.overwrite_model_parameters)
|
|
331
|
+
self._check_model_parameter_software_versions(self.parameters.keys())
|
|
390
332
|
|
|
391
333
|
self._load_simulation_software_parameter()
|
|
334
|
+
for software_name, parameters in self._simulation_config_parameters.items():
|
|
335
|
+
self._check_model_parameter_software_versions(
|
|
336
|
+
parameters.keys(), software_name=software_name
|
|
337
|
+
)
|
|
392
338
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
339
|
+
def _check_model_parameter_software_versions(self, parameter_list, software_name=None):
|
|
340
|
+
"""
|
|
341
|
+
Ensure that model parameters are compatible with the installed software versions.
|
|
342
|
+
|
|
343
|
+
Compares software versions listed in schema files with the installed software versions
|
|
344
|
+
(e.g., sim_telarray, CORSIKA).
|
|
397
345
|
|
|
398
|
-
|
|
346
|
+
Parameters
|
|
347
|
+
----------
|
|
348
|
+
parameter_list: list
|
|
349
|
+
List containing model parameter names.
|
|
350
|
+
software_name: str
|
|
351
|
+
Name of the software for which the parameters are checked.
|
|
352
|
+
"""
|
|
353
|
+
for par_name in parameter_list:
|
|
354
|
+
if par_name in (parameter_schema := names.model_parameters()):
|
|
355
|
+
schema.validate_deprecation_and_version(
|
|
356
|
+
data=parameter_schema[par_name],
|
|
357
|
+
software_name=software_name,
|
|
358
|
+
ignore_software_version=self.ignore_software_version,
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
def overwrite_model_parameter(self, par_name, value, parameter_version=None):
|
|
399
362
|
"""
|
|
400
|
-
|
|
363
|
+
Overwrite the parameter dictionary for a specific parameter in the model.
|
|
364
|
+
|
|
365
|
+
This function does not modify the DB, it affects only the current instance of
|
|
366
|
+
the model parameter dictionary.
|
|
401
367
|
|
|
402
|
-
|
|
368
|
+
If the parameter version is given only, the parameter dictionary is updated
|
|
369
|
+
from the database for the given version.
|
|
403
370
|
|
|
404
371
|
Parameters
|
|
405
372
|
----------
|
|
406
373
|
par_name: str
|
|
407
374
|
Name of the parameter.
|
|
408
375
|
value:
|
|
409
|
-
|
|
376
|
+
New value for the parameter.
|
|
377
|
+
parameter_version: str, optional
|
|
378
|
+
New version for the parameter.
|
|
410
379
|
|
|
411
380
|
Raises
|
|
412
381
|
------
|
|
@@ -416,31 +385,48 @@ class ModelParameter:
|
|
|
416
385
|
if par_name not in self.parameters:
|
|
417
386
|
raise InvalidModelParameterError(f"Parameter {par_name} not in the model")
|
|
418
387
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
388
|
+
if value is None and parameter_version:
|
|
389
|
+
_para_dict = self.db.get_model_parameter(
|
|
390
|
+
parameter=par_name,
|
|
391
|
+
site=self.site,
|
|
392
|
+
array_element_name=self.name,
|
|
393
|
+
parameter_version=parameter_version,
|
|
394
|
+
)
|
|
395
|
+
if _para_dict:
|
|
396
|
+
self.parameters[par_name] = _para_dict.get(par_name)
|
|
397
|
+
self._logger.debug(
|
|
398
|
+
f"Changing parameter {par_name} to version {parameter_version} with value "
|
|
399
|
+
f"{self.parameters[par_name]['value']}"
|
|
400
|
+
)
|
|
401
|
+
else:
|
|
402
|
+
value = gen.convert_string_to_list(value) if isinstance(value, str) else value
|
|
403
|
+
|
|
404
|
+
par_type = self.get_parameter_type(par_name)
|
|
405
|
+
if not gen.validate_data_type(
|
|
406
|
+
reference_dtype=par_type,
|
|
407
|
+
value=value,
|
|
408
|
+
dtype=None,
|
|
409
|
+
allow_subtypes=True,
|
|
410
|
+
):
|
|
411
|
+
raise ValueError(f"Could not cast {value} of type {type(value)} to {par_type}.")
|
|
429
412
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
413
|
+
self._logger.debug(
|
|
414
|
+
f"Changing parameter {par_name} from {self.get_parameter_value(par_name)} "
|
|
415
|
+
f"to {value}"
|
|
416
|
+
)
|
|
417
|
+
self.parameters[par_name]["value"] = value
|
|
418
|
+
if parameter_version:
|
|
419
|
+
self.parameters[par_name]["parameter_version"] = parameter_version
|
|
434
420
|
|
|
435
421
|
# In case parameter is a file, the model files will be outdated
|
|
436
422
|
if self.get_parameter_file_flag(par_name):
|
|
437
423
|
self._is_exported_model_files_up_to_date = False
|
|
438
424
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
def change_multiple_parameters_from_file(self, file_name):
|
|
425
|
+
def overwrite_parameters_from_file(self, file_name):
|
|
442
426
|
"""
|
|
443
|
-
|
|
427
|
+
Overwrite parameters from a file.
|
|
428
|
+
|
|
429
|
+
File is expected to follow the format described in 'simulation_models_info.schema.yml'.
|
|
444
430
|
|
|
445
431
|
This function does not modify the DB, it affects only the current instance.
|
|
446
432
|
This feature is intended for developers and lacks validation.
|
|
@@ -450,34 +436,85 @@ class ModelParameter:
|
|
|
450
436
|
file_name: str
|
|
451
437
|
File containing the parameters to be changed.
|
|
452
438
|
"""
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
"
|
|
439
|
+
changes_data = schema.validate_dict_using_schema(
|
|
440
|
+
data=ascii_handler.collect_data_from_file(file_name=file_name),
|
|
441
|
+
schema_file="simulation_models_info.schema.yml",
|
|
442
|
+
).get("changes", {})
|
|
443
|
+
|
|
444
|
+
key_for_changes = self._get_key_for_parameter_changes(self.site, self.name, changes_data)
|
|
445
|
+
self.overwrite_parameters(changes_data.get(key_for_changes, {}) if key_for_changes else {})
|
|
446
|
+
|
|
447
|
+
def _get_key_for_parameter_changes(self, site, array_element_name, changes_data):
|
|
448
|
+
"""
|
|
449
|
+
Get the key for parameter changes based on site and array element name.
|
|
450
|
+
|
|
451
|
+
For array elements, the following cases are taken into account:
|
|
452
|
+
|
|
453
|
+
- array element name in changes_data: specific array element is returned
|
|
454
|
+
- design type in changes_data: specific design type is returned if array
|
|
455
|
+
element matches this design
|
|
456
|
+
|
|
457
|
+
Parameters
|
|
458
|
+
----------
|
|
459
|
+
site: str
|
|
460
|
+
Site name.
|
|
461
|
+
array_element_name: str
|
|
462
|
+
Array element name.
|
|
463
|
+
changes_data: dict
|
|
464
|
+
Dictionary containing the changes data.
|
|
465
|
+
|
|
466
|
+
Returns
|
|
467
|
+
-------
|
|
468
|
+
str
|
|
469
|
+
Key for parameter changes.
|
|
470
|
+
"""
|
|
471
|
+
if site and not array_element_name:
|
|
472
|
+
return f"OBS-{site}"
|
|
473
|
+
|
|
474
|
+
if array_element_name in changes_data:
|
|
475
|
+
return array_element_name
|
|
476
|
+
|
|
477
|
+
design_type = self.db.get_design_model(
|
|
478
|
+
model_version=self.model_version,
|
|
479
|
+
array_element_name=array_element_name,
|
|
480
|
+
collection=self.collection,
|
|
456
481
|
)
|
|
457
|
-
|
|
458
|
-
|
|
482
|
+
if design_type in changes_data:
|
|
483
|
+
return design_type
|
|
484
|
+
|
|
485
|
+
return None
|
|
459
486
|
|
|
460
|
-
def
|
|
487
|
+
def overwrite_parameters(self, changes):
|
|
461
488
|
"""
|
|
462
489
|
Change the value of multiple existing parameters in the model.
|
|
463
490
|
|
|
464
491
|
This function does not modify the DB, it affects only the current instance.
|
|
465
492
|
|
|
493
|
+
Allows for two types of 'changes' dictionary:
|
|
494
|
+
|
|
495
|
+
- simple: '{parameter_name: new_value, ...}'
|
|
496
|
+
- model repository style:
|
|
497
|
+
'{parameter_name: {"value": new_value, "version": new_version}, ...}'
|
|
498
|
+
|
|
466
499
|
Parameters
|
|
467
500
|
----------
|
|
468
|
-
|
|
469
|
-
Parameters
|
|
501
|
+
changes: dict
|
|
502
|
+
Parameters to be changed.
|
|
503
|
+
"""
|
|
504
|
+
for par_name, par_value in changes.items():
|
|
505
|
+
if par_name in self.parameters:
|
|
506
|
+
if isinstance(par_value, dict) and ("value" in par_value or "version" in par_value):
|
|
507
|
+
self.overwrite_model_parameter(
|
|
508
|
+
par_name, par_value.get("value"), par_value.get("version")
|
|
509
|
+
)
|
|
510
|
+
else:
|
|
511
|
+
self.overwrite_model_parameter(par_name, par_value)
|
|
470
512
|
|
|
513
|
+
def overwrite_model_file(self, par_name, file_path):
|
|
471
514
|
"""
|
|
472
|
-
|
|
473
|
-
if par in self.parameters:
|
|
474
|
-
self.change_parameter(par, value)
|
|
515
|
+
Overwrite the existing model file in the config file directory.
|
|
475
516
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
def export_parameter_file(self, par_name, file_path):
|
|
479
|
-
"""
|
|
480
|
-
Export a file to the config file directory.
|
|
517
|
+
Keeps track of updated model file with '_added_parameter_files' attribute.
|
|
481
518
|
|
|
482
519
|
Parameters
|
|
483
520
|
----------
|
|
@@ -492,7 +529,7 @@ class ModelParameter:
|
|
|
492
529
|
|
|
493
530
|
def export_model_files(self, destination_path=None, update_if_necessary=False):
|
|
494
531
|
"""
|
|
495
|
-
Export
|
|
532
|
+
Export model files from the database into the config file directory.
|
|
496
533
|
|
|
497
534
|
Parameters
|
|
498
535
|
----------
|