gammasimtools 0.9.0__py3-none-any.whl → 0.10.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.9.0.dist-info → gammasimtools-0.10.0.dist-info}/METADATA +2 -2
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.10.0.dist-info}/RECORD +94 -85
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.10.0.dist-info}/entry_points.txt +2 -1
- simtools/_version.py +2 -2
- simtools/applications/calculate_trigger_rate.py +15 -38
- simtools/applications/convert_all_model_parameters_from_simtel.py +9 -28
- simtools/applications/convert_geo_coordinates_of_array_elements.py +47 -45
- simtools/applications/convert_model_parameter_from_simtel.py +2 -2
- simtools/applications/db_add_file_to_db.py +1 -2
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +110 -0
- simtools/applications/db_add_value_from_json_to_db.py +1 -2
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +6 -6
- simtools/applications/db_get_file_from_db.py +11 -12
- simtools/applications/db_get_parameter_from_db.py +44 -32
- simtools/applications/derive_photon_electron_spectrum.py +99 -0
- simtools/applications/generate_array_config.py +17 -17
- simtools/applications/generate_regular_arrays.py +15 -15
- simtools/applications/generate_simtel_array_histograms.py +11 -48
- simtools/applications/production_generate_simulation_config.py +25 -7
- simtools/applications/production_scale_events.py +2 -2
- simtools/applications/simulate_prod.py +1 -1
- simtools/applications/simulate_prod_htcondor_generator.py +26 -26
- simtools/applications/submit_data_from_external.py +12 -4
- simtools/applications/submit_model_parameter_from_external.py +8 -6
- simtools/applications/validate_camera_efficiency.py +2 -2
- simtools/applications/validate_file_using_schema.py +23 -19
- simtools/camera/single_photon_electron_spectrum.py +168 -0
- simtools/configuration/commandline_parser.py +8 -1
- simtools/constants.py +10 -3
- simtools/corsika/corsika_config.py +8 -7
- simtools/corsika/corsika_histograms.py +1 -1
- simtools/data_model/data_reader.py +0 -3
- simtools/data_model/metadata_collector.py +3 -4
- simtools/data_model/metadata_model.py +8 -124
- simtools/data_model/model_data_writer.py +17 -63
- simtools/data_model/schema.py +213 -0
- simtools/data_model/validate_data.py +9 -44
- simtools/db/db_handler.py +323 -495
- simtools/db/db_model_upload.py +139 -0
- simtools/io_operations/hdf5_handler.py +54 -24
- simtools/layout/array_layout.py +33 -28
- simtools/model/array_model.py +13 -7
- simtools/model/model_parameter.py +22 -54
- simtools/model/site_model.py +2 -2
- simtools/production_configuration/calculate_statistical_errors_grid_point.py +119 -144
- simtools/production_configuration/event_scaler.py +7 -17
- simtools/production_configuration/generate_simulation_config.py +5 -32
- simtools/production_configuration/interpolation_handler.py +8 -11
- simtools/runners/corsika_simtel_runner.py +3 -1
- simtools/schemas/input/MST_mirror_2f_measurements.schema.yml +39 -0
- simtools/schemas/input/single_pe_spectrum.schema.yml +38 -0
- simtools/schemas/integration_tests_config.metaschema.yml +10 -0
- simtools/schemas/model_parameter.metaschema.yml +7 -2
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +2 -0
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +1 -1
- simtools/schemas/model_parameters/array_window.schema.yml +37 -0
- simtools/schemas/model_parameters/asum_clipping.schema.yml +0 -4
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_offset.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +0 -2
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +0 -2
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_noise.schema.yml +3 -3
- simtools/schemas/model_parameters/fake_mirror_list.schema.yml +33 -0
- simtools/schemas/model_parameters/laser_photons.schema.yml +2 -2
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/production_configuration_metrics.schema.yml +68 -0
- simtools/schemas/production_tables.schema.yml +41 -0
- simtools/simtel/simtel_config_writer.py +5 -6
- simtools/simtel/simtel_io_histogram.py +32 -67
- simtools/simtel/simtel_io_histograms.py +15 -30
- simtools/simtel/simulator_array.py +2 -1
- simtools/simtel/simulator_camera_efficiency.py +5 -0
- simtools/simtel/simulator_light_emission.py +3 -1
- simtools/simtel/simulator_ray_tracing.py +2 -1
- simtools/testing/helpers.py +6 -13
- simtools/testing/validate_output.py +131 -47
- simtools/utils/general.py +102 -12
- simtools/utils/names.py +24 -20
- simtools/applications/db_add_model_parameters_from_repository_to_db.py +0 -176
- simtools/db/db_array_elements.py +0 -130
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.10.0.dist-info}/LICENSE +0 -0
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.10.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.10.0.dist-info}/top_level.txt +0 -0
- /simtools/{camera_efficiency.py → camera/camera_efficiency.py} +0 -0
simtools/db/db_handler.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
-
from importlib.resources import files
|
|
6
5
|
from pathlib import Path
|
|
7
6
|
from threading import Lock
|
|
8
7
|
|
|
@@ -10,11 +9,9 @@ import gridfs
|
|
|
10
9
|
import jsonschema
|
|
11
10
|
from bson.objectid import ObjectId
|
|
12
11
|
from packaging.version import Version
|
|
13
|
-
from pymongo import
|
|
14
|
-
from pymongo.errors import BulkWriteError
|
|
12
|
+
from pymongo import MongoClient
|
|
15
13
|
|
|
16
14
|
from simtools.data_model import validate_data
|
|
17
|
-
from simtools.db import db_array_elements
|
|
18
15
|
from simtools.io_operations import io_handler
|
|
19
16
|
from simtools.utils import names, value_conversion
|
|
20
17
|
|
|
@@ -66,17 +63,11 @@ class DatabaseHandler:
|
|
|
66
63
|
Dictionary with the MongoDB configuration (see jsonschema_db_dict for details).
|
|
67
64
|
"""
|
|
68
65
|
|
|
69
|
-
DB_CTA_SIMULATION_MODEL_DESCRIPTIONS = "CTA-Simulation-Model-Descriptions"
|
|
70
|
-
# DB collection with updates field names
|
|
71
|
-
DB_DERIVED_VALUES = "Staging-CTA-Simulation-Model-Derived-Values"
|
|
72
|
-
|
|
73
66
|
ALLOWED_FILE_EXTENSIONS = [".dat", ".txt", ".lis", ".cfg", ".yml", ".yaml", ".ecsv"]
|
|
74
67
|
|
|
75
68
|
db_client = None
|
|
76
|
-
|
|
69
|
+
production_table_cached = {}
|
|
77
70
|
model_parameters_cached = {}
|
|
78
|
-
model_versions_cached = {}
|
|
79
|
-
corsika_configuration_parameters_cached = {}
|
|
80
71
|
|
|
81
72
|
def __init__(self, mongo_db_config=None):
|
|
82
73
|
"""Initialize the DatabaseHandler class."""
|
|
@@ -150,12 +141,13 @@ class DatabaseHandler:
|
|
|
150
141
|
|
|
151
142
|
"""
|
|
152
143
|
try:
|
|
153
|
-
|
|
144
|
+
db_simulation_model = self.mongo_db_config["db_simulation_model"]
|
|
145
|
+
if not db_simulation_model.endswith("LATEST"):
|
|
154
146
|
return
|
|
155
|
-
except TypeError:
|
|
147
|
+
except TypeError: # db_simulation_model is None
|
|
156
148
|
return
|
|
157
149
|
|
|
158
|
-
prefix =
|
|
150
|
+
prefix = db_simulation_model.replace("LATEST", "")
|
|
159
151
|
list_of_db_names = self.db_client.list_database_names()
|
|
160
152
|
filtered_list_of_db_names = [s for s in list_of_db_names if s.startswith(prefix)]
|
|
161
153
|
versioned_strings = []
|
|
@@ -180,69 +172,117 @@ class DatabaseHandler:
|
|
|
180
172
|
else:
|
|
181
173
|
raise ValueError("Found LATEST in the DB name but no matching versions found in DB.")
|
|
182
174
|
|
|
175
|
+
def get_model_parameter(
|
|
176
|
+
self,
|
|
177
|
+
parameter,
|
|
178
|
+
parameter_version,
|
|
179
|
+
site,
|
|
180
|
+
array_element_name,
|
|
181
|
+
collection,
|
|
182
|
+
):
|
|
183
|
+
"""
|
|
184
|
+
Get a model parameter using the parameter version.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
parameter: str
|
|
189
|
+
Name of the parameter.
|
|
190
|
+
parameter_version: str
|
|
191
|
+
Version of the parameter.
|
|
192
|
+
site: str
|
|
193
|
+
Site name.
|
|
194
|
+
array_element_name: str
|
|
195
|
+
Name of the array element model (e.g. MSTN, SSTS).
|
|
196
|
+
collection: str
|
|
197
|
+
Collection of array element (e.g. telescopes, calibration_devices).
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
dict containing the parameter
|
|
202
|
+
|
|
203
|
+
"""
|
|
204
|
+
query = {
|
|
205
|
+
"parameter_version": parameter_version,
|
|
206
|
+
"parameter": parameter,
|
|
207
|
+
}
|
|
208
|
+
if array_element_name is not None:
|
|
209
|
+
query["instrument"] = array_element_name
|
|
210
|
+
if site is not None:
|
|
211
|
+
query["site"] = site
|
|
212
|
+
return self._read_mongo_db(query=query, collection_name=collection)
|
|
213
|
+
|
|
183
214
|
def get_model_parameters(
|
|
184
215
|
self,
|
|
185
216
|
site,
|
|
186
217
|
array_element_name,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
only_applicable=False,
|
|
218
|
+
collection,
|
|
219
|
+
model_version=None,
|
|
190
220
|
):
|
|
191
221
|
"""
|
|
192
|
-
Get parameters
|
|
222
|
+
Get model parameters using the model version.
|
|
193
223
|
|
|
194
|
-
|
|
195
|
-
Read parameters for design and for the specified array element (if necessary). This allows
|
|
196
|
-
to overwrite design parameters with specific parameters without having to copy
|
|
197
|
-
all model parameters when changing only a few.
|
|
224
|
+
Queries parameters for design and for the specified array element (if necessary).
|
|
198
225
|
|
|
199
226
|
Parameters
|
|
200
227
|
----------
|
|
201
228
|
site: str
|
|
202
229
|
Site name.
|
|
203
230
|
array_element_name: str
|
|
204
|
-
Name of the array element model (e.g. LSTN-01, MSTS-design)
|
|
205
|
-
model_version: str
|
|
206
|
-
Version of the model.
|
|
231
|
+
Name of the array element model (e.g. LSTN-01, MSTS-design, ILLN-01).
|
|
232
|
+
model_version: str, list
|
|
233
|
+
Version(s) of the model.
|
|
207
234
|
collection: str
|
|
208
|
-
|
|
209
|
-
only_applicable: bool
|
|
210
|
-
If True, only applicable parameters will be read.
|
|
235
|
+
Collection of array element (e.g. telescopes, calibration_devices).
|
|
211
236
|
|
|
212
237
|
Returns
|
|
213
238
|
-------
|
|
214
239
|
dict containing the parameters
|
|
215
|
-
|
|
216
240
|
"""
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
)
|
|
220
|
-
array_element_list = db_array_elements.get_array_element_list_for_db_query(
|
|
221
|
-
_array_element_name, self, _model_version, collection
|
|
241
|
+
model_versions = (
|
|
242
|
+
self.get_model_versions(collection) if model_version is None else [model_version]
|
|
222
243
|
)
|
|
244
|
+
|
|
223
245
|
pars = {}
|
|
224
|
-
for
|
|
225
|
-
|
|
226
|
-
|
|
246
|
+
for _model_version in model_versions:
|
|
247
|
+
production_table = self._read_production_table_from_mongo_db(collection, _model_version)
|
|
248
|
+
array_element_list = self._get_array_element_list(
|
|
249
|
+
array_element_name, site, production_table, collection
|
|
227
250
|
)
|
|
228
|
-
|
|
229
|
-
pars.update(DatabaseHandler.model_parameters_cached[_array_elements_cache_key])
|
|
230
|
-
except KeyError:
|
|
251
|
+
for array_element in array_element_list:
|
|
231
252
|
pars.update(
|
|
232
|
-
self.
|
|
233
|
-
|
|
234
|
-
array_element_name=array_element,
|
|
235
|
-
model_version=_model_version,
|
|
236
|
-
collection_name=collection,
|
|
237
|
-
run_location=None,
|
|
238
|
-
write_files=False,
|
|
239
|
-
only_applicable=only_applicable,
|
|
253
|
+
self._get_parameter_for_model_version(
|
|
254
|
+
array_element, _model_version, site, collection, production_table
|
|
240
255
|
)
|
|
241
256
|
)
|
|
242
|
-
DatabaseHandler.model_parameters_cached[_array_elements_cache_key] = pars
|
|
243
|
-
|
|
244
257
|
return pars
|
|
245
258
|
|
|
259
|
+
def _get_parameter_for_model_version(
|
|
260
|
+
self, array_element, model_version, site, collection, production_table
|
|
261
|
+
):
|
|
262
|
+
cache_key, cache_dict = self._read_cache(
|
|
263
|
+
DatabaseHandler.model_parameters_cached,
|
|
264
|
+
names.validate_site_name(site) if site else None,
|
|
265
|
+
array_element,
|
|
266
|
+
model_version,
|
|
267
|
+
collection,
|
|
268
|
+
)
|
|
269
|
+
if cache_dict:
|
|
270
|
+
self._logger.debug(f"Found {array_element} in cache (key: {cache_key})")
|
|
271
|
+
return cache_dict
|
|
272
|
+
self._logger.debug(f"Did not find {array_element} in cache (key: {cache_key})")
|
|
273
|
+
|
|
274
|
+
try:
|
|
275
|
+
parameter_version_table = production_table["parameters"][array_element]
|
|
276
|
+
except KeyError: # allow missing array elements (parameter dict is checked later)
|
|
277
|
+
return {}
|
|
278
|
+
DatabaseHandler.model_parameters_cached[cache_key] = self._read_mongo_db(
|
|
279
|
+
query=self._get_query_from_parameter_version_table(
|
|
280
|
+
parameter_version_table, array_element, site
|
|
281
|
+
),
|
|
282
|
+
collection_name=collection,
|
|
283
|
+
)
|
|
284
|
+
return DatabaseHandler.model_parameters_cached[cache_key]
|
|
285
|
+
|
|
246
286
|
def get_collection(self, db_name, collection_name):
|
|
247
287
|
"""
|
|
248
288
|
Get a collection from the DB.
|
|
@@ -263,99 +303,102 @@ class DatabaseHandler:
|
|
|
263
303
|
db_name = self._get_db_name(db_name)
|
|
264
304
|
return DatabaseHandler.db_client[db_name][collection_name]
|
|
265
305
|
|
|
266
|
-
def
|
|
306
|
+
def get_collections(self, db_name=None, model_collections_only=False):
|
|
267
307
|
"""
|
|
268
|
-
|
|
308
|
+
List of collections in the DB.
|
|
269
309
|
|
|
270
310
|
Parameters
|
|
271
311
|
----------
|
|
272
312
|
db_name: str
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
file_name: str
|
|
277
|
-
Name of the file to get.
|
|
313
|
+
Database name.
|
|
314
|
+
model_collections_only: bool
|
|
315
|
+
If True, only return model collections (i.e. exclude fs.files, fs.chunks)
|
|
278
316
|
|
|
279
317
|
Returns
|
|
280
318
|
-------
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
Raises
|
|
285
|
-
------
|
|
286
|
-
FileNotFoundError
|
|
287
|
-
If the desired file is not found.
|
|
319
|
+
list
|
|
320
|
+
List of collection names
|
|
288
321
|
|
|
289
322
|
"""
|
|
290
|
-
db_name = self._get_db_name(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
323
|
+
db_name = db_name or self._get_db_name()
|
|
324
|
+
if db_name not in self.list_of_collections:
|
|
325
|
+
self.list_of_collections[db_name] = DatabaseHandler.db_client[
|
|
326
|
+
db_name
|
|
327
|
+
].list_collection_names()
|
|
328
|
+
collections = self.list_of_collections[db_name]
|
|
329
|
+
if model_collections_only:
|
|
330
|
+
return [collection for collection in collections if not collection.startswith("fs.")]
|
|
331
|
+
return collections
|
|
296
332
|
|
|
297
|
-
def export_model_files(self, parameters, dest):
|
|
333
|
+
def export_model_files(self, parameters=None, file_names=None, dest=None, db_name=None):
|
|
298
334
|
"""
|
|
299
|
-
Export
|
|
335
|
+
Export files from the DB to the model directory.
|
|
336
|
+
|
|
337
|
+
The files to be exported can be specified by file_name or retrieved from the database
|
|
338
|
+
using the parameters dictionary.
|
|
300
339
|
|
|
301
340
|
Parameters
|
|
302
341
|
----------
|
|
303
342
|
parameters: dict
|
|
304
|
-
Dict of model parameters
|
|
343
|
+
Dict of model parameters
|
|
344
|
+
file_names: list, str
|
|
345
|
+
List (or string) of file names to export
|
|
305
346
|
dest: str or Path
|
|
306
347
|
Location where to write the files to.
|
|
307
348
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
349
|
+
Returns
|
|
350
|
+
-------
|
|
351
|
+
file_id: dict of GridOut._id
|
|
352
|
+
Dict of database IDs of files.
|
|
313
353
|
"""
|
|
314
|
-
|
|
315
|
-
for info in parameters.values():
|
|
316
|
-
if not info or not info.get("file") or info["value"] is None:
|
|
317
|
-
continue
|
|
318
|
-
if Path(dest).joinpath(info["value"]).exists():
|
|
319
|
-
continue
|
|
320
|
-
file = self._get_file_mongo_db(self._get_db_name(), info["value"])
|
|
321
|
-
self._write_file_from_mongo_to_disk(self._get_db_name(), dest, file)
|
|
354
|
+
db_name = self._get_db_name(db_name)
|
|
322
355
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
356
|
+
if file_names:
|
|
357
|
+
file_names = [file_names] if not isinstance(file_names, list) else file_names
|
|
358
|
+
elif parameters:
|
|
359
|
+
file_names = [
|
|
360
|
+
info["value"]
|
|
361
|
+
for info in parameters.values()
|
|
362
|
+
if info and info.get("file") and info["value"] is not None
|
|
363
|
+
]
|
|
327
364
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
365
|
+
instance_ids = {}
|
|
366
|
+
for file_name in file_names:
|
|
367
|
+
if Path(dest).joinpath(file_name).exists():
|
|
368
|
+
instance_ids[file_name] = "file exists"
|
|
369
|
+
else:
|
|
370
|
+
file_path_instance = self._get_file_mongo_db(self._get_db_name(), file_name)
|
|
371
|
+
self._write_file_from_mongo_to_disk(self._get_db_name(), dest, file_path_instance)
|
|
372
|
+
instance_ids[file_name] = file_path_instance._id # pylint: disable=protected-access
|
|
373
|
+
return instance_ids
|
|
374
|
+
|
|
375
|
+
def _get_query_from_parameter_version_table(
|
|
376
|
+
self, parameter_version_table, array_element_name, site
|
|
337
377
|
):
|
|
338
|
-
"""
|
|
339
|
-
|
|
378
|
+
"""Return query based on parameter version table."""
|
|
379
|
+
query_dict = {
|
|
380
|
+
"$or": [
|
|
381
|
+
{"parameter": param, "parameter_version": version}
|
|
382
|
+
for param, version in parameter_version_table.items()
|
|
383
|
+
],
|
|
384
|
+
}
|
|
385
|
+
# 'xSTX-design' is a placeholder to ignore 'instrument' field in query.
|
|
386
|
+
if array_element_name and array_element_name != "xSTx-design":
|
|
387
|
+
query_dict["instrument"] = array_element_name
|
|
388
|
+
if site:
|
|
389
|
+
query_dict["site"] = site
|
|
390
|
+
return query_dict
|
|
340
391
|
|
|
341
|
-
|
|
392
|
+
def _read_mongo_db(self, query, collection_name):
|
|
393
|
+
"""
|
|
394
|
+
Query MongoDB.
|
|
342
395
|
|
|
343
396
|
Parameters
|
|
344
397
|
----------
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
array_element_name: str
|
|
348
|
-
Name of the array element model (e.g. MSTN-design ...)
|
|
349
|
-
model_version: str
|
|
350
|
-
Version of the model.
|
|
351
|
-
run_location: Path or str
|
|
352
|
-
The sim_telarray run location to write the tabulated data files into.
|
|
398
|
+
query: dict
|
|
399
|
+
Query to execute.
|
|
353
400
|
collection_name: str
|
|
354
|
-
|
|
355
|
-
write_files: bool
|
|
356
|
-
If true, write the files to the run_location.
|
|
357
|
-
only_applicable: bool
|
|
358
|
-
If True, only applicable parameters will be read.
|
|
401
|
+
Collection name.
|
|
359
402
|
|
|
360
403
|
Returns
|
|
361
404
|
-------
|
|
@@ -364,154 +407,127 @@ class DatabaseHandler:
|
|
|
364
407
|
Raises
|
|
365
408
|
------
|
|
366
409
|
ValueError
|
|
367
|
-
if query returned
|
|
368
|
-
|
|
410
|
+
if query returned no results.
|
|
369
411
|
"""
|
|
412
|
+
db_name = self._get_db_name()
|
|
370
413
|
collection = self.get_collection(db_name, collection_name)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
query = {
|
|
374
|
-
"instrument": array_element_name,
|
|
375
|
-
"version": self.model_version(model_version, db_name),
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if only_applicable:
|
|
379
|
-
query["applicable"] = True
|
|
380
|
-
if collection.count_documents(query) < 1:
|
|
414
|
+
posts = list(collection.find(query))
|
|
415
|
+
if not posts:
|
|
381
416
|
raise ValueError(
|
|
382
|
-
"The following query returned zero results
|
|
383
|
-
query,
|
|
417
|
+
f"The following query for {collection_name} returned zero results: {query} "
|
|
384
418
|
)
|
|
385
|
-
|
|
419
|
+
parameters = {}
|
|
420
|
+
for post in posts:
|
|
386
421
|
par_now = post["parameter"]
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
_parameters[par_now]["entry_date"] = ObjectId(post["_id"]).generation_time
|
|
391
|
-
if _parameters[par_now]["file"] and write_files:
|
|
392
|
-
file = self._get_file_mongo_db(db_name, _parameters[par_now]["value"])
|
|
393
|
-
self._write_file_from_mongo_to_disk(db_name, run_location, file)
|
|
422
|
+
parameters[par_now] = post
|
|
423
|
+
parameters[par_now]["entry_date"] = ObjectId(post["_id"]).generation_time
|
|
424
|
+
return {k: parameters[k] for k in sorted(parameters)}
|
|
394
425
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
def get_site_parameters(
|
|
398
|
-
self,
|
|
399
|
-
site,
|
|
400
|
-
model_version,
|
|
401
|
-
only_applicable=False,
|
|
402
|
-
):
|
|
426
|
+
def _read_production_table_from_mongo_db(self, collection_name, model_version):
|
|
403
427
|
"""
|
|
404
|
-
|
|
428
|
+
Read production table from MongoDB.
|
|
405
429
|
|
|
406
430
|
Parameters
|
|
407
431
|
----------
|
|
408
|
-
|
|
409
|
-
|
|
432
|
+
collection_name: str
|
|
433
|
+
Name of the collection.
|
|
410
434
|
model_version: str
|
|
411
435
|
Version of the model.
|
|
412
|
-
only_applicable: bool
|
|
413
|
-
If True, only applicable parameters will be read.
|
|
414
|
-
|
|
415
|
-
Returns
|
|
416
|
-
-------
|
|
417
|
-
dict containing the parameters
|
|
418
436
|
|
|
437
|
+
Raises
|
|
438
|
+
------
|
|
439
|
+
ValueError
|
|
440
|
+
if query returned no results.
|
|
419
441
|
"""
|
|
420
|
-
_site, _, _model_version = self._validate_model_input(site, None, model_version)
|
|
421
|
-
_db_name = self._get_db_name()
|
|
422
|
-
_site_cache_key = self._parameter_cache_key(site, None, model_version)
|
|
423
442
|
try:
|
|
424
|
-
return DatabaseHandler.
|
|
443
|
+
return DatabaseHandler.production_table_cached[
|
|
444
|
+
self._cache_key(None, None, model_version, collection_name)
|
|
445
|
+
]
|
|
425
446
|
except KeyError:
|
|
426
447
|
pass
|
|
427
448
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
449
|
+
query = {"model_version": model_version, "collection": collection_name}
|
|
450
|
+
collection = self.get_collection(self._get_db_name(), "production_tables")
|
|
451
|
+
post = collection.find_one(query)
|
|
452
|
+
if not post:
|
|
453
|
+
raise ValueError(f"The following query returned zero results: {query}")
|
|
454
|
+
|
|
455
|
+
return {
|
|
456
|
+
"collection": post["collection"],
|
|
457
|
+
"model_version": post["model_version"],
|
|
458
|
+
"parameters": post["parameters"],
|
|
459
|
+
"design_model": post.get("design_model", {}),
|
|
460
|
+
"entry_date": ObjectId(post["_id"]).generation_time,
|
|
461
|
+
}
|
|
437
462
|
|
|
438
|
-
def
|
|
463
|
+
def get_model_versions(self, collection_name="telescopes"):
|
|
439
464
|
"""
|
|
440
|
-
Get
|
|
465
|
+
Get list of model versions from the DB.
|
|
441
466
|
|
|
442
467
|
Parameters
|
|
443
468
|
----------
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
site: str
|
|
447
|
-
Site name.
|
|
448
|
-
model_version: str
|
|
449
|
-
Version of the model.
|
|
450
|
-
only_applicable: bool
|
|
451
|
-
If True, only applicable parameters will be read.
|
|
469
|
+
collection_name: str
|
|
470
|
+
Name of the collection.
|
|
452
471
|
|
|
453
472
|
Returns
|
|
454
473
|
-------
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
Raises
|
|
458
|
-
------
|
|
459
|
-
ValueError
|
|
460
|
-
if query returned zero results.
|
|
461
|
-
|
|
474
|
+
list
|
|
475
|
+
List of model versions
|
|
462
476
|
"""
|
|
463
|
-
collection = self.get_collection(
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
"site": site,
|
|
468
|
-
"version": model_version,
|
|
469
|
-
}
|
|
470
|
-
if only_applicable:
|
|
471
|
-
query["applicable"] = True
|
|
472
|
-
if collection.count_documents(query) < 1:
|
|
473
|
-
raise ValueError(
|
|
474
|
-
"The following query returned zero results! Check the input data and rerun.\n",
|
|
475
|
-
query,
|
|
476
|
-
)
|
|
477
|
-
for post in collection.find(query).sort("parameter", ASCENDING):
|
|
478
|
-
par_now = post["parameter"]
|
|
479
|
-
_parameters[par_now] = post
|
|
480
|
-
_parameters[par_now].pop("parameter", None)
|
|
481
|
-
_parameters[par_now].pop("site", None)
|
|
482
|
-
_parameters[par_now]["entry_date"] = ObjectId(post["_id"]).generation_time
|
|
483
|
-
|
|
484
|
-
return _parameters
|
|
477
|
+
collection = self.get_collection(self._get_db_name(), "production_tables")
|
|
478
|
+
return sorted(
|
|
479
|
+
[post["model_version"] for post in collection.find({"collection": collection_name})]
|
|
480
|
+
)
|
|
485
481
|
|
|
486
|
-
def
|
|
482
|
+
def get_array_elements(self, model_version, collection="telescopes"):
|
|
487
483
|
"""
|
|
488
|
-
Get
|
|
484
|
+
Get list array elements for a given model version and collection from the DB.
|
|
489
485
|
|
|
490
486
|
Parameters
|
|
491
487
|
----------
|
|
492
|
-
site: str
|
|
493
|
-
Site name.
|
|
494
|
-
array_element_name: str
|
|
495
|
-
Name of the array element model (e.g. MSTN, SSTS).
|
|
496
488
|
model_version: str
|
|
497
489
|
Version of the model.
|
|
490
|
+
collection: str
|
|
491
|
+
Which collection to get the array elements from:
|
|
492
|
+
i.e. telescopes, calibration_devices.
|
|
498
493
|
|
|
499
494
|
Returns
|
|
500
495
|
-------
|
|
501
|
-
|
|
496
|
+
list
|
|
497
|
+
Sorted list of all array elements found in collection
|
|
498
|
+
"""
|
|
499
|
+
production_table = self._read_production_table_from_mongo_db(collection, model_version)
|
|
500
|
+
return sorted([entry for entry in production_table["parameters"] if "-design" not in entry])
|
|
502
501
|
|
|
502
|
+
def get_array_elements_of_type(self, array_element_type, model_version, collection):
|
|
503
503
|
"""
|
|
504
|
-
|
|
505
|
-
site, array_element_name, model_version
|
|
506
|
-
)
|
|
504
|
+
Get array elements of a certain type (e.g. 'LSTN') for a DB collection.
|
|
507
505
|
|
|
508
|
-
return
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
506
|
+
Does not return 'design' models.
|
|
507
|
+
|
|
508
|
+
Parameters
|
|
509
|
+
----------
|
|
510
|
+
array_element_type: str
|
|
511
|
+
Type of the array element (e.g. LSTN, MSTS).
|
|
512
|
+
model_version: str
|
|
513
|
+
Version of the model.
|
|
514
|
+
collection: str
|
|
515
|
+
Which collection to get the array elements from:
|
|
516
|
+
i.e. telescopes, calibration_devices.
|
|
517
|
+
|
|
518
|
+
Returns
|
|
519
|
+
-------
|
|
520
|
+
list
|
|
521
|
+
Sorted list of all array element names found in collection
|
|
522
|
+
"""
|
|
523
|
+
production_table = self._read_production_table_from_mongo_db(collection, model_version)
|
|
524
|
+
all_array_elements = production_table["parameters"]
|
|
525
|
+
return sorted(
|
|
526
|
+
[
|
|
527
|
+
entry
|
|
528
|
+
for entry in all_array_elements
|
|
529
|
+
if entry.startswith(array_element_type) and "-design" not in entry
|
|
530
|
+
]
|
|
515
531
|
)
|
|
516
532
|
|
|
517
533
|
def get_simulation_configuration_parameters(
|
|
@@ -541,63 +557,24 @@ class DatabaseHandler:
|
|
|
541
557
|
if simulation_software is not valid.
|
|
542
558
|
"""
|
|
543
559
|
if simulation_software == "corsika":
|
|
544
|
-
return self.
|
|
560
|
+
return self.get_model_parameters(
|
|
561
|
+
None,
|
|
562
|
+
None,
|
|
563
|
+
model_version=model_version,
|
|
564
|
+
collection="configuration_corsika",
|
|
565
|
+
)
|
|
545
566
|
if simulation_software == "simtel":
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
site,
|
|
567
|
+
return (
|
|
568
|
+
self.get_model_parameters(
|
|
569
|
+
site,
|
|
570
|
+
array_element_name,
|
|
571
|
+
model_version=model_version,
|
|
572
|
+
collection="configuration_sim_telarray",
|
|
549
573
|
)
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
def get_corsika_configuration_parameters(self, model_version):
|
|
554
|
-
"""
|
|
555
|
-
Get CORSIKA configuration parameters from the DB.
|
|
556
|
-
|
|
557
|
-
Parameters
|
|
558
|
-
----------
|
|
559
|
-
model_version : str
|
|
560
|
-
Version of the model.
|
|
561
|
-
|
|
562
|
-
Returns
|
|
563
|
-
-------
|
|
564
|
-
dict
|
|
565
|
-
Configuration parameters for CORSIKA
|
|
566
|
-
"""
|
|
567
|
-
_corsika_cache_key = self._parameter_cache_key(None, None, model_version)
|
|
568
|
-
try:
|
|
569
|
-
return DatabaseHandler.corsika_configuration_parameters_cached[_corsika_cache_key]
|
|
570
|
-
except KeyError:
|
|
571
|
-
pass
|
|
572
|
-
DatabaseHandler.corsika_configuration_parameters_cached[_corsika_cache_key] = (
|
|
573
|
-
self.read_mongo_db(
|
|
574
|
-
db_name=self._get_db_name(),
|
|
575
|
-
array_element_name=None,
|
|
576
|
-
model_version=model_version,
|
|
577
|
-
run_location=None,
|
|
578
|
-
collection_name="configuration_corsika",
|
|
579
|
-
write_files=False,
|
|
574
|
+
if site and array_element_name
|
|
575
|
+
else {}
|
|
580
576
|
)
|
|
581
|
-
)
|
|
582
|
-
return DatabaseHandler.corsika_configuration_parameters_cached[_corsika_cache_key]
|
|
583
|
-
|
|
584
|
-
def _validate_model_input(self, site, array_element_name, model_version):
|
|
585
|
-
"""
|
|
586
|
-
Validate input for model parameter queries.
|
|
587
|
-
|
|
588
|
-
site: str
|
|
589
|
-
Site name.
|
|
590
|
-
array_element_name: str
|
|
591
|
-
Name of the array element model (e.g. LSTN-01, MSTS-design)
|
|
592
|
-
model_version: str
|
|
593
|
-
Version of the model.
|
|
594
|
-
|
|
595
|
-
"""
|
|
596
|
-
return (
|
|
597
|
-
names.validate_site_name(site),
|
|
598
|
-
names.validate_array_element_name(array_element_name) if array_element_name else None,
|
|
599
|
-
self.model_version(model_version),
|
|
600
|
-
)
|
|
577
|
+
raise ValueError(f"Unknown simulation software: {simulation_software}")
|
|
601
578
|
|
|
602
579
|
@staticmethod
|
|
603
580
|
def _get_file_mongo_db(db_name, file_name):
|
|
@@ -648,76 +625,22 @@ class DatabaseHandler:
|
|
|
648
625
|
with open(Path(path).joinpath(file.filename), "wb") as output_file:
|
|
649
626
|
fs_output.download_to_stream_by_name(file.filename, output_file)
|
|
650
627
|
|
|
651
|
-
def
|
|
652
|
-
self,
|
|
653
|
-
db_name,
|
|
654
|
-
element_to_copy,
|
|
655
|
-
version_to_copy,
|
|
656
|
-
new_array_element_name,
|
|
657
|
-
collection_name="telescopes",
|
|
658
|
-
db_to_copy_to=None,
|
|
659
|
-
collection_to_copy_to=None,
|
|
660
|
-
):
|
|
628
|
+
def add_production_table(self, db_name, production_table):
|
|
661
629
|
"""
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
Only a specific version is copied.
|
|
665
|
-
This function should be rarely used and is intended to simplify unit tests.
|
|
630
|
+
Add a production table to the DB.
|
|
666
631
|
|
|
667
632
|
Parameters
|
|
668
633
|
----------
|
|
669
634
|
db_name: str
|
|
670
|
-
the name of the DB
|
|
671
|
-
|
|
672
|
-
The
|
|
673
|
-
version_to_copy: str
|
|
674
|
-
The version of the configuration to copy
|
|
675
|
-
new_array_element_name: str
|
|
676
|
-
The name of the new array element
|
|
677
|
-
collection_name: str
|
|
678
|
-
The name of the collection to copy from.
|
|
679
|
-
db_to_copy_to: str
|
|
680
|
-
The name of the DB to copy to.
|
|
681
|
-
collection_to_copy_to: str
|
|
682
|
-
The name of the collection to copy to.
|
|
683
|
-
|
|
684
|
-
Raises
|
|
685
|
-
------
|
|
686
|
-
BulkWriteError
|
|
687
|
-
|
|
635
|
+
the name of the DB.
|
|
636
|
+
production_table: dict
|
|
637
|
+
The production table to add to the DB.
|
|
688
638
|
"""
|
|
689
639
|
db_name = self._get_db_name(db_name)
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
collection_to_copy_to = collection_name
|
|
695
|
-
|
|
696
|
-
self._logger.info(
|
|
697
|
-
f"Copying version {version_to_copy} of {element_to_copy} "
|
|
698
|
-
f"to the new array element {new_array_element_name} in the {db_to_copy_to} DB"
|
|
699
|
-
)
|
|
700
|
-
|
|
701
|
-
collection = self.get_collection(db_name, collection_name)
|
|
702
|
-
db_entries = []
|
|
703
|
-
|
|
704
|
-
_version_to_copy = self.model_version(version_to_copy)
|
|
705
|
-
|
|
706
|
-
query = {
|
|
707
|
-
"instrument": element_to_copy,
|
|
708
|
-
"version": _version_to_copy,
|
|
709
|
-
}
|
|
710
|
-
for post in collection.find(query):
|
|
711
|
-
post["instrument"] = new_array_element_name
|
|
712
|
-
post.pop("_id", None)
|
|
713
|
-
db_entries.append(post)
|
|
714
|
-
|
|
715
|
-
self._logger.info(f"Creating new array element {new_array_element_name}")
|
|
716
|
-
collection = self.get_collection(db_to_copy_to, collection_to_copy_to)
|
|
717
|
-
try:
|
|
718
|
-
collection.insert_many(db_entries)
|
|
719
|
-
except BulkWriteError as exc:
|
|
720
|
-
raise BulkWriteError(str(exc.details)) from exc
|
|
640
|
+
collection = self.get_collection(db_name, "production_tables")
|
|
641
|
+
self._logger.info(f"Adding production for {production_table.get('collection')} to to DB")
|
|
642
|
+
collection.insert_one(production_table)
|
|
643
|
+
DatabaseHandler.production_table_cached.clear()
|
|
721
644
|
|
|
722
645
|
def add_new_parameter(
|
|
723
646
|
self,
|
|
@@ -727,7 +650,7 @@ class DatabaseHandler:
|
|
|
727
650
|
file_prefix=None,
|
|
728
651
|
):
|
|
729
652
|
"""
|
|
730
|
-
Add a parameter dictionary
|
|
653
|
+
Add a new parameter dictionary to the DB.
|
|
731
654
|
|
|
732
655
|
A new document will be added to the DB, with all fields taken from the input parameters.
|
|
733
656
|
Parameter dictionaries are validated before submission using the corresponding schema.
|
|
@@ -743,13 +666,7 @@ class DatabaseHandler:
|
|
|
743
666
|
file_prefix: str or Path
|
|
744
667
|
where to find files to upload to the DB
|
|
745
668
|
"""
|
|
746
|
-
|
|
747
|
-
schema_file=files("simtools")
|
|
748
|
-
/ f"schemas/model_parameters/{par_dict['parameter']}.schema.yml",
|
|
749
|
-
data_dict=par_dict,
|
|
750
|
-
check_exact_data_type=False,
|
|
751
|
-
)
|
|
752
|
-
par_dict = data_validator.validate_and_transform(is_model_parameter=True)
|
|
669
|
+
par_dict = validate_data.DataValidator.validate_model_parameter(par_dict)
|
|
753
670
|
|
|
754
671
|
db_name = self._get_db_name(db_name)
|
|
755
672
|
collection = self.get_collection(db_name, collection_name)
|
|
@@ -778,7 +695,7 @@ class DatabaseHandler:
|
|
|
778
695
|
self._logger.info(f"Will also add the file {file_to_insert_now} to the DB")
|
|
779
696
|
self.insert_file_to_db(file_to_insert_now, db_name)
|
|
780
697
|
|
|
781
|
-
self._reset_parameter_cache(
|
|
698
|
+
self._reset_parameter_cache()
|
|
782
699
|
|
|
783
700
|
def _get_db_name(self, db_name=None):
|
|
784
701
|
"""
|
|
@@ -796,42 +713,6 @@ class DatabaseHandler:
|
|
|
796
713
|
"""
|
|
797
714
|
return self.mongo_db_config["db_simulation_model"] if db_name is None else db_name
|
|
798
715
|
|
|
799
|
-
def model_version(self, version, db_name=None):
|
|
800
|
-
"""
|
|
801
|
-
Return model version and check that it is valid.
|
|
802
|
-
|
|
803
|
-
Queries the database for all available model versions and check if the
|
|
804
|
-
requested version is valid.
|
|
805
|
-
|
|
806
|
-
Parameters
|
|
807
|
-
----------
|
|
808
|
-
version : str
|
|
809
|
-
Model version.
|
|
810
|
-
db_name : str
|
|
811
|
-
Database name.
|
|
812
|
-
|
|
813
|
-
Returns
|
|
814
|
-
-------
|
|
815
|
-
str
|
|
816
|
-
Model version.
|
|
817
|
-
|
|
818
|
-
Raises
|
|
819
|
-
------
|
|
820
|
-
ValueError
|
|
821
|
-
if version not valid.
|
|
822
|
-
|
|
823
|
-
"""
|
|
824
|
-
_all_versions = self.get_all_versions(db_name=db_name)
|
|
825
|
-
if version in _all_versions:
|
|
826
|
-
return version
|
|
827
|
-
if len(_all_versions) == 0:
|
|
828
|
-
return None
|
|
829
|
-
|
|
830
|
-
raise ValueError(
|
|
831
|
-
f"Invalid model version {version} in DB {self._get_db_name(db_name)} "
|
|
832
|
-
f"(allowed are {_all_versions})"
|
|
833
|
-
)
|
|
834
|
-
|
|
835
716
|
def insert_file_to_db(self, file_name, db_name=None, **kwargs):
|
|
836
717
|
"""
|
|
837
718
|
Insert a file to the DB.
|
|
@@ -855,15 +736,11 @@ class DatabaseHandler:
|
|
|
855
736
|
|
|
856
737
|
"""
|
|
857
738
|
db_name = self._get_db_name(db_name)
|
|
858
|
-
|
|
859
739
|
db = DatabaseHandler.db_client[db_name]
|
|
860
740
|
file_system = gridfs.GridFS(db)
|
|
861
741
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
if "filename" not in kwargs:
|
|
866
|
-
kwargs["filename"] = Path(file_name).name
|
|
742
|
+
kwargs.setdefault("content_type", "ascii/dat")
|
|
743
|
+
kwargs.setdefault("filename", Path(file_name).name)
|
|
867
744
|
|
|
868
745
|
if file_system.exists({"filename": kwargs["filename"]}):
|
|
869
746
|
self._logger.warning(
|
|
@@ -872,78 +749,11 @@ class DatabaseHandler:
|
|
|
872
749
|
return file_system.find_one( # pylint: disable=protected-access
|
|
873
750
|
{"filename": kwargs["filename"]}
|
|
874
751
|
)._id
|
|
752
|
+
self._logger.debug(f"Writing file to DB: {file_name}")
|
|
875
753
|
with open(file_name, "rb") as data_file:
|
|
876
754
|
return file_system.put(data_file, **kwargs)
|
|
877
755
|
|
|
878
|
-
def
|
|
879
|
-
self,
|
|
880
|
-
parameter=None,
|
|
881
|
-
array_element_name=None,
|
|
882
|
-
site=None,
|
|
883
|
-
db_name=None,
|
|
884
|
-
collection=None,
|
|
885
|
-
):
|
|
886
|
-
"""
|
|
887
|
-
Get all version entries in the DB of collection and/or a specific parameter.
|
|
888
|
-
|
|
889
|
-
Parameters
|
|
890
|
-
----------
|
|
891
|
-
parameter: str
|
|
892
|
-
Which parameter to get the versions of
|
|
893
|
-
array_element_name: str
|
|
894
|
-
Which array element to get the versions of (in case "collection_name" is not "sites")
|
|
895
|
-
site: str
|
|
896
|
-
Site name.
|
|
897
|
-
db_name: str
|
|
898
|
-
Database name.
|
|
899
|
-
collection_name: str
|
|
900
|
-
The name of the collection in which to update the parameter.
|
|
901
|
-
|
|
902
|
-
Returns
|
|
903
|
-
-------
|
|
904
|
-
all_versions: list
|
|
905
|
-
List of all versions found
|
|
906
|
-
|
|
907
|
-
Raises
|
|
908
|
-
------
|
|
909
|
-
ValueError
|
|
910
|
-
If key to collection_name is not valid.
|
|
911
|
-
|
|
912
|
-
"""
|
|
913
|
-
db_name = self._get_db_name() if db_name is None else db_name
|
|
914
|
-
if not db_name:
|
|
915
|
-
self._logger.warning("No database name defined to determine list of model versions")
|
|
916
|
-
return []
|
|
917
|
-
_cache_key = f"model_versions_{db_name}-{collection}"
|
|
918
|
-
|
|
919
|
-
query = {}
|
|
920
|
-
if parameter is not None:
|
|
921
|
-
query["parameter"] = parameter
|
|
922
|
-
_cache_key = f"{_cache_key}-{parameter}"
|
|
923
|
-
if collection in ["telescopes", "calibration_devices"] and array_element_name is not None:
|
|
924
|
-
query["instrument"] = names.validate_array_element_name(array_element_name)
|
|
925
|
-
_cache_key = f"{_cache_key}-{query['instrument']}"
|
|
926
|
-
elif collection == "sites" and site is not None:
|
|
927
|
-
query["site"] = names.validate_site_name(site)
|
|
928
|
-
_cache_key = f"{_cache_key}-{query['site']}"
|
|
929
|
-
|
|
930
|
-
if _cache_key not in DatabaseHandler.model_versions_cached:
|
|
931
|
-
all_versions = set()
|
|
932
|
-
collections_to_query = (
|
|
933
|
-
[collection] if collection else self.get_collections(db_name, True)
|
|
934
|
-
)
|
|
935
|
-
for collection_name in collections_to_query:
|
|
936
|
-
db_collection = self.get_collection(db_name, collection_name)
|
|
937
|
-
sorted_posts = db_collection.find(query).sort("version", ASCENDING)
|
|
938
|
-
all_versions.update(post["version"] for post in sorted_posts)
|
|
939
|
-
DatabaseHandler.model_versions_cached[_cache_key] = list(all_versions)
|
|
940
|
-
|
|
941
|
-
if len(DatabaseHandler.model_versions_cached[_cache_key]) == 0:
|
|
942
|
-
self._logger.warning(f"The query {query} did not return any results. No versions found")
|
|
943
|
-
|
|
944
|
-
return DatabaseHandler.model_versions_cached[_cache_key]
|
|
945
|
-
|
|
946
|
-
def _parameter_cache_key(self, site, array_element_name, model_version, collection=None):
|
|
756
|
+
def _cache_key(self, site=None, array_element_name=None, model_version=None, collection=None):
|
|
947
757
|
"""
|
|
948
758
|
Create a cache key for the parameter cache dictionaries.
|
|
949
759
|
|
|
@@ -963,61 +773,79 @@ class DatabaseHandler:
|
|
|
963
773
|
str
|
|
964
774
|
Cache key.
|
|
965
775
|
"""
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
if array_element_name:
|
|
970
|
-
parts.append(array_element_name)
|
|
971
|
-
parts.append(model_version)
|
|
972
|
-
if collection:
|
|
973
|
-
parts.append(collection)
|
|
974
|
-
return "-".join(parts)
|
|
776
|
+
return "-".join(
|
|
777
|
+
part for part in [model_version, collection, site, array_element_name] if part
|
|
778
|
+
)
|
|
975
779
|
|
|
976
|
-
def
|
|
780
|
+
def _read_cache(
|
|
781
|
+
self, cache_dict, site=None, array_element_name=None, model_version=None, collection=None
|
|
782
|
+
):
|
|
977
783
|
"""
|
|
978
|
-
|
|
784
|
+
Read parameters from cache.
|
|
979
785
|
|
|
980
786
|
Parameters
|
|
981
787
|
----------
|
|
788
|
+
cache_dict: dict
|
|
789
|
+
Cache dictionary.
|
|
982
790
|
site: str
|
|
983
791
|
Site name.
|
|
984
792
|
array_element_name: str
|
|
985
793
|
Array element name.
|
|
986
794
|
model_version: str
|
|
987
795
|
Model version.
|
|
796
|
+
collection: str
|
|
797
|
+
DB collection name.
|
|
798
|
+
|
|
799
|
+
Returns
|
|
800
|
+
-------
|
|
801
|
+
str
|
|
802
|
+
Cache key.
|
|
988
803
|
"""
|
|
989
|
-
self.
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
804
|
+
cache_key = self._cache_key(site, array_element_name, model_version, collection)
|
|
805
|
+
try:
|
|
806
|
+
return cache_key, cache_dict[cache_key]
|
|
807
|
+
except KeyError:
|
|
808
|
+
return cache_key, None
|
|
994
809
|
|
|
995
|
-
def
|
|
810
|
+
def _reset_parameter_cache(self):
|
|
811
|
+
"""Reset the cache for the parameters."""
|
|
812
|
+
DatabaseHandler.model_parameters_cached.clear()
|
|
813
|
+
|
|
814
|
+
def _get_array_element_list(self, array_element_name, site, production_table, collection):
|
|
996
815
|
"""
|
|
997
|
-
|
|
816
|
+
Return list of array elements for DB queries (add design model if needed).
|
|
817
|
+
|
|
818
|
+
Design model is added if found in the production table.
|
|
998
819
|
|
|
999
820
|
Parameters
|
|
1000
821
|
----------
|
|
1001
|
-
|
|
1002
|
-
|
|
822
|
+
array_element_name: str
|
|
823
|
+
Name of the array element.
|
|
824
|
+
site: str
|
|
825
|
+
Site name.
|
|
826
|
+
production_table: dict
|
|
827
|
+
Production table.
|
|
828
|
+
collection: str
|
|
829
|
+
collection of array element (e.g. telescopes, calibration_devices).
|
|
1003
830
|
|
|
1004
831
|
Returns
|
|
1005
832
|
-------
|
|
1006
833
|
list
|
|
1007
|
-
List of
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
""
|
|
1012
|
-
|
|
1013
|
-
if
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
834
|
+
List of array elements
|
|
835
|
+
"""
|
|
836
|
+
if collection == "configuration_corsika":
|
|
837
|
+
return ["xSTx-design"] # placeholder to ignore 'instrument' field in query.
|
|
838
|
+
if collection == "sites":
|
|
839
|
+
return [f"OBS-{site}"]
|
|
840
|
+
if "-design" in array_element_name:
|
|
841
|
+
return [array_element_name]
|
|
842
|
+
try:
|
|
843
|
+
return [
|
|
844
|
+
production_table["design_model"][array_element_name],
|
|
845
|
+
array_element_name,
|
|
846
|
+
]
|
|
847
|
+
except KeyError:
|
|
1018
848
|
return [
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
if not collection.startswith("fs.") and collection != "metadata"
|
|
849
|
+
f"{names.get_array_element_type_from_name(array_element_name)}-design",
|
|
850
|
+
array_element_name,
|
|
1022
851
|
]
|
|
1023
|
-
return self.list_of_collections[db_name]
|