gammasimtools 0.22.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.22.0.dist-info → gammasimtools-0.24.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/RECORD +128 -125
- simtools/_version.py +2 -2
- simtools/application_control.py +118 -0
- simtools/applications/calculate_incident_angles.py +17 -22
- simtools/applications/convert_all_model_parameters_from_simtel.py +28 -43
- simtools/applications/convert_geo_coordinates_of_array_elements.py +26 -45
- simtools/applications/convert_model_parameter_from_simtel.py +21 -41
- simtools/applications/db_add_file_to_db.py +13 -14
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +20 -33
- simtools/applications/db_add_value_from_json_to_db.py +29 -24
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +20 -35
- simtools/applications/db_generate_compound_indexes.py +11 -13
- simtools/applications/db_get_array_layouts_from_db.py +20 -40
- simtools/applications/db_get_file_from_db.py +15 -17
- simtools/applications/db_get_parameter_from_db.py +33 -35
- simtools/applications/db_inspect_databases.py +13 -12
- simtools/applications/db_upload_model_repository.py +13 -31
- simtools/applications/derive_ctao_array_layouts.py +16 -21
- simtools/applications/derive_mirror_rnda.py +9 -14
- simtools/applications/derive_photon_electron_spectrum.py +7 -10
- simtools/applications/derive_psf_parameters.py +13 -20
- simtools/applications/derive_trigger_rates.py +6 -9
- simtools/applications/docs_produce_array_element_report.py +22 -23
- simtools/applications/docs_produce_calibration_reports.py +26 -24
- simtools/applications/docs_produce_model_parameter_reports.py +15 -22
- simtools/applications/docs_produce_simulation_configuration_report.py +21 -22
- simtools/applications/generate_array_config.py +14 -33
- simtools/applications/generate_corsika_histograms.py +22 -43
- simtools/applications/generate_default_metadata.py +15 -36
- simtools/applications/generate_regular_arrays.py +11 -15
- simtools/applications/generate_simtel_event_data.py +23 -33
- simtools/applications/maintain_simulation_model_add_production.py +20 -37
- simtools/applications/maintain_simulation_model_compare_productions.py +10 -12
- simtools/applications/maintain_simulation_model_verify_production_tables.py +8 -11
- simtools/applications/merge_tables.py +14 -23
- simtools/applications/plot_array_layout.py +77 -54
- simtools/applications/plot_simtel_events.py +11 -13
- simtools/applications/plot_tabular_data.py +17 -38
- simtools/applications/plot_tabular_data_for_model_parameter.py +16 -23
- simtools/applications/print_version.py +14 -42
- simtools/applications/production_derive_corsika_limits.py +5 -9
- simtools/applications/production_derive_statistics.py +12 -25
- simtools/applications/production_generate_grid.py +20 -48
- simtools/applications/production_merge_corsika_limits.py +17 -21
- simtools/applications/run_application.py +12 -32
- simtools/applications/simulate_flasher.py +21 -25
- simtools/applications/simulate_illuminator.py +7 -14
- simtools/applications/simulate_pedestals.py +13 -13
- simtools/applications/simulate_prod.py +21 -33
- simtools/applications/simulate_prod_htcondor_generator.py +11 -25
- simtools/applications/submit_array_layouts.py +16 -19
- simtools/applications/submit_data_from_external.py +18 -34
- simtools/applications/submit_model_parameter_from_external.py +27 -40
- simtools/applications/validate_camera_efficiency.py +23 -21
- simtools/applications/validate_camera_fov.py +21 -26
- simtools/applications/validate_cumulative_psf.py +27 -35
- simtools/applications/validate_file_using_schema.py +15 -33
- simtools/applications/validate_optics.py +27 -33
- simtools/camera/camera_efficiency.py +0 -2
- simtools/configuration/commandline_parser.py +39 -13
- simtools/configuration/configurator.py +1 -6
- simtools/corsika/corsika_config.py +2 -9
- simtools/data_model/data_reader.py +0 -2
- simtools/data_model/metadata_collector.py +0 -2
- simtools/data_model/model_data_writer.py +1 -3
- simtools/data_model/schema.py +36 -34
- simtools/data_model/validate_data.py +0 -2
- simtools/db/db_handler.py +61 -296
- simtools/db/db_model_upload.py +1 -1
- simtools/db/mongo_db.py +535 -0
- simtools/dependencies.py +33 -8
- simtools/io/hdf5_handler.py +0 -5
- simtools/io/legacy_data_handler.py +0 -5
- simtools/job_execution/job_manager.py +0 -3
- simtools/layout/array_layout.py +7 -9
- simtools/layout/array_layout_utils.py +3 -3
- simtools/layout/telescope_position.py +0 -2
- simtools/model/array_model.py +38 -71
- simtools/model/calibration_model.py +12 -11
- simtools/model/camera.py +0 -2
- simtools/model/mirrors.py +0 -2
- simtools/model/model_parameter.py +200 -140
- simtools/model/model_repository.py +159 -35
- simtools/model/model_utils.py +3 -8
- simtools/model/site_model.py +59 -29
- simtools/model/telescope_model.py +21 -15
- simtools/production_configuration/calculate_statistical_uncertainties_grid_point.py +0 -2
- simtools/production_configuration/derive_production_statistics.py +0 -2
- simtools/production_configuration/interpolation_handler.py +0 -2
- simtools/ray_tracing/mirror_panel_psf.py +4 -4
- simtools/ray_tracing/psf_analysis.py +0 -2
- simtools/ray_tracing/psf_parameter_optimisation.py +1 -1
- simtools/ray_tracing/ray_tracing.py +0 -2
- simtools/reporting/docs_auto_report_generator.py +109 -1
- simtools/reporting/docs_read_parameters.py +4 -9
- simtools/runners/corsika_runner.py +0 -2
- simtools/runners/corsika_simtel_runner.py +0 -2
- simtools/runners/simtel_runner.py +0 -2
- simtools/schemas/model_parameters/transit_time_random.schema.yml +29 -0
- simtools/schemas/simulation_models_info.schema.yml +2 -1
- simtools/simtel/simtel_config_reader.py +0 -2
- simtools/simtel/simtel_config_writer.py +128 -33
- simtools/simtel/simtel_io_metadata.py +3 -3
- simtools/simtel/simulator_array.py +9 -21
- simtools/simtel/simulator_camera_efficiency.py +0 -2
- simtools/simtel/simulator_light_emission.py +1 -3
- simtools/simtel/simulator_ray_tracing.py +0 -2
- simtools/simulator.py +2 -6
- simtools/testing/assertions.py +52 -8
- simtools/testing/configuration.py +17 -4
- simtools/testing/validate_output.py +4 -8
- simtools/utils/general.py +5 -13
- simtools/utils/geometry.py +0 -5
- simtools/utils/names.py +1 -13
- simtools/utils/value_conversion.py +10 -5
- simtools/version.py +85 -0
- simtools/visualization/plot_array_layout.py +129 -23
- simtools/visualization/plot_incident_angles.py +0 -2
- simtools/visualization/plot_pixels.py +1 -1
- simtools/visualization/plot_psf.py +1 -1
- simtools/visualization/plot_simtel_events.py +0 -11
- simtools/visualization/plot_tables.py +1 -1
- simtools/visualization/visualize.py +0 -12
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/entry_points.txt +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.24.0.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"""Utilities for managing the simulation models repository.
|
|
2
2
|
|
|
3
3
|
Simulation model parameters and production tables are managed through
|
|
4
|
-
a gitlab repository ('
|
|
4
|
+
a gitlab repository ('simulation_models'). This module provides service
|
|
5
5
|
functions to interact with and verify the repository.
|
|
6
|
+
|
|
7
|
+
Main functionalities are:
|
|
8
|
+
|
|
9
|
+
- validation of production tables against model parameters
|
|
10
|
+
- generation of new production tables and model parameters based on
|
|
11
|
+
updates defined in a configuration file
|
|
12
|
+
|
|
6
13
|
"""
|
|
7
14
|
|
|
8
15
|
import logging
|
|
@@ -18,6 +25,44 @@ from simtools.utils import names
|
|
|
18
25
|
_logger = logging.getLogger(__name__)
|
|
19
26
|
|
|
20
27
|
|
|
28
|
+
def get_production_directory(simulation_models_path, model_version=None):
|
|
29
|
+
"""
|
|
30
|
+
Get the production directory for a specific model version.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
simulation_models_path : str
|
|
35
|
+
Path to the simulation models repository.
|
|
36
|
+
model_version : str, optional
|
|
37
|
+
Specific model version to get the production directory for.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
Path
|
|
42
|
+
Path to the production directory.
|
|
43
|
+
"""
|
|
44
|
+
if model_version:
|
|
45
|
+
return Path(simulation_models_path) / "simulation-models/productions" / str(model_version)
|
|
46
|
+
return Path(simulation_models_path) / "simulation-models/productions"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_model_parameter_directory(simulation_models_path):
|
|
50
|
+
"""
|
|
51
|
+
Get the model parameters directory.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
simulation_models_path : str
|
|
56
|
+
Path to the simulation models repository.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
Path
|
|
61
|
+
Path to the model parameters directory.
|
|
62
|
+
"""
|
|
63
|
+
return Path(simulation_models_path) / "simulation-models/model_parameters"
|
|
64
|
+
|
|
65
|
+
|
|
21
66
|
def verify_simulation_model_production_tables(simulation_models_path):
|
|
22
67
|
"""
|
|
23
68
|
Verify the simulation model production tables in the specified path.
|
|
@@ -35,7 +80,7 @@ def verify_simulation_model_production_tables(simulation_models_path):
|
|
|
35
80
|
bool
|
|
36
81
|
True if all parameters found, False if any missing.
|
|
37
82
|
"""
|
|
38
|
-
productions_path =
|
|
83
|
+
productions_path = get_production_directory(simulation_models_path)
|
|
39
84
|
production_files = list(productions_path.rglob("*.json"))
|
|
40
85
|
|
|
41
86
|
_logger.info(
|
|
@@ -124,9 +169,7 @@ def _get_model_parameter_file_path(
|
|
|
124
169
|
"""
|
|
125
170
|
collection = names.get_collection_name_from_parameter_name(parameter_name)
|
|
126
171
|
return (
|
|
127
|
-
|
|
128
|
-
/ "simulation-models"
|
|
129
|
-
/ "model_parameters"
|
|
172
|
+
get_model_parameter_directory(simulation_models_path)
|
|
130
173
|
/ (
|
|
131
174
|
collection
|
|
132
175
|
if collection in ("configuration_sim_telarray", "configuration_corsika")
|
|
@@ -138,39 +181,36 @@ def _get_model_parameter_file_path(
|
|
|
138
181
|
)
|
|
139
182
|
|
|
140
183
|
|
|
141
|
-
def generate_new_production(
|
|
184
|
+
def generate_new_production(model_version, simulation_models_path):
|
|
142
185
|
"""
|
|
143
186
|
Generate a new production definition (production tables and model parameters).
|
|
144
187
|
|
|
145
188
|
The following steps are performed:
|
|
146
189
|
|
|
147
190
|
- copy of production tables from an existing base model version
|
|
148
|
-
- update production tables with changes defined in a
|
|
191
|
+
- update production tables with changes defined in a configuration file (expected
|
|
192
|
+
to be called 'info.yml' in the target production directory)
|
|
149
193
|
- generate new model parameter entries for changed parameters
|
|
150
194
|
- allows for full or patch updates
|
|
151
195
|
|
|
152
196
|
Parameters
|
|
153
197
|
----------
|
|
154
|
-
|
|
155
|
-
|
|
198
|
+
model_version: str
|
|
199
|
+
Model version to be created or updated.
|
|
156
200
|
simulation_models_path: str
|
|
157
201
|
Path to the simulation models repository.
|
|
158
202
|
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
except ValueError as exc:
|
|
165
|
-
raise ValueError(f"Base model version not found in {modifications}") from exc
|
|
166
|
-
model_version = modifications["model_version"]
|
|
167
|
-
changes = modifications.get("changes", {})
|
|
203
|
+
modification_dict = _get_changes_dict(model_version, simulation_models_path)
|
|
204
|
+
update_type = modification_dict.get("model_update", "full_update")
|
|
205
|
+
changes, base_model_version = _get_changes_to_production(
|
|
206
|
+
modification_dict, simulation_models_path, update_type
|
|
207
|
+
)
|
|
168
208
|
|
|
169
209
|
_apply_changes_to_production_tables(
|
|
170
210
|
changes,
|
|
171
211
|
base_model_version,
|
|
172
|
-
model_version,
|
|
173
|
-
|
|
212
|
+
modification_dict["model_version"],
|
|
213
|
+
update_type,
|
|
174
214
|
simulation_models_path,
|
|
175
215
|
)
|
|
176
216
|
|
|
@@ -181,27 +221,27 @@ def _apply_changes_to_production_tables(
|
|
|
181
221
|
changes, base_model_version, model_version, update_type, simulation_models_path
|
|
182
222
|
):
|
|
183
223
|
"""
|
|
184
|
-
Apply changes to production tables and write them to target directory.
|
|
224
|
+
Apply changes to or generate new production tables and write them to target directory.
|
|
185
225
|
|
|
186
226
|
Parameters
|
|
187
227
|
----------
|
|
188
228
|
changes: dict
|
|
189
|
-
|
|
229
|
+
Changes to be applied.
|
|
190
230
|
base_model_version: str
|
|
191
|
-
|
|
231
|
+
Base model version (source directory for production tables).
|
|
192
232
|
model_version: str
|
|
193
|
-
|
|
233
|
+
Model version of the new production tables.
|
|
194
234
|
update_type: str
|
|
195
|
-
Update
|
|
235
|
+
Update type (e.g., 'full_update' or 'patch_update').
|
|
196
236
|
simulation_models_path: Path
|
|
197
237
|
Path to the simulation models repository.
|
|
198
238
|
"""
|
|
199
|
-
source = simulation_models_path
|
|
200
|
-
target = simulation_models_path
|
|
239
|
+
source = get_production_directory(simulation_models_path, base_model_version)
|
|
240
|
+
target = get_production_directory(simulation_models_path, model_version)
|
|
201
241
|
_logger.info(f"Production tables {update_type} from {source} to {target}")
|
|
202
242
|
target.mkdir(parents=True, exist_ok=True)
|
|
203
243
|
|
|
204
|
-
# load existing tables
|
|
244
|
+
# load existing tables from source
|
|
205
245
|
tables = {}
|
|
206
246
|
for file_path in Path(source).rglob("*.json"):
|
|
207
247
|
data = ascii_handler.collect_data_from_file(file_path)
|
|
@@ -217,9 +257,10 @@ def _apply_changes_to_production_tables(
|
|
|
217
257
|
if _apply_changes_to_production_table(
|
|
218
258
|
table_name, data, changes, model_version, update_type == "patch_update"
|
|
219
259
|
):
|
|
220
|
-
|
|
260
|
+
target_file = target / f"{table_name}.json"
|
|
261
|
+
_logger.info(f"Writing updated production table '{target_file}'")
|
|
221
262
|
data["production_table_name"] = table_name
|
|
222
|
-
ascii_handler.write_data_to_file(data,
|
|
263
|
+
ascii_handler.write_data_to_file(data, target_file, sort_keys=True)
|
|
223
264
|
|
|
224
265
|
|
|
225
266
|
def _apply_changes_to_production_table(table_name, data, changes, model_version, patch_update):
|
|
@@ -228,12 +269,14 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
|
|
|
228
269
|
|
|
229
270
|
Parameters
|
|
230
271
|
----------
|
|
272
|
+
table_name: str
|
|
273
|
+
Name of the production table.
|
|
231
274
|
data: dict
|
|
232
|
-
|
|
275
|
+
Data to be updated.
|
|
233
276
|
changes: dict
|
|
234
|
-
|
|
277
|
+
Changes to be applied.
|
|
235
278
|
model_version: str
|
|
236
|
-
|
|
279
|
+
Model version of the new production tables.
|
|
237
280
|
patch_update: bool
|
|
238
281
|
True if patch update (modify only changed parameters), False for full update.
|
|
239
282
|
|
|
@@ -248,7 +291,7 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
|
|
|
248
291
|
table_parameters = {} if patch_update else data.get("parameters", {}).get(table_name, {})
|
|
249
292
|
parameters, deprecated = _update_parameters_dict(table_parameters, changes, table_name)
|
|
250
293
|
data["parameters"] = parameters
|
|
251
|
-
if deprecated:
|
|
294
|
+
if deprecated and patch_update:
|
|
252
295
|
data["deprecated_parameters"] = deprecated
|
|
253
296
|
elif patch_update:
|
|
254
297
|
return False
|
|
@@ -256,6 +299,86 @@ def _apply_changes_to_production_table(table_name, data, changes, model_version,
|
|
|
256
299
|
return True
|
|
257
300
|
|
|
258
301
|
|
|
302
|
+
def _get_changes_dict(model_version, simulation_models_path):
|
|
303
|
+
"""
|
|
304
|
+
Load the changes dictionary from 'info.yml' files in production directories.
|
|
305
|
+
|
|
306
|
+
Parameters
|
|
307
|
+
----------
|
|
308
|
+
model_version: str
|
|
309
|
+
Model version of the new production tables.
|
|
310
|
+
simulation_models_path: Path
|
|
311
|
+
Path to the simulation models directory.
|
|
312
|
+
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
dict
|
|
316
|
+
Changes dictionary.
|
|
317
|
+
"""
|
|
318
|
+
return ascii_handler.collect_data_from_file(
|
|
319
|
+
get_production_directory(simulation_models_path, model_version) / "info.yml"
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _get_changes_to_production(
|
|
324
|
+
modification_dict, simulation_models_path, update_type="full_update"
|
|
325
|
+
):
|
|
326
|
+
"""
|
|
327
|
+
Prepare changes applied to production tables.
|
|
328
|
+
|
|
329
|
+
For full updates, this includes the combination of changes to be applied
|
|
330
|
+
for all model versions in the history, starting from the base version.
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
modification_dict: dict
|
|
335
|
+
Modifications dictionary.
|
|
336
|
+
simulation_models_path: Path
|
|
337
|
+
Path to the simulation models directory.
|
|
338
|
+
update_type: str
|
|
339
|
+
Update mode.
|
|
340
|
+
|
|
341
|
+
Returns
|
|
342
|
+
-------
|
|
343
|
+
dict, str
|
|
344
|
+
Changes dictionary and base model version.
|
|
345
|
+
"""
|
|
346
|
+
model_version_history = modification_dict.get("model_version_history", [])
|
|
347
|
+
|
|
348
|
+
try:
|
|
349
|
+
# oldest version is the base version
|
|
350
|
+
base_model_version = min(set(model_version_history), key=Version)
|
|
351
|
+
except ValueError:
|
|
352
|
+
_logger.debug(f"Base model version not found in {model_version_history}")
|
|
353
|
+
return {}, modification_dict.get("model_version")
|
|
354
|
+
|
|
355
|
+
changes = modification_dict.get("changes", {})
|
|
356
|
+
if update_type == "patch_update":
|
|
357
|
+
return changes, base_model_version
|
|
358
|
+
|
|
359
|
+
for version_mod in reversed(model_version_history):
|
|
360
|
+
_changes_dict = _get_changes_dict(version_mod, simulation_models_path)
|
|
361
|
+
_version_changes, base_model_version = _get_changes_to_production(
|
|
362
|
+
_changes_dict, simulation_models_path, update_type="full_update"
|
|
363
|
+
)
|
|
364
|
+
changes = _update_two_levels_in_changes_dict(changes, _version_changes)
|
|
365
|
+
# stop iterative loop after reaching first full version of production tables
|
|
366
|
+
if _changes_dict.get("model_update", "full_update") == "full_update":
|
|
367
|
+
break
|
|
368
|
+
|
|
369
|
+
return changes, base_model_version
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _update_two_levels_in_changes_dict(d, u):
|
|
373
|
+
"""Update changes dict, e.g. {"LSTN-design": { "parameter_name: { ... } } }."""
|
|
374
|
+
for k, v in u.items():
|
|
375
|
+
if isinstance(v, dict) and isinstance(d.get(k), dict):
|
|
376
|
+
d[k].update(v)
|
|
377
|
+
else:
|
|
378
|
+
d[k] = v
|
|
379
|
+
return d
|
|
380
|
+
|
|
381
|
+
|
|
259
382
|
def _update_parameters_dict(table_parameters, changes, table_name):
|
|
260
383
|
"""
|
|
261
384
|
Create a new parameters dictionary for the production tables.
|
|
@@ -285,6 +408,7 @@ def _update_parameters_dict(table_parameters, changes, table_name):
|
|
|
285
408
|
if data.get("deprecated", False):
|
|
286
409
|
_logger.info(f"Removing model parameter '{table_name} - {param}'")
|
|
287
410
|
deprecated_params.append(param)
|
|
411
|
+
new_params[table_name].pop(param, None)
|
|
288
412
|
else:
|
|
289
413
|
version = data["version"]
|
|
290
414
|
_logger.info(f"Setting '{table_name} - {param}' to version {version}")
|
|
@@ -330,7 +454,7 @@ def _create_new_model_parameter_entry(telescope, param, param_data, simulation_m
|
|
|
330
454
|
simulation_models_path: Path
|
|
331
455
|
Path to the simulation models directory.
|
|
332
456
|
"""
|
|
333
|
-
telescope_dir = simulation_models_path /
|
|
457
|
+
telescope_dir = get_model_parameter_directory(simulation_models_path) / telescope
|
|
334
458
|
if not telescope_dir.exists():
|
|
335
459
|
_logger.info(f"Create directory for array element '{telescope}': '{telescope_dir}'.")
|
|
336
460
|
telescope_dir.mkdir(parents=True, exist_ok=True)
|
simtools/model/model_utils.py
CHANGED
|
@@ -8,11 +8,6 @@ from simtools.model.site_model import SiteModel
|
|
|
8
8
|
from simtools.model.telescope_model import TelescopeModel
|
|
9
9
|
from simtools.utils import names
|
|
10
10
|
|
|
11
|
-
__all__ = [
|
|
12
|
-
"compute_telescope_transmission",
|
|
13
|
-
"is_two_mirror_telescope",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
11
|
|
|
17
12
|
def initialize_simulation_models(
|
|
18
13
|
label, db_config, model_version, site, telescope_name, calibration_device_name=None
|
|
@@ -43,21 +38,21 @@ def initialize_simulation_models(
|
|
|
43
38
|
tel_model = TelescopeModel(
|
|
44
39
|
site=site,
|
|
45
40
|
telescope_name=telescope_name,
|
|
46
|
-
|
|
41
|
+
db_config=db_config,
|
|
47
42
|
model_version=model_version,
|
|
48
43
|
label=label,
|
|
49
44
|
)
|
|
50
45
|
site_model = SiteModel(
|
|
51
46
|
site=site,
|
|
52
47
|
model_version=model_version,
|
|
53
|
-
|
|
48
|
+
db_config=db_config,
|
|
54
49
|
label=label,
|
|
55
50
|
)
|
|
56
51
|
if calibration_device_name is not None:
|
|
57
52
|
calibration_model = CalibrationModel(
|
|
58
53
|
site=site,
|
|
59
54
|
calibration_device_model_name=calibration_device_name,
|
|
60
|
-
|
|
55
|
+
db_config=db_config,
|
|
61
56
|
model_version=model_version,
|
|
62
57
|
label=label,
|
|
63
58
|
)
|
simtools/model/site_model.py
CHANGED
|
@@ -9,52 +9,67 @@ from astropy import units as u
|
|
|
9
9
|
|
|
10
10
|
from simtools.model.model_parameter import ModelParameter
|
|
11
11
|
|
|
12
|
-
__all__ = ["SiteModel"]
|
|
13
|
-
|
|
14
12
|
|
|
15
13
|
class SiteModel(ModelParameter):
|
|
16
14
|
"""
|
|
17
|
-
|
|
15
|
+
Representation of an observatory site model.
|
|
16
|
+
|
|
17
|
+
The site model includes (among others):
|
|
18
|
+
|
|
19
|
+
- Reference point coordinates
|
|
20
|
+
- Array elements
|
|
21
|
+
- Geomagnetic field parameters
|
|
22
|
+
- Atmospheric parameters
|
|
23
|
+
- NSB parameters
|
|
18
24
|
|
|
19
25
|
Parameters
|
|
20
26
|
----------
|
|
21
27
|
site: str
|
|
22
28
|
Site name (e.g., South or North).
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
db_config: dict
|
|
30
|
+
Database configuration.
|
|
25
31
|
model_version: str or list
|
|
26
32
|
Model version or list of model versions (in which case only the first one is used).
|
|
27
33
|
label: str, optional
|
|
28
|
-
Instance label.
|
|
34
|
+
Instance label.
|
|
35
|
+
overwrite_model_parameters: str, optional
|
|
36
|
+
File name to overwrite model parameters from DB with provided values.
|
|
37
|
+
ignore_software_version: bool, optional
|
|
38
|
+
If True, ignore software version checks for deprecated parameters.
|
|
29
39
|
"""
|
|
30
40
|
|
|
31
41
|
def __init__(
|
|
32
42
|
self,
|
|
33
|
-
site
|
|
34
|
-
|
|
35
|
-
model_version
|
|
36
|
-
label
|
|
43
|
+
site,
|
|
44
|
+
db_config,
|
|
45
|
+
model_version,
|
|
46
|
+
label=None,
|
|
47
|
+
overwrite_model_parameters=None,
|
|
48
|
+
ignore_software_version=False,
|
|
37
49
|
):
|
|
38
50
|
"""Initialize SiteModel."""
|
|
39
51
|
self._logger = logging.getLogger(__name__)
|
|
40
52
|
self._logger.debug("Init SiteModel for site %s", site)
|
|
41
53
|
super().__init__(
|
|
42
54
|
site=site,
|
|
43
|
-
|
|
55
|
+
db_config=db_config,
|
|
44
56
|
model_version=model_version,
|
|
45
|
-
db=None,
|
|
46
57
|
label=label,
|
|
47
58
|
collection="sites",
|
|
59
|
+
overwrite_model_parameters=overwrite_model_parameters,
|
|
60
|
+
ignore_software_version=ignore_software_version,
|
|
48
61
|
)
|
|
49
62
|
|
|
50
|
-
def get_reference_point(self)
|
|
63
|
+
def get_reference_point(self):
|
|
51
64
|
"""
|
|
52
|
-
Get reference point coordinates
|
|
65
|
+
Get reference point coordinates.
|
|
66
|
+
|
|
67
|
+
Ground coordinates are calculated relative to this point.
|
|
53
68
|
|
|
54
69
|
Returns
|
|
55
70
|
-------
|
|
56
71
|
dict
|
|
57
|
-
Reference point coordinates
|
|
72
|
+
Reference point coordinates.
|
|
58
73
|
"""
|
|
59
74
|
return {
|
|
60
75
|
"center_altitude": self.get_parameter_value_with_unit("reference_point_altitude"),
|
|
@@ -63,13 +78,12 @@ class SiteModel(ModelParameter):
|
|
|
63
78
|
"epsg_code": self.get_parameter_value("epsg_code"),
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
def get_corsika_site_parameters(
|
|
67
|
-
self, config_file_style: bool = False, model_directory: Path | None = None
|
|
68
|
-
) -> dict:
|
|
81
|
+
def get_corsika_site_parameters(self, config_file_style=False, model_directory=None):
|
|
69
82
|
"""
|
|
70
|
-
Get site-related CORSIKA parameters
|
|
83
|
+
Get site-related CORSIKA parameters.
|
|
71
84
|
|
|
72
|
-
Parameters are returned with units wherever possible
|
|
85
|
+
Parameters are returned with units wherever possible ('config_file_style=False')
|
|
86
|
+
or in CORSIKA-expected coordinates.
|
|
73
87
|
|
|
74
88
|
Parameters
|
|
75
89
|
----------
|
|
@@ -81,7 +95,7 @@ class SiteModel(ModelParameter):
|
|
|
81
95
|
Returns
|
|
82
96
|
-------
|
|
83
97
|
dict
|
|
84
|
-
Site-related CORSIKA parameters
|
|
98
|
+
Site-related CORSIKA parameters.
|
|
85
99
|
"""
|
|
86
100
|
if config_file_style:
|
|
87
101
|
model_directory = model_directory or Path()
|
|
@@ -110,7 +124,7 @@ class SiteModel(ModelParameter):
|
|
|
110
124
|
"geomag_rotation": self.get_parameter_value_with_unit("geomag_rotation"),
|
|
111
125
|
}
|
|
112
126
|
|
|
113
|
-
def get_array_elements_for_layout(self, layout_name
|
|
127
|
+
def get_array_elements_for_layout(self, layout_name):
|
|
114
128
|
"""
|
|
115
129
|
Return list of array elements for a given array layout.
|
|
116
130
|
|
|
@@ -130,7 +144,27 @@ class SiteModel(ModelParameter):
|
|
|
130
144
|
return layout["elements"]
|
|
131
145
|
raise ValueError(f"Array layout '{layout_name}' not found in '{self.site}' site model.")
|
|
132
146
|
|
|
133
|
-
def
|
|
147
|
+
def get_array_elements_of_type(self, array_element_type):
|
|
148
|
+
"""
|
|
149
|
+
Get all array elements of a given type.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
array_element_type : str
|
|
154
|
+
Type of the array element (e.g. LSTN, MSTS)
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
dict
|
|
159
|
+
Dict with array elements.
|
|
160
|
+
"""
|
|
161
|
+
return self.db.get_array_elements_of_type(
|
|
162
|
+
array_element_type=array_element_type,
|
|
163
|
+
model_version=self.model_version,
|
|
164
|
+
collection="telescopes",
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def get_list_of_array_layouts(self):
|
|
134
168
|
"""
|
|
135
169
|
Get list of available array layouts.
|
|
136
170
|
|
|
@@ -141,13 +175,9 @@ class SiteModel(ModelParameter):
|
|
|
141
175
|
"""
|
|
142
176
|
return [layout["name"] for layout in self.get_parameter_value("array_layouts")]
|
|
143
177
|
|
|
144
|
-
def export_atmospheric_transmission_file(self, model_directory
|
|
178
|
+
def export_atmospheric_transmission_file(self, model_directory):
|
|
145
179
|
"""
|
|
146
|
-
Export atmospheric transmission file.
|
|
147
|
-
|
|
148
|
-
This method is needed because when CORSIKA is not piped to sim_telarray,
|
|
149
|
-
the atmospheric transmission file is not written out to the model directory.
|
|
150
|
-
This method allows to export it explicitly.
|
|
180
|
+
Export atmospheric transmission file from database to the given directory.
|
|
151
181
|
|
|
152
182
|
Parameters
|
|
153
183
|
----------
|
|
@@ -13,8 +13,6 @@ from simtools.model.mirrors import Mirrors
|
|
|
13
13
|
from simtools.model.model_parameter import InvalidModelParameterError, ModelParameter
|
|
14
14
|
from simtools.utils import names
|
|
15
15
|
|
|
16
|
-
__all__ = ["TelescopeModel"]
|
|
17
|
-
|
|
18
16
|
|
|
19
17
|
class TelescopeModel(ModelParameter):
|
|
20
18
|
"""
|
|
@@ -28,30 +26,37 @@ class TelescopeModel(ModelParameter):
|
|
|
28
26
|
Site name (e.g., South or North).
|
|
29
27
|
telescope_name: str
|
|
30
28
|
Telescope name (ex. LSTN-01, LSTN-design, ...).
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
db_config: dict
|
|
30
|
+
Database configuration.
|
|
33
31
|
model_version: str
|
|
34
32
|
Model version.
|
|
35
33
|
label: str, optional
|
|
36
|
-
Instance label.
|
|
34
|
+
Instance label.
|
|
35
|
+
overwrite_model_parameters: str, optional
|
|
36
|
+
File name to overwrite model parameters from DB with provided values.
|
|
37
|
+
ignore_software_version: bool, optional
|
|
38
|
+
If True, ignore software version checks for deprecated parameters.
|
|
37
39
|
"""
|
|
38
40
|
|
|
39
41
|
def __init__(
|
|
40
42
|
self,
|
|
41
|
-
site
|
|
42
|
-
telescope_name
|
|
43
|
-
|
|
44
|
-
model_version
|
|
45
|
-
label
|
|
43
|
+
site,
|
|
44
|
+
telescope_name,
|
|
45
|
+
db_config,
|
|
46
|
+
model_version,
|
|
47
|
+
label=None,
|
|
48
|
+
overwrite_model_parameters=None,
|
|
49
|
+
ignore_software_version=False,
|
|
46
50
|
):
|
|
47
51
|
"""Initialize TelescopeModel."""
|
|
48
52
|
super().__init__(
|
|
49
53
|
site=site,
|
|
50
54
|
array_element_name=telescope_name,
|
|
51
|
-
|
|
55
|
+
db_config=db_config,
|
|
52
56
|
model_version=model_version,
|
|
53
|
-
db=None,
|
|
54
57
|
label=label,
|
|
58
|
+
overwrite_model_parameters=overwrite_model_parameters,
|
|
59
|
+
ignore_software_version=ignore_software_version,
|
|
55
60
|
)
|
|
56
61
|
|
|
57
62
|
self._logger = logging.getLogger(__name__)
|
|
@@ -144,7 +149,7 @@ class TelescopeModel(ModelParameter):
|
|
|
144
149
|
except TypeError as exc:
|
|
145
150
|
raise TypeError("Undefined mirror list") from exc
|
|
146
151
|
|
|
147
|
-
self._mirrors = Mirrors(mirror_list_file, parameters=self.
|
|
152
|
+
self._mirrors = Mirrors(mirror_list_file, parameters=self.parameters)
|
|
148
153
|
|
|
149
154
|
def get_telescope_effective_focal_length(
|
|
150
155
|
self, unit: str = "m", return_focal_length_if_zero: bool = False
|
|
@@ -376,8 +381,9 @@ class TelescopeModel(ModelParameter):
|
|
|
376
381
|
try:
|
|
377
382
|
return self.get_parameter_value_with_unit(f"array_element_position_{coordinate_system}")
|
|
378
383
|
except InvalidModelParameterError as exc:
|
|
379
|
-
|
|
380
|
-
|
|
384
|
+
raise InvalidModelParameterError(
|
|
385
|
+
f"Coordinate system {coordinate_system} not found."
|
|
386
|
+
) from exc
|
|
381
387
|
|
|
382
388
|
def get_calibration_device_name(self, device_type):
|
|
383
389
|
"""
|
|
@@ -81,10 +81,10 @@ class MirrorPanelPSF:
|
|
|
81
81
|
mirror_list_file = gen.find_file(
|
|
82
82
|
name=self.args_dict["mirror_list"], loc=self.args_dict["model_path"]
|
|
83
83
|
)
|
|
84
|
-
tel_model.
|
|
85
|
-
tel_model.
|
|
84
|
+
tel_model.overwrite_model_parameter("mirror_list", self.args_dict["mirror_list"])
|
|
85
|
+
tel_model.overwrite_model_file("mirror_list", mirror_list_file)
|
|
86
86
|
if self.args_dict["random_focal_length"] is not None:
|
|
87
|
-
tel_model.
|
|
87
|
+
tel_model.overwrite_model_parameter(
|
|
88
88
|
"random_focal_length", str(self.args_dict["random_focal_length"])
|
|
89
89
|
)
|
|
90
90
|
|
|
@@ -221,7 +221,7 @@ class MirrorPanelPSF:
|
|
|
221
221
|
sig_d80: float
|
|
222
222
|
Standard deviation of D80 in cm.
|
|
223
223
|
"""
|
|
224
|
-
self.telescope_model.
|
|
224
|
+
self.telescope_model.overwrite_model_parameter("mirror_reflection_random_angle", rnda)
|
|
225
225
|
ray = RayTracing(
|
|
226
226
|
telescope_model=self.telescope_model,
|
|
227
227
|
site_model=self.site_model,
|
|
@@ -95,7 +95,7 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars):
|
|
|
95
95
|
if pars is None:
|
|
96
96
|
raise ValueError("No best parameters found")
|
|
97
97
|
|
|
98
|
-
tel_model.
|
|
98
|
+
tel_model.overwrite_parameters(pars)
|
|
99
99
|
ray = RayTracing(
|
|
100
100
|
telescope_model=tel_model,
|
|
101
101
|
site_model=site_model,
|