gammasimtools 0.9.0__py3-none-any.whl → 0.11.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.11.0.dist-info}/METADATA +4 -2
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/RECORD +133 -117
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/entry_points.txt +6 -1
- simtools/_version.py +9 -4
- simtools/applications/calculate_trigger_rate.py +15 -38
- simtools/applications/convert_all_model_parameters_from_simtel.py +9 -29
- simtools/applications/convert_geo_coordinates_of_array_elements.py +47 -45
- simtools/applications/convert_model_parameter_from_simtel.py +2 -3
- simtools/applications/db_add_file_to_db.py +1 -3
- 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 +26 -35
- simtools/applications/derive_mirror_rnda.py +1 -2
- simtools/applications/derive_photon_electron_spectrum.py +99 -0
- simtools/applications/derive_psf_parameters.py +1 -0
- simtools/applications/docs_produce_array_element_report.py +71 -0
- simtools/applications/docs_produce_model_parameter_reports.py +63 -0
- simtools/applications/generate_array_config.py +17 -17
- simtools/applications/generate_corsika_histograms.py +2 -2
- simtools/applications/generate_regular_arrays.py +19 -17
- simtools/applications/generate_simtel_array_histograms.py +11 -48
- simtools/applications/production_derive_limits.py +95 -0
- simtools/applications/production_generate_simulation_config.py +37 -33
- simtools/applications/production_scale_events.py +4 -9
- simtools/applications/run_application.py +165 -0
- simtools/applications/simulate_light_emission.py +0 -4
- 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 +18 -11
- simtools/applications/validate_camera_efficiency.py +2 -2
- simtools/applications/validate_file_using_schema.py +26 -22
- simtools/camera/single_photon_electron_spectrum.py +168 -0
- simtools/configuration/commandline_parser.py +37 -1
- simtools/configuration/configurator.py +8 -10
- simtools/constants.py +10 -3
- simtools/corsika/corsika_config.py +19 -17
- simtools/corsika/corsika_histograms.py +5 -7
- simtools/corsika/corsika_histograms_visualize.py +2 -4
- simtools/data_model/data_reader.py +0 -3
- simtools/data_model/metadata_collector.py +20 -12
- simtools/data_model/metadata_model.py +8 -124
- simtools/data_model/model_data_writer.py +81 -75
- simtools/data_model/schema.py +220 -0
- simtools/data_model/validate_data.py +79 -68
- simtools/db/db_handler.py +350 -492
- simtools/db/db_model_upload.py +139 -0
- simtools/dependencies.py +112 -0
- simtools/io_operations/hdf5_handler.py +54 -24
- simtools/layout/array_layout.py +38 -32
- simtools/model/array_model.py +13 -7
- simtools/model/model_parameter.py +55 -54
- simtools/model/site_model.py +2 -2
- simtools/production_configuration/calculate_statistical_errors_grid_point.py +119 -145
- simtools/production_configuration/event_scaler.py +9 -35
- simtools/production_configuration/generate_simulation_config.py +9 -44
- simtools/production_configuration/interpolation_handler.py +9 -15
- simtools/production_configuration/limits_calculation.py +202 -0
- simtools/reporting/docs_read_parameters.py +310 -0
- simtools/runners/corsika_simtel_runner.py +4 -4
- simtools/schemas/{integration_tests_config.metaschema.yml → application_workflow.metaschema.yml} +61 -27
- simtools/schemas/array_elements.yml +8 -0
- simtools/schemas/input/MST_mirror_2f_measurements.schema.yml +39 -0
- simtools/schemas/input/single_pe_spectrum.schema.yml +38 -0
- simtools/schemas/model_parameter.metaschema.yml +103 -2
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +4 -1
- 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/correct_nsb_spectrum_to_telescope_altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +4 -2
- simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +2 -0
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +2 -0
- 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/iobuf_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_photons.schema.yml +2 -2
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/random_generator.schema.yml +1 -1
- simtools/schemas/model_parameters/sampled_output.schema.yml +1 -1
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/tailcut_scale.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_reader.py +1 -2
- simtools/simtel/simtel_config_writer.py +6 -8
- simtools/simtel/simtel_io_histogram.py +32 -68
- simtools/simtel/simtel_io_histograms.py +17 -34
- simtools/simtel/simulator_array.py +2 -1
- simtools/simtel/simulator_camera_efficiency.py +6 -3
- simtools/simtel/simulator_light_emission.py +5 -6
- simtools/simtel/simulator_ray_tracing.py +3 -4
- simtools/testing/configuration.py +2 -1
- simtools/testing/helpers.py +6 -13
- simtools/testing/validate_output.py +141 -47
- simtools/utils/general.py +114 -14
- simtools/utils/names.py +299 -157
- simtools/utils/value_conversion.py +17 -13
- simtools/version.py +2 -2
- simtools/visualization/legend_handlers.py +2 -0
- 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.11.0.dist-info}/LICENSE +0 -0
- {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/top_level.txt +0 -0
- /simtools/{camera_efficiency.py → camera/camera_efficiency.py} +0 -0
|
@@ -12,39 +12,22 @@ from simtools.testing import assertions
|
|
|
12
12
|
_logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
"""
|
|
17
|
-
Validate test output for all integration tests.
|
|
18
|
-
|
|
19
|
-
Parameters
|
|
20
|
-
----------
|
|
21
|
-
config: dict
|
|
22
|
-
Integration test configuration dictionary.
|
|
23
|
-
request: request
|
|
24
|
-
Request object.
|
|
25
|
-
config_file_model_version: str
|
|
26
|
-
Model version from the configuration file.
|
|
27
|
-
|
|
28
|
-
"""
|
|
29
|
-
if request.config.getoption("--model_version") is None:
|
|
30
|
-
validate_application_output(config)
|
|
31
|
-
elif config_file_model_version is not None:
|
|
32
|
-
_from_command_line = request.config.getoption("--model_version")
|
|
33
|
-
_from_config_file = config_file_model_version
|
|
34
|
-
if _from_command_line == _from_config_file:
|
|
35
|
-
validate_application_output(config)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def validate_application_output(config):
|
|
15
|
+
def validate_application_output(config, from_command_line=None, from_config_file=None):
|
|
39
16
|
"""
|
|
40
17
|
Validate application output against expected output.
|
|
41
18
|
|
|
42
19
|
Expected output is defined in configuration file.
|
|
20
|
+
Some tests run only if the model version from the command line
|
|
21
|
+
equals the model version from the configuration file.
|
|
43
22
|
|
|
44
23
|
Parameters
|
|
45
24
|
----------
|
|
46
25
|
config: dict
|
|
47
26
|
dictionary with the configuration for the application test.
|
|
27
|
+
from_command_line: str
|
|
28
|
+
Model version from the command line.
|
|
29
|
+
from_config_file: str
|
|
30
|
+
Model version from the configuration file.
|
|
48
31
|
|
|
49
32
|
"""
|
|
50
33
|
if "INTEGRATION_TESTS" not in config:
|
|
@@ -52,24 +35,40 @@ def validate_application_output(config):
|
|
|
52
35
|
|
|
53
36
|
for integration_test in config["INTEGRATION_TESTS"]:
|
|
54
37
|
_logger.info(f"Testing application output: {integration_test}")
|
|
55
|
-
if "REFERENCE_OUTPUT_FILE" in integration_test:
|
|
56
|
-
_validate_reference_output_file(config, integration_test)
|
|
57
|
-
|
|
58
|
-
if "TEST_OUTPUT_FILES" in integration_test:
|
|
59
|
-
_validate_output_path_and_file(config, integration_test["TEST_OUTPUT_FILES"])
|
|
60
|
-
if "OUTPUT_FILE" in integration_test:
|
|
61
|
-
_validate_output_path_and_file(
|
|
62
|
-
config,
|
|
63
|
-
[{"PATH_DESCRIPTOR": "OUTPUT_PATH", "FILE": integration_test["OUTPUT_FILE"]}],
|
|
64
|
-
)
|
|
65
38
|
|
|
66
|
-
if
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
39
|
+
if from_command_line == from_config_file:
|
|
40
|
+
_validate_output_files(config, integration_test)
|
|
41
|
+
|
|
42
|
+
if "FILE_TYPE" in integration_test:
|
|
43
|
+
assert assertions.assert_file_type(
|
|
44
|
+
integration_test["FILE_TYPE"],
|
|
45
|
+
Path(config["CONFIGURATION"]["OUTPUT_PATH"]).joinpath(
|
|
46
|
+
config["CONFIGURATION"]["OUTPUT_FILE"]
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
_test_simtel_cfg_files(config, integration_test, from_command_line, from_config_file)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _validate_output_files(config, integration_test):
|
|
53
|
+
"""Validate output files."""
|
|
54
|
+
if "REFERENCE_OUTPUT_FILE" in integration_test:
|
|
55
|
+
_validate_reference_output_file(config, integration_test)
|
|
56
|
+
if "TEST_OUTPUT_FILES" in integration_test:
|
|
57
|
+
_validate_output_path_and_file(config, integration_test["TEST_OUTPUT_FILES"])
|
|
58
|
+
if "OUTPUT_FILE" in integration_test:
|
|
59
|
+
_validate_output_path_and_file(
|
|
60
|
+
config,
|
|
61
|
+
[{"PATH_DESCRIPTOR": "OUTPUT_PATH", "FILE": integration_test["OUTPUT_FILE"]}],
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _test_simtel_cfg_files(config, integration_test, from_command_line, from_config_file):
|
|
66
|
+
"""Test simtel cfg files."""
|
|
67
|
+
test_simtel_cfg_file = integration_test.get("TEST_SIMTEL_CFG_FILES", {}).get(
|
|
68
|
+
from_command_line or from_config_file
|
|
69
|
+
)
|
|
70
|
+
if test_simtel_cfg_file:
|
|
71
|
+
_validate_simtel_cfg_files(config, test_simtel_cfg_file)
|
|
73
72
|
|
|
74
73
|
|
|
75
74
|
def _validate_reference_output_file(config, integration_test):
|
|
@@ -128,12 +127,13 @@ def compare_files(file1, file2, tolerance=1.0e-5, test_columns=None):
|
|
|
128
127
|
"""
|
|
129
128
|
_file1_suffix = Path(file1).suffix
|
|
130
129
|
_file2_suffix = Path(file2).suffix
|
|
130
|
+
_logger.info("Comparing files: %s and %s", file1, file2)
|
|
131
131
|
if _file1_suffix != _file2_suffix:
|
|
132
132
|
raise ValueError(f"File suffixes do not match: {file1} and {file2}")
|
|
133
133
|
if _file1_suffix == ".ecsv":
|
|
134
134
|
return compare_ecsv_files(file1, file2, tolerance, test_columns)
|
|
135
135
|
if _file1_suffix in (".json", ".yaml", ".yml"):
|
|
136
|
-
return compare_json_or_yaml_files(file1, file2)
|
|
136
|
+
return compare_json_or_yaml_files(file1, file2, tolerance)
|
|
137
137
|
|
|
138
138
|
_logger.warning(f"Unknown file type for files: {file1} and {file2}")
|
|
139
139
|
return False
|
|
@@ -144,6 +144,7 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
|
|
|
144
144
|
Compare two json or yaml files.
|
|
145
145
|
|
|
146
146
|
Take into account float comparison for sim_telarray string-embedded floats.
|
|
147
|
+
Allow differences in 'schema_version' field.
|
|
147
148
|
|
|
148
149
|
Parameters
|
|
149
150
|
----------
|
|
@@ -162,17 +163,47 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
|
|
|
162
163
|
"""
|
|
163
164
|
data1 = gen.collect_data_from_file(file1)
|
|
164
165
|
data2 = gen.collect_data_from_file(file2)
|
|
166
|
+
data1.pop("schema_version", None)
|
|
167
|
+
data2.pop("schema_version", None)
|
|
165
168
|
|
|
166
169
|
_logger.debug(f"Comparing json/yaml files: {file1} and {file2}")
|
|
167
170
|
|
|
168
171
|
if data1 == data2:
|
|
169
172
|
return True
|
|
170
173
|
|
|
171
|
-
if
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
if data1.keys() != data2.keys():
|
|
175
|
+
_logger.error(f"Keys do not match: {data1.keys()} and {data2.keys()}")
|
|
176
|
+
return False
|
|
177
|
+
_comparison = all(
|
|
178
|
+
(
|
|
179
|
+
_compare_value_from_parameter_dict(data1[k], data2[k], tolerance)
|
|
180
|
+
if k == "value"
|
|
181
|
+
else data1[k] == data2[k]
|
|
182
|
+
)
|
|
183
|
+
for k in data1
|
|
184
|
+
)
|
|
185
|
+
if not _comparison:
|
|
186
|
+
_logger.error(f"Values do not match: {data1} and {data2} (tolerance: {tolerance})")
|
|
187
|
+
return _comparison
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _compare_value_from_parameter_dict(data1, data2, tolerance=1.0e-5):
|
|
191
|
+
"""Compare value fields given in different formats."""
|
|
192
|
+
|
|
193
|
+
def _as_list(value):
|
|
194
|
+
if isinstance(value, str):
|
|
195
|
+
return gen.convert_string_to_list(value)
|
|
196
|
+
if isinstance(value, list | np.ndarray):
|
|
197
|
+
return value
|
|
198
|
+
return [value]
|
|
199
|
+
|
|
200
|
+
_logger.info(f"Comparing values: {data1} and {data2} (tolerance: {tolerance})")
|
|
201
|
+
|
|
202
|
+
_as_list_1 = _as_list(data1)
|
|
203
|
+
_as_list_2 = _as_list(data2)
|
|
204
|
+
if isinstance(_as_list_1, str):
|
|
205
|
+
return _as_list_1 == _as_list_2
|
|
206
|
+
return np.allclose(_as_list_1, _as_list_2, rtol=tolerance)
|
|
176
207
|
|
|
177
208
|
|
|
178
209
|
def compare_ecsv_files(file1, file2, tolerance=1.0e-5, test_columns=None):
|
|
@@ -238,3 +269,66 @@ def compare_ecsv_files(file1, file2, tolerance=1.0e-5, test_columns=None):
|
|
|
238
269
|
return False
|
|
239
270
|
|
|
240
271
|
return True
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def _validate_simtel_cfg_files(config, simtel_cfg_file):
|
|
275
|
+
"""
|
|
276
|
+
Check sim_telarray configuration files and compare with reference file.
|
|
277
|
+
|
|
278
|
+
Note the finetuned naming of configuration files by simtools.
|
|
279
|
+
|
|
280
|
+
"""
|
|
281
|
+
reference_file = Path(simtel_cfg_file)
|
|
282
|
+
test_file = Path(config["CONFIGURATION"]["OUTPUT_PATH"]) / reference_file.name.replace(
|
|
283
|
+
"_test", f"_{config['CONFIGURATION']['LABEL']}"
|
|
284
|
+
)
|
|
285
|
+
_logger.info(
|
|
286
|
+
f"Comparing simtel cfg files: {reference_file} and {test_file} "
|
|
287
|
+
f"for model version {config['CONFIGURATION']['MODEL_VERSION']}"
|
|
288
|
+
)
|
|
289
|
+
return _compare_simtel_cfg_files(reference_file, test_file)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _compare_simtel_cfg_files(reference_file, test_file):
|
|
293
|
+
"""
|
|
294
|
+
Compare two sim_telarray configuration files.
|
|
295
|
+
|
|
296
|
+
Line-by-line string comparison. Requires similar sequence of
|
|
297
|
+
parameters in the files. Ignore lines containing 'config_release'
|
|
298
|
+
(as it contains the simtools package version).
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
reference_file: Path
|
|
303
|
+
Reference sim_telarray configuration file.
|
|
304
|
+
test_file: Path
|
|
305
|
+
Test sim_telarray configuration file.
|
|
306
|
+
|
|
307
|
+
Returns
|
|
308
|
+
-------
|
|
309
|
+
bool
|
|
310
|
+
True if the files are equal.
|
|
311
|
+
|
|
312
|
+
"""
|
|
313
|
+
with open(reference_file, encoding="utf-8") as f1, open(test_file, encoding="utf-8") as f2:
|
|
314
|
+
reference_cfg = [line.rstrip() for line in f1 if line.strip()]
|
|
315
|
+
test_cfg = [line.rstrip() for line in f2 if line.strip()]
|
|
316
|
+
|
|
317
|
+
if len(reference_cfg) != len(test_cfg):
|
|
318
|
+
_logger.error(
|
|
319
|
+
f"Line counts differ: {reference_file} ({len(reference_cfg)} lines), "
|
|
320
|
+
f"{test_file} ({len(test_cfg)} lines)."
|
|
321
|
+
)
|
|
322
|
+
return False
|
|
323
|
+
|
|
324
|
+
for ref_line, test_line in zip(reference_cfg, test_cfg):
|
|
325
|
+
if any(ignore in ref_line for ignore in ("config_release", "Label")):
|
|
326
|
+
continue
|
|
327
|
+
if ref_line != test_line:
|
|
328
|
+
_logger.error(
|
|
329
|
+
f"Configuration files {reference_file} and {test_file} do not match: "
|
|
330
|
+
f"'{ref_line}' and '{test_line}'"
|
|
331
|
+
)
|
|
332
|
+
return False
|
|
333
|
+
|
|
334
|
+
return True
|
simtools/utils/general.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""General functions useful across different parts of the code."""
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
+
import datetime
|
|
4
5
|
import json
|
|
5
6
|
import logging
|
|
6
7
|
import os
|
|
@@ -17,6 +18,7 @@ import yaml
|
|
|
17
18
|
__all__ = [
|
|
18
19
|
"InvalidConfigDataError",
|
|
19
20
|
"change_dict_keys_case",
|
|
21
|
+
"clear_default_sim_telarray_cfg_directories",
|
|
20
22
|
"collect_data_from_file",
|
|
21
23
|
"collect_final_lines",
|
|
22
24
|
"collect_kwargs",
|
|
@@ -81,6 +83,28 @@ def is_url(url):
|
|
|
81
83
|
return False
|
|
82
84
|
|
|
83
85
|
|
|
86
|
+
def url_exists(url):
|
|
87
|
+
"""
|
|
88
|
+
Check if a URL exists.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
url: str
|
|
93
|
+
URL to be checked.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
bool
|
|
98
|
+
True if URL exists.
|
|
99
|
+
"""
|
|
100
|
+
try:
|
|
101
|
+
with urllib.request.urlopen(url, timeout=5) as response:
|
|
102
|
+
return response.status == 200
|
|
103
|
+
except (urllib.error.URLError, AttributeError) as e:
|
|
104
|
+
_logger.error(f"URL {url} does not exist: {e}")
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
|
|
84
108
|
def collect_data_from_http(url):
|
|
85
109
|
"""
|
|
86
110
|
Download yaml or json file from url and return it contents as dict.
|
|
@@ -135,7 +159,7 @@ def collect_data_from_http(url):
|
|
|
135
159
|
return data
|
|
136
160
|
|
|
137
161
|
|
|
138
|
-
def collect_data_from_file(file_name):
|
|
162
|
+
def collect_data_from_file(file_name, yaml_document=None):
|
|
139
163
|
"""
|
|
140
164
|
Collect data from file based on its extension.
|
|
141
165
|
|
|
@@ -143,6 +167,8 @@ def collect_data_from_file(file_name):
|
|
|
143
167
|
----------
|
|
144
168
|
file_name: str
|
|
145
169
|
Name of the yaml/json/ascii file.
|
|
170
|
+
yaml_document: None, int
|
|
171
|
+
Return list of yaml documents or a single document (for yaml files with several documents).
|
|
146
172
|
|
|
147
173
|
Returns
|
|
148
174
|
-------
|
|
@@ -152,21 +178,34 @@ def collect_data_from_file(file_name):
|
|
|
152
178
|
if is_url(file_name):
|
|
153
179
|
return collect_data_from_http(file_name)
|
|
154
180
|
|
|
181
|
+
suffix = Path(file_name).suffix.lower()
|
|
155
182
|
with open(file_name, encoding="utf-8") as file:
|
|
156
|
-
if
|
|
183
|
+
if suffix == ".json":
|
|
157
184
|
return json.load(file)
|
|
185
|
+
if suffix == ".list":
|
|
186
|
+
return [line.strip() for line in file.readlines()]
|
|
187
|
+
if suffix in [".yml", ".yaml"]:
|
|
188
|
+
return _collect_data_from_yaml_file(file, file_name, yaml_document)
|
|
189
|
+
return None
|
|
158
190
|
|
|
159
|
-
if Path(file_name).suffix.lower() == ".list":
|
|
160
|
-
lines = file.readlines()
|
|
161
|
-
return [line.strip() for line in lines]
|
|
162
191
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
192
|
+
def _collect_data_from_yaml_file(file, file_name, yaml_document):
|
|
193
|
+
"""Collect data from a yaml file."""
|
|
194
|
+
try:
|
|
195
|
+
return yaml.safe_load(file)
|
|
196
|
+
except yaml.constructor.ConstructorError:
|
|
197
|
+
return _load_yaml_using_astropy(file)
|
|
198
|
+
except yaml.composer.ComposerError:
|
|
199
|
+
pass
|
|
200
|
+
file.seek(0)
|
|
201
|
+
if yaml_document is None:
|
|
202
|
+
return list(yaml.safe_load_all(file))
|
|
203
|
+
try:
|
|
204
|
+
return list(yaml.safe_load_all(file))[yaml_document]
|
|
205
|
+
except IndexError as exc:
|
|
206
|
+
raise InvalidConfigDataError(
|
|
207
|
+
f"YAML file {file_name} does not contain {yaml_document} documents."
|
|
208
|
+
) from exc
|
|
170
209
|
|
|
171
210
|
|
|
172
211
|
def collect_kwargs(label, in_kwargs):
|
|
@@ -705,7 +744,7 @@ def convert_list_to_string(data, comma_separated=False, shorten_list=False, coll
|
|
|
705
744
|
return " ".join(str(item) for item in data)
|
|
706
745
|
|
|
707
746
|
|
|
708
|
-
def convert_string_to_list(data_string, is_float=True):
|
|
747
|
+
def convert_string_to_list(data_string, is_float=True, force_comma_separation=False):
|
|
709
748
|
"""
|
|
710
749
|
Convert string (as used e.g. in sim_telarray) to list.
|
|
711
750
|
|
|
@@ -715,6 +754,10 @@ def convert_string_to_list(data_string, is_float=True):
|
|
|
715
754
|
----------
|
|
716
755
|
data_string: object
|
|
717
756
|
String to be converted
|
|
757
|
+
is_float: bool
|
|
758
|
+
If True, convert to float, otherwise to int.
|
|
759
|
+
force_comma_separation: bool
|
|
760
|
+
If True, force comma separation.
|
|
718
761
|
|
|
719
762
|
Returns
|
|
720
763
|
-------
|
|
@@ -732,7 +775,7 @@ def convert_string_to_list(data_string, is_float=True):
|
|
|
732
775
|
if "," in data_string:
|
|
733
776
|
result = data_string.split(",")
|
|
734
777
|
return [item.strip() for item in result]
|
|
735
|
-
if " " in data_string:
|
|
778
|
+
if " " in data_string and not force_comma_separation:
|
|
736
779
|
return data_string.split()
|
|
737
780
|
return data_string
|
|
738
781
|
|
|
@@ -832,3 +875,60 @@ def convert_keys_in_dict_to_lowercase(data):
|
|
|
832
875
|
if isinstance(data, list):
|
|
833
876
|
return [convert_keys_in_dict_to_lowercase(i) for i in data]
|
|
834
877
|
return data
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
def clear_default_sim_telarray_cfg_directories(command):
|
|
881
|
+
"""Prefix the command to clear default sim_telarray configuration directories.
|
|
882
|
+
|
|
883
|
+
Parameters
|
|
884
|
+
----------
|
|
885
|
+
command: str
|
|
886
|
+
Command to be prefixed.
|
|
887
|
+
|
|
888
|
+
Returns
|
|
889
|
+
-------
|
|
890
|
+
str
|
|
891
|
+
Prefixed command.
|
|
892
|
+
|
|
893
|
+
"""
|
|
894
|
+
return f"SIM_TELARRAY_CONFIG_PATH='' {command}"
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
def get_list_of_files_from_command_line(file_names, suffix_list):
|
|
898
|
+
"""
|
|
899
|
+
Get a list of files from the command line.
|
|
900
|
+
|
|
901
|
+
Files can be given as a list of file names or as a text file containing the list of files.
|
|
902
|
+
The list of suffixes restrict the files types to be returned. Note that a file list must
|
|
903
|
+
have a different suffix than those in the suffix list.
|
|
904
|
+
|
|
905
|
+
Parameters
|
|
906
|
+
----------
|
|
907
|
+
file_names: list
|
|
908
|
+
List of file names to be checked.
|
|
909
|
+
suffix_list: list
|
|
910
|
+
List of suffixes to be checked.
|
|
911
|
+
|
|
912
|
+
Returns
|
|
913
|
+
-------
|
|
914
|
+
list
|
|
915
|
+
List of files with the given suffixes.
|
|
916
|
+
"""
|
|
917
|
+
_files = []
|
|
918
|
+
for one_file in file_names:
|
|
919
|
+
path = Path(one_file)
|
|
920
|
+
try:
|
|
921
|
+
if path.suffix in suffix_list:
|
|
922
|
+
_files.append(one_file)
|
|
923
|
+
elif len(file_names) == 1:
|
|
924
|
+
with open(one_file, encoding="utf-8") as file:
|
|
925
|
+
_files.extend(line.strip() for line in file)
|
|
926
|
+
except FileNotFoundError as exc:
|
|
927
|
+
_logger.error(f"{one_file} is not a file.")
|
|
928
|
+
raise FileNotFoundError from exc
|
|
929
|
+
return _files
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def now_date_time_in_isoformat():
|
|
933
|
+
"""Return date and time in isoformat and second accuracy."""
|
|
934
|
+
return datetime.datetime.now(datetime.UTC).isoformat(timespec="seconds")
|