gammasimtools 0.15.0__py3-none-any.whl → 0.17.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.15.0.dist-info → gammasimtools-0.17.0.dist-info}/METADATA +5 -33
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/RECORD +243 -229
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/entry_points.txt +8 -3
- simtools/_version.py +2 -2
- simtools/applications/calculate_trigger_rate.py +10 -10
- simtools/applications/convert_all_model_parameters_from_simtel.py +16 -16
- simtools/applications/convert_model_parameter_from_simtel.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +5 -5
- simtools/applications/derive_psf_parameters.py +12 -9
- simtools/applications/docs_produce_array_element_report.py +3 -3
- simtools/applications/docs_produce_calibration_reports.py +49 -0
- simtools/applications/docs_produce_simulation_configuration_report.py +50 -0
- simtools/applications/{generate_simtel_array_histograms.py → generate_sim_telarray_histograms.py} +2 -2
- simtools/applications/generate_simtel_event_data.py +36 -46
- simtools/applications/merge_tables.py +104 -0
- simtools/applications/plot_array_layout.py +145 -258
- simtools/applications/production_derive_corsika_limits.py +35 -167
- simtools/applications/production_derive_statistics.py +159 -0
- simtools/applications/production_generate_grid.py +197 -0
- simtools/applications/simulate_light_emission.py +6 -13
- simtools/applications/simulate_prod.py +45 -21
- simtools/applications/simulate_prod_htcondor_generator.py +0 -1
- simtools/applications/submit_array_layouts.py +93 -0
- simtools/applications/validate_cumulative_psf.py +6 -4
- simtools/applications/validate_file_using_schema.py +7 -3
- simtools/applications/validate_optics.py +5 -4
- simtools/applications/verify_simulation_model_production_tables.py +52 -0
- simtools/camera/camera_efficiency.py +17 -42
- simtools/configuration/commandline_parser.py +32 -37
- simtools/configuration/configurator.py +10 -4
- simtools/corsika/corsika_config.py +120 -17
- simtools/corsika/primary_particle.py +46 -13
- simtools/data_model/format_checkers.py +9 -0
- simtools/data_model/metadata_collector.py +7 -3
- simtools/data_model/model_data_writer.py +3 -0
- simtools/data_model/schema.py +27 -16
- simtools/data_model/validate_data.py +27 -7
- simtools/db/db_handler.py +21 -15
- simtools/db/db_model_upload.py +2 -2
- simtools/io_operations/io_handler.py +2 -2
- simtools/io_operations/io_table_handler.py +345 -0
- simtools/job_execution/htcondor_script_generator.py +2 -2
- simtools/job_execution/job_manager.py +7 -121
- simtools/layout/array_layout.py +1 -0
- simtools/layout/array_layout_utils.py +385 -0
- simtools/model/array_model.py +68 -29
- simtools/model/model_parameter.py +76 -51
- simtools/model/model_repository.py +134 -0
- simtools/model/model_utils.py +43 -1
- simtools/model/site_model.py +3 -2
- simtools/model/telescope_model.py +4 -4
- simtools/production_configuration/{calculate_statistical_errors_grid_point.py → calculate_statistical_uncertainties_grid_point.py} +101 -116
- simtools/production_configuration/derive_corsika_limits.py +239 -111
- simtools/production_configuration/derive_corsika_limits_grid.py +189 -0
- simtools/production_configuration/derive_production_statistics.py +155 -0
- simtools/production_configuration/derive_production_statistics_handler.py +152 -0
- simtools/production_configuration/generate_production_grid.py +364 -0
- simtools/production_configuration/interpolation_handler.py +303 -96
- simtools/ray_tracing/mirror_panel_psf.py +16 -20
- simtools/ray_tracing/psf_analysis.py +2 -2
- simtools/ray_tracing/ray_tracing.py +12 -7
- simtools/reporting/docs_read_parameters.py +426 -81
- simtools/runners/corsika_runner.py +11 -1
- simtools/runners/corsika_simtel_runner.py +84 -90
- simtools/runners/runner_services.py +22 -8
- simtools/runners/simtel_runner.py +27 -10
- simtools/schemas/model_parameter.metaschema.yml +4 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +1 -0
- simtools/schemas/model_parameters/adjust_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +2 -2
- simtools/schemas/model_parameters/array_window.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_file.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_depth.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_filter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_pixels.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +2 -2
- simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +2 -2
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +90 -1
- simtools/schemas/model_parameters/default_trigger.schema.yml +2 -2
- simtools/schemas/model_parameters/design_model.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_start.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +44 -3
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +2 -2
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
- simtools/schemas/model_parameters/flatfielding.schema.yml +2 -2
- simtools/schemas/model_parameters/focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/focus_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/gain_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photons.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_class.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_list.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +2 -2
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +2 -2
- simtools/schemas/model_parameters/num_gains.schema.yml +2 -2
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +2 -2
- simtools/schemas/model_parameters/optics_properties.schema.yml +2 -2
- simtools/schemas/model_parameters/pedestal_events.schema.yml +7 -3
- simtools/schemas/model_parameters/photon_delay.schema.yml +2 -2
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/qe_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/random_generator.schema.yml +2 -2
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +2 -2
- simtools/schemas/model_parameters/sampled_output.schema.yml +2 -2
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +2 -2
- simtools/schemas/production_configuration_metrics.schema.yml +2 -2
- simtools/simtel/simtel_config_reader.py +21 -17
- simtools/simtel/simtel_config_writer.py +258 -66
- simtools/simtel/simtel_io_event_reader.py +301 -194
- simtools/simtel/simtel_io_event_writer.py +207 -227
- simtools/simtel/simtel_io_file_info.py +62 -0
- simtools/simtel/simtel_io_histogram.py +10 -14
- simtools/simtel/simtel_io_histograms.py +2 -2
- simtools/simtel/simtel_io_metadata.py +106 -0
- simtools/simtel/simulator_array.py +28 -14
- simtools/simtel/simulator_camera_efficiency.py +12 -6
- simtools/simtel/simulator_light_emission.py +85 -45
- simtools/simtel/simulator_ray_tracing.py +16 -6
- simtools/simulator.py +286 -89
- simtools/testing/configuration.py +5 -0
- simtools/testing/helpers.py +18 -0
- simtools/testing/sim_telarray_metadata.py +212 -0
- simtools/testing/validate_output.py +16 -6
- simtools/utils/general.py +18 -27
- simtools/utils/names.py +32 -10
- simtools/visualization/plot_array_layout.py +242 -0
- simtools/visualization/plot_pixels.py +681 -0
- simtools/visualization/visualize.py +5 -221
- simtools/applications/production_generate_simulation_config.py +0 -162
- simtools/applications/production_scale_events.py +0 -185
- simtools/layout/ctao_array_layouts.py +0 -172
- simtools/production_configuration/event_scaler.py +0 -120
- simtools/production_configuration/generate_simulation_config.py +0 -158
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.17.0.dist-info}/top_level.txt +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
r"""Class to read and manage relevant model parameters for a given telescope model."""
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
+
import re
|
|
6
7
|
import textwrap
|
|
7
8
|
from collections import defaultdict
|
|
8
9
|
from itertools import groupby
|
|
@@ -11,8 +12,11 @@ from pathlib import Path
|
|
|
11
12
|
import numpy as np
|
|
12
13
|
|
|
13
14
|
from simtools.db import db_handler
|
|
15
|
+
from simtools.io_operations import io_handler
|
|
14
16
|
from simtools.model.telescope_model import TelescopeModel
|
|
17
|
+
from simtools.utils import general as gen
|
|
15
18
|
from simtools.utils import names
|
|
19
|
+
from simtools.visualization import plot_pixels
|
|
16
20
|
|
|
17
21
|
logger = logging.getLogger()
|
|
18
22
|
|
|
@@ -25,35 +29,98 @@ class ReadParameters:
|
|
|
25
29
|
self._logger = logging.getLogger(__name__)
|
|
26
30
|
self.db = db_handler.DatabaseHandler(mongo_db_config=db_config)
|
|
27
31
|
self.db_config = db_config
|
|
28
|
-
self.array_element = args.get("telescope")
|
|
29
|
-
self.site = args.get("site")
|
|
32
|
+
self.array_element = args.get("telescope", None)
|
|
33
|
+
self.site = args.get("site", None)
|
|
30
34
|
self.model_version = args.get("model_version", None)
|
|
31
35
|
self.output_path = output_path
|
|
32
36
|
self.observatory = args.get("observatory")
|
|
37
|
+
self.software = args.get("simulation_software", None)
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
@property
|
|
40
|
+
def model_version(self):
|
|
41
|
+
"""Model version."""
|
|
42
|
+
return self._model_version
|
|
43
|
+
|
|
44
|
+
@model_version.setter
|
|
45
|
+
def model_version(self, model_version):
|
|
46
|
+
"""
|
|
47
|
+
Set model version.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
_model_version: str or list
|
|
52
|
+
Model version (e.g., "6.0.0").
|
|
53
|
+
If a list is passed, it must contain exactly one element,
|
|
54
|
+
and only that element will be used.
|
|
55
|
+
|
|
56
|
+
Raises
|
|
57
|
+
------
|
|
58
|
+
ValueError
|
|
59
|
+
If more than one model version is passed.
|
|
60
|
+
"""
|
|
61
|
+
if isinstance(model_version, list):
|
|
62
|
+
raise ValueError(
|
|
63
|
+
f"Only one model version can be passed to {self.__class__.__name__}, not a list."
|
|
64
|
+
)
|
|
65
|
+
self._model_version = model_version
|
|
66
|
+
|
|
67
|
+
def _convert_to_md(self, parameter, parameter_version, input_file):
|
|
35
68
|
"""Convert a file to a Markdown file, preserving formatting."""
|
|
36
69
|
input_file = Path(input_file)
|
|
70
|
+
|
|
37
71
|
output_data_path = Path(self.output_path / "_data_files")
|
|
38
72
|
output_data_path.mkdir(parents=True, exist_ok=True)
|
|
39
73
|
output_file_name = Path(input_file.stem + ".md")
|
|
40
74
|
output_file = output_data_path / output_file_name
|
|
75
|
+
image_name = f"{self.array_element}_{parameter}_{self.model_version.replace('.', '-')}"
|
|
76
|
+
outpath = Path(io_handler.IOHandler().get_output_directory().parent / "_images")
|
|
77
|
+
outpath.mkdir(parents=True, exist_ok=True)
|
|
78
|
+
image_path = Path(f"{outpath}/{image_name}")
|
|
79
|
+
|
|
80
|
+
if parameter == "camera_config_file" and parameter_version:
|
|
81
|
+
image_path = Path(f"{outpath}/{input_file.stem.replace('.', '-')}")
|
|
82
|
+
if not (image_path.with_suffix(".png")).exists():
|
|
83
|
+
logger.info("Plotting camera configuration file: %s", input_file.name)
|
|
84
|
+
plot_config = {
|
|
85
|
+
"file_name": input_file.name,
|
|
86
|
+
"telescope": self.array_element,
|
|
87
|
+
"parameter_version": parameter_version,
|
|
88
|
+
"site": self.site,
|
|
89
|
+
"model_version": self.model_version,
|
|
90
|
+
"parameter": parameter,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
plot_pixels.plot(
|
|
94
|
+
config=plot_config,
|
|
95
|
+
output_file=image_path,
|
|
96
|
+
db_config=self.db_config,
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
logger.info(
|
|
100
|
+
"Camera configuration file plot already exists: %s",
|
|
101
|
+
image_path.with_suffix(".png"),
|
|
102
|
+
)
|
|
41
103
|
|
|
42
104
|
try:
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
105
|
+
# with input_file.open("r", encoding="utf-8") as infile:
|
|
106
|
+
file_contents = gen.read_file_encoded_in_utf_or_latin(input_file)
|
|
107
|
+
|
|
108
|
+
if self.model_version is not None:
|
|
109
|
+
with output_file.open("w", encoding="utf-8") as outfile:
|
|
110
|
+
outfile.write(f"# {input_file.stem}\n")
|
|
111
|
+
outfile.write(f"\n\n")
|
|
112
|
+
outfile.write(
|
|
113
|
+
"\n\nThe full file can be found in the Simulation Model repository [here]"
|
|
114
|
+
"(https://gitlab.cta-observatory.org/cta-science/simulations/"
|
|
115
|
+
"simulation-model/simulation-models/-/blob/main/simulation-models/"
|
|
116
|
+
f"model_parameters/Files/{input_file.name}).\n\n"
|
|
117
|
+
)
|
|
118
|
+
outfile.write("\n\n")
|
|
119
|
+
outfile.write("The first 30 lines of the file are:\n")
|
|
120
|
+
outfile.write("```\n")
|
|
121
|
+
first_30_lines = "".join(file_contents[:30])
|
|
122
|
+
outfile.write(first_30_lines)
|
|
123
|
+
outfile.write("\n```")
|
|
57
124
|
|
|
58
125
|
except FileNotFoundError as exc:
|
|
59
126
|
logger.exception(f"Data file not found: {input_file}.")
|
|
@@ -61,11 +128,19 @@ class ReadParameters:
|
|
|
61
128
|
|
|
62
129
|
return f"_data_files/{output_file_name}"
|
|
63
130
|
|
|
64
|
-
def _format_parameter_value(
|
|
131
|
+
def _format_parameter_value(
|
|
132
|
+
self, parameter, value_data, unit, file_flag, parameter_version=None
|
|
133
|
+
):
|
|
65
134
|
"""Format parameter value based on type."""
|
|
66
135
|
if file_flag:
|
|
67
136
|
input_file_name = f"{self.output_path}/model/{value_data}"
|
|
68
|
-
|
|
137
|
+
if parameter_version is None:
|
|
138
|
+
return (
|
|
139
|
+
f"[{Path(value_data).name}](https://gitlab.cta-observatory.org/"
|
|
140
|
+
"cta-science/simulations/simulation-model/simulation-models/-/blob/main/"
|
|
141
|
+
f"simulation-models/model_parameters/Files/{value_data})"
|
|
142
|
+
).strip()
|
|
143
|
+
output_file_name = self._convert_to_md(parameter, parameter_version, input_file_name)
|
|
69
144
|
return f"[{Path(value_data).name}]({output_file_name})".strip()
|
|
70
145
|
if isinstance(value_data, (str | int | float)):
|
|
71
146
|
return f"{value_data} {unit}".strip()
|
|
@@ -77,6 +152,26 @@ class ReadParameters:
|
|
|
77
152
|
else ", ".join(f"{v} {unit}" for v in value_data)
|
|
78
153
|
).strip()
|
|
79
154
|
|
|
155
|
+
def _wrap_at_underscores(self, text, max_width):
|
|
156
|
+
"""Wrap text at underscores to fit within a specified width."""
|
|
157
|
+
parts = text.split("_")
|
|
158
|
+
lines = []
|
|
159
|
+
current = []
|
|
160
|
+
|
|
161
|
+
for part in parts:
|
|
162
|
+
# Predict the new length if we add this part
|
|
163
|
+
next_line = "_".join([*current, part])
|
|
164
|
+
if len(next_line) <= max_width:
|
|
165
|
+
current.append(part)
|
|
166
|
+
else:
|
|
167
|
+
lines.append("_".join(current))
|
|
168
|
+
current = [part]
|
|
169
|
+
|
|
170
|
+
if current:
|
|
171
|
+
lines.append("_".join(current))
|
|
172
|
+
|
|
173
|
+
return " ".join(lines)
|
|
174
|
+
|
|
80
175
|
def _group_model_versions_by_parameter_version(self, grouped_data):
|
|
81
176
|
"""Group model versions by parameter version and track the parameter values."""
|
|
82
177
|
result = {}
|
|
@@ -152,8 +247,10 @@ class ReadParameters:
|
|
|
152
247
|
continue
|
|
153
248
|
|
|
154
249
|
file_flag = parameter_data.get("file", False)
|
|
155
|
-
value = self._format_parameter_value(value_data, unit, file_flag)
|
|
156
250
|
parameter_version = parameter_data.get("parameter_version")
|
|
251
|
+
value = self._format_parameter_value(
|
|
252
|
+
parameter_name, value_data, unit, file_flag, parameter_version=None
|
|
253
|
+
)
|
|
157
254
|
model_version = version
|
|
158
255
|
|
|
159
256
|
# Group the data by parameter version and store model versions as a list
|
|
@@ -168,26 +265,29 @@ class ReadParameters:
|
|
|
168
265
|
|
|
169
266
|
return self._group_model_versions_by_parameter_version(grouped_data)
|
|
170
267
|
|
|
171
|
-
def get_all_parameter_descriptions(self):
|
|
172
|
-
"""
|
|
173
|
-
Get descriptions for all model parameters.
|
|
268
|
+
def get_all_parameter_descriptions(self, collection="telescopes"):
|
|
269
|
+
"""Get descriptions for all model parameters.
|
|
174
270
|
|
|
175
271
|
Returns
|
|
176
272
|
-------
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
273
|
+
dict
|
|
274
|
+
Nested dictionaries with first key as the parameter name and
|
|
275
|
+
the following dictionary as the value:
|
|
276
|
+
- key: description, value: description of the parameter.
|
|
277
|
+
- key: short_description, value: short description of the parameter.
|
|
278
|
+
- key: inst_class, value: class, for eg. Structure, Camera, etc.
|
|
181
279
|
"""
|
|
182
|
-
|
|
280
|
+
parameter_dict = {}
|
|
183
281
|
|
|
184
|
-
for instrument_class in names.db_collection_to_instrument_class_key(
|
|
282
|
+
for instrument_class in names.db_collection_to_instrument_class_key(collection):
|
|
185
283
|
for parameter, details in names.model_parameters(instrument_class).items():
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
284
|
+
parameter_dict[parameter] = {
|
|
285
|
+
"description": details.get("description"),
|
|
286
|
+
"short_description": details.get("short_description"),
|
|
287
|
+
"inst_class": instrument_class,
|
|
288
|
+
}
|
|
189
289
|
|
|
190
|
-
return
|
|
290
|
+
return parameter_dict
|
|
191
291
|
|
|
192
292
|
def get_array_element_parameter_data(self, telescope_model, collection="telescopes"):
|
|
193
293
|
"""
|
|
@@ -219,8 +319,6 @@ class ReadParameters:
|
|
|
219
319
|
|
|
220
320
|
for parameter in filter(all_parameter_data.__contains__, names.model_parameters().keys()):
|
|
221
321
|
parameter_data = all_parameter_data.get(parameter)
|
|
222
|
-
if parameter_data["instrument"] != telescope_model.name:
|
|
223
|
-
continue
|
|
224
322
|
parameter_version = telescope_model.get_parameter_version(parameter)
|
|
225
323
|
unit = parameter_data.get("unit") or " "
|
|
226
324
|
value_data = parameter_data.get("value")
|
|
@@ -229,11 +327,25 @@ class ReadParameters:
|
|
|
229
327
|
continue
|
|
230
328
|
|
|
231
329
|
file_flag = parameter_data.get("file", False)
|
|
232
|
-
value = self._format_parameter_value(
|
|
330
|
+
value = self._format_parameter_value(
|
|
331
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
description = parameter_descriptions.get(parameter).get("description")
|
|
335
|
+
short_description = (
|
|
336
|
+
parameter_descriptions.get(parameter).get("short_description") or description
|
|
337
|
+
)
|
|
338
|
+
inst_class = parameter_descriptions.get(parameter).get("inst_class")
|
|
339
|
+
|
|
340
|
+
matching_instrument = parameter_data["instrument"] == telescope_model.name
|
|
341
|
+
if not names.is_design_type(telescope_model.name) and matching_instrument:
|
|
342
|
+
parameter = f"***{parameter}***"
|
|
343
|
+
parameter_version = f"***{parameter_version}***"
|
|
344
|
+
if not re.match(r"^\[.*\]\(.*\)$", value.strip()):
|
|
345
|
+
value = f"***{value}***"
|
|
346
|
+
description = f"***{description}***"
|
|
347
|
+
short_description = f"***{short_description}***"
|
|
233
348
|
|
|
234
|
-
description = parameter_descriptions[0].get(parameter)
|
|
235
|
-
short_description = parameter_descriptions[1].get(parameter, description)
|
|
236
|
-
inst_class = parameter_descriptions[2].get(parameter)
|
|
237
349
|
data.append(
|
|
238
350
|
[
|
|
239
351
|
inst_class,
|
|
@@ -247,6 +359,120 @@ class ReadParameters:
|
|
|
247
359
|
|
|
248
360
|
return data
|
|
249
361
|
|
|
362
|
+
def _write_to_file(self, data, file):
|
|
363
|
+
# Write table header and separator row
|
|
364
|
+
file.write(
|
|
365
|
+
"| Parameter Name | Parameter Version "
|
|
366
|
+
"| Values | Short Description |\n"
|
|
367
|
+
"|---------------------|------------------------"
|
|
368
|
+
"|-------------|-----------------------------|\n"
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Write table rows
|
|
372
|
+
column_widths = [10, 10, 20, 60]
|
|
373
|
+
for (
|
|
374
|
+
_,
|
|
375
|
+
parameter_name,
|
|
376
|
+
parameter_version,
|
|
377
|
+
value,
|
|
378
|
+
description,
|
|
379
|
+
short_description,
|
|
380
|
+
) in data:
|
|
381
|
+
text = short_description if short_description else description
|
|
382
|
+
wrapped_text = textwrap.fill(str(text), column_widths[3]).split("\n")
|
|
383
|
+
wrapped_text = " ".join(wrapped_text)
|
|
384
|
+
parameter_name = self._wrap_at_underscores(parameter_name, column_widths[0])
|
|
385
|
+
|
|
386
|
+
file.write(
|
|
387
|
+
f"| {parameter_name:{column_widths[0]}} |"
|
|
388
|
+
f" {parameter_version:{column_widths[1]}} |"
|
|
389
|
+
f" {value:{column_widths[2]}} |"
|
|
390
|
+
f" {wrapped_text:{column_widths[3]}} |\n"
|
|
391
|
+
)
|
|
392
|
+
file.write("\n\n")
|
|
393
|
+
|
|
394
|
+
def get_simulation_configuration_data(self):
|
|
395
|
+
"""Get data and descriptions for simulation configuration parameters."""
|
|
396
|
+
|
|
397
|
+
def get_param_data(telescope, site):
|
|
398
|
+
"""Retrieve and format parameter data for one telescope-site combo."""
|
|
399
|
+
param_dict = self.db.get_simulation_configuration_parameters(
|
|
400
|
+
simulation_software=self.software,
|
|
401
|
+
site=site,
|
|
402
|
+
array_element_name=telescope,
|
|
403
|
+
model_version=self.model_version,
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
parameter_descriptions = self.get_all_parameter_descriptions(
|
|
407
|
+
collection=f"configuration_{self.software}"
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
model_output_path = Path(f"{self.output_path}/model")
|
|
411
|
+
model_output_path.mkdir(parents=True, exist_ok=True)
|
|
412
|
+
self.db.export_model_files(parameters=param_dict, dest=str(model_output_path))
|
|
413
|
+
|
|
414
|
+
data = []
|
|
415
|
+
for parameter, parameter_data in param_dict.items():
|
|
416
|
+
description = parameter_descriptions.get(parameter).get("description")
|
|
417
|
+
short_description = parameter_descriptions.get(parameter).get(
|
|
418
|
+
"short_description", description
|
|
419
|
+
)
|
|
420
|
+
value_data = parameter_data.get("value")
|
|
421
|
+
|
|
422
|
+
if value_data is None:
|
|
423
|
+
continue
|
|
424
|
+
|
|
425
|
+
unit = parameter_data.get("unit") or " "
|
|
426
|
+
file_flag = parameter_data.get("file", False)
|
|
427
|
+
parameter_version = parameter_data.get("parameter_version")
|
|
428
|
+
value = self._format_parameter_value(
|
|
429
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
data.append(
|
|
433
|
+
[
|
|
434
|
+
telescope,
|
|
435
|
+
parameter,
|
|
436
|
+
parameter_version,
|
|
437
|
+
value,
|
|
438
|
+
description,
|
|
439
|
+
short_description,
|
|
440
|
+
]
|
|
441
|
+
)
|
|
442
|
+
return data
|
|
443
|
+
|
|
444
|
+
if self.software == "corsika":
|
|
445
|
+
return get_param_data(self.array_element, self.site)
|
|
446
|
+
|
|
447
|
+
results = []
|
|
448
|
+
telescopes = self.db.get_array_elements(self.model_version)
|
|
449
|
+
for telescope in telescopes:
|
|
450
|
+
valid_site = names.get_site_from_array_element_name(telescope)
|
|
451
|
+
if not isinstance(valid_site, list):
|
|
452
|
+
results.extend(get_param_data(telescope, valid_site))
|
|
453
|
+
else:
|
|
454
|
+
for site in valid_site:
|
|
455
|
+
results.extend(get_param_data(telescope, site))
|
|
456
|
+
return results
|
|
457
|
+
|
|
458
|
+
def produce_simulation_configuration_report(self):
|
|
459
|
+
"""Write simulation configuration report."""
|
|
460
|
+
output_filename = Path(self.output_path / (f"configuration_{self.software}.md"))
|
|
461
|
+
output_filename.parent.mkdir(parents=True, exist_ok=True)
|
|
462
|
+
data = self.get_simulation_configuration_data()
|
|
463
|
+
|
|
464
|
+
with output_filename.open("w", encoding="utf-8") as file:
|
|
465
|
+
file.write(f"# configuration_{self.software}\n")
|
|
466
|
+
file.write("\n\n")
|
|
467
|
+
if self.software == "sim_telarray":
|
|
468
|
+
data.sort(key=lambda x: (x[0], x[1]))
|
|
469
|
+
for telescope, group in groupby(data, key=lambda x: x[0]):
|
|
470
|
+
file.write(f"## [{telescope}]({telescope}.md)\n")
|
|
471
|
+
file.write("\n\n")
|
|
472
|
+
self._write_to_file(group, file)
|
|
473
|
+
else:
|
|
474
|
+
self._write_to_file(data, file)
|
|
475
|
+
|
|
250
476
|
def produce_array_element_report(self):
|
|
251
477
|
"""
|
|
252
478
|
Produce a markdown report of all model parameters per array element.
|
|
@@ -281,44 +507,20 @@ class ReadParameters:
|
|
|
281
507
|
file.write(
|
|
282
508
|
"The design model can be found here: "
|
|
283
509
|
f"[{telescope_model.design_model}]"
|
|
284
|
-
f"({telescope_model.design_model}.md).\n"
|
|
510
|
+
f"({telescope_model.design_model}.md).\n\n"
|
|
511
|
+
)
|
|
512
|
+
file.write(
|
|
513
|
+
"Parameters shown in ***bold and italics*** are specific to each telescope.\n"
|
|
514
|
+
"Parameters without emphasis are inherited from the design model.\n"
|
|
285
515
|
)
|
|
286
516
|
file.write("\n\n")
|
|
287
517
|
|
|
288
518
|
for class_name, group in groupby(data, key=lambda x: x[0]):
|
|
289
519
|
group = sorted(group, key=lambda x: x[1])
|
|
290
520
|
file.write(f"## {class_name}\n\n")
|
|
521
|
+
self._write_to_file(group, file)
|
|
291
522
|
|
|
292
|
-
|
|
293
|
-
file.write(
|
|
294
|
-
"| Parameter Name | Parameter Version "
|
|
295
|
-
"| Values | Short Description |\n"
|
|
296
|
-
"|---------------------|------------------------"
|
|
297
|
-
"|-------------|-----------------------------|\n"
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
# Write table rows
|
|
301
|
-
column_widths = [20, 20, 20, 70]
|
|
302
|
-
for (
|
|
303
|
-
_,
|
|
304
|
-
parameter_name,
|
|
305
|
-
parameter_version,
|
|
306
|
-
value,
|
|
307
|
-
description,
|
|
308
|
-
short_description,
|
|
309
|
-
) in group:
|
|
310
|
-
text = short_description if short_description else description
|
|
311
|
-
wrapped_text = textwrap.fill(str(text), column_widths[3]).split("\n")
|
|
312
|
-
wrapped_text = " ".join(wrapped_text)
|
|
313
|
-
file.write(
|
|
314
|
-
f"| {parameter_name:{column_widths[0]}} |"
|
|
315
|
-
f" {parameter_version:{column_widths[1]}} |"
|
|
316
|
-
f" {value:{column_widths[2]}} |"
|
|
317
|
-
f" {wrapped_text} |\n"
|
|
318
|
-
)
|
|
319
|
-
file.write("\n\n")
|
|
320
|
-
|
|
321
|
-
def produce_model_parameter_reports(self):
|
|
523
|
+
def produce_model_parameter_reports(self, collection="telescopes"):
|
|
322
524
|
"""
|
|
323
525
|
Produce a markdown report per parameter for a given array element.
|
|
324
526
|
|
|
@@ -334,7 +536,7 @@ class ReadParameters:
|
|
|
334
536
|
|
|
335
537
|
all_parameter_names = names.model_parameters(None).keys()
|
|
336
538
|
all_parameter_data = self.db.get_model_parameters_for_all_model_versions(
|
|
337
|
-
site=self.site, array_element_name=self.array_element, collection=
|
|
539
|
+
site=self.site, array_element_name=self.array_element, collection=collection
|
|
338
540
|
)
|
|
339
541
|
|
|
340
542
|
comparison_data = self._compare_parameter_across_versions(
|
|
@@ -347,7 +549,12 @@ class ReadParameters:
|
|
|
347
549
|
continue
|
|
348
550
|
|
|
349
551
|
output_filename = output_path / f"{parameter}.md"
|
|
350
|
-
|
|
552
|
+
|
|
553
|
+
parameter_descriptions = self.get_all_parameter_descriptions(collection=collection).get(
|
|
554
|
+
parameter
|
|
555
|
+
) or self.get_all_parameter_descriptions(collection="telescopes").get(parameter)
|
|
556
|
+
|
|
557
|
+
description = parameter_descriptions.get("description")
|
|
351
558
|
with output_filename.open("w", encoding="utf-8") as file:
|
|
352
559
|
# Write header
|
|
353
560
|
file.write(
|
|
@@ -370,16 +577,16 @@ class ReadParameters:
|
|
|
370
577
|
file.write(
|
|
371
578
|
f"| {item['parameter_version']} |"
|
|
372
579
|
f" {item['model_version']} |"
|
|
373
|
-
f"{item['value']
|
|
580
|
+
f"{item['value']} |\n"
|
|
374
581
|
)
|
|
375
582
|
|
|
376
583
|
file.write("\n")
|
|
377
584
|
if comparison_data.get(parameter)[0]["file_flag"]:
|
|
378
|
-
file.write(f"")
|
|
585
|
+
file.write(f"")
|
|
379
586
|
|
|
380
587
|
def _write_array_layouts_section(self, file, layouts):
|
|
381
588
|
"""Write the array layouts section of the report."""
|
|
382
|
-
file.write("\n## Array Layouts
|
|
589
|
+
file.write("\n## Array Layouts\n\n")
|
|
383
590
|
for layout in layouts:
|
|
384
591
|
layout_name = layout["name"]
|
|
385
592
|
elements = layout["elements"]
|
|
@@ -388,10 +595,15 @@ class ReadParameters:
|
|
|
388
595
|
for element in sorted(elements):
|
|
389
596
|
file.write(f"| [{element}]({element}.md) |\n")
|
|
390
597
|
file.write("\n")
|
|
598
|
+
version = self.model_version.replace(".", "-")
|
|
599
|
+
filename = f"OBS-{self.site}_{layout_name}_{version}.png"
|
|
600
|
+
image_path = f"/_images/{filename}"
|
|
601
|
+
file.write(f"\n\n")
|
|
602
|
+
file.write("\n")
|
|
391
603
|
|
|
392
604
|
def _write_array_triggers_section(self, file, trigger_configs):
|
|
393
605
|
"""Write the array triggers section of the report."""
|
|
394
|
-
file.write("\n## Array Trigger Configurations
|
|
606
|
+
file.write("\n## Array Trigger Configurations\n\n")
|
|
395
607
|
file.write(
|
|
396
608
|
"| Trigger Name | Multiplicity | Width | Hard Stereo | Min Separation |\n"
|
|
397
609
|
"|--------------|--------------|--------|-------------|----------------|\n"
|
|
@@ -411,24 +623,34 @@ class ReadParameters:
|
|
|
411
623
|
|
|
412
624
|
def _write_parameters_table(self, file, all_parameter_data):
|
|
413
625
|
"""Write the main parameters table of the report."""
|
|
414
|
-
file.write(
|
|
626
|
+
file.write(
|
|
627
|
+
"| Parameter | Value | Parameter Version |\n"
|
|
628
|
+
"|-----------|--------|-------------------|\n"
|
|
629
|
+
)
|
|
415
630
|
for param_name, param_data in sorted(all_parameter_data.items()):
|
|
416
631
|
value = param_data.get("value")
|
|
417
632
|
unit = param_data.get("unit") or " "
|
|
418
633
|
file_flag = param_data.get("file", False)
|
|
634
|
+
parameter_version = param_data.get("parameter_version")
|
|
419
635
|
|
|
420
636
|
if value is None:
|
|
421
637
|
continue
|
|
422
638
|
|
|
423
639
|
if param_name == "array_layouts":
|
|
424
|
-
file.write(
|
|
640
|
+
file.write(
|
|
641
|
+
"| array_layouts | [View Array Layouts](#array-layouts)"
|
|
642
|
+
f" | {parameter_version} |\n"
|
|
643
|
+
)
|
|
425
644
|
elif param_name == "array_triggers":
|
|
426
645
|
file.write(
|
|
427
|
-
"| array_triggers | [View Trigger Configurations]
|
|
646
|
+
"| array_triggers | [View Trigger Configurations]"
|
|
647
|
+
f"(#array-trigger-configurations) | {parameter_version} |\n"
|
|
428
648
|
)
|
|
429
649
|
else:
|
|
430
|
-
formatted_value = self._format_parameter_value(
|
|
431
|
-
|
|
650
|
+
formatted_value = self._format_parameter_value(
|
|
651
|
+
param_name, value, unit, file_flag, parameter_version
|
|
652
|
+
)
|
|
653
|
+
file.write(f"| {param_name} | {formatted_value} | {parameter_version} |\n")
|
|
432
654
|
file.write("\n")
|
|
433
655
|
|
|
434
656
|
def produce_observatory_report(self):
|
|
@@ -463,3 +685,126 @@ class ReadParameters:
|
|
|
463
685
|
self._write_array_triggers_section(
|
|
464
686
|
file, all_parameter_data["array_triggers"]["value"]
|
|
465
687
|
)
|
|
688
|
+
|
|
689
|
+
def get_calibration_data(self, all_parameter_data, array_element):
|
|
690
|
+
"""Get calibration data and descriptions for a given array element."""
|
|
691
|
+
calibration_descriptions = self.get_all_parameter_descriptions(
|
|
692
|
+
collection="calibration_devices"
|
|
693
|
+
)
|
|
694
|
+
# get descriptions of array element positions from the telescope collection
|
|
695
|
+
telescope_descriptions = self.get_all_parameter_descriptions(collection="telescopes")
|
|
696
|
+
data = []
|
|
697
|
+
class_grouped_data = {}
|
|
698
|
+
|
|
699
|
+
for parameter in all_parameter_data.keys():
|
|
700
|
+
parameter_descriptions = calibration_descriptions.get(
|
|
701
|
+
parameter
|
|
702
|
+
) or telescope_descriptions.get(parameter)
|
|
703
|
+
|
|
704
|
+
parameter_data = all_parameter_data.get(parameter)
|
|
705
|
+
parameter_version = parameter_data.get("parameter_version")
|
|
706
|
+
unit = parameter_data.get("unit") or " "
|
|
707
|
+
value_data = parameter_data.get("value")
|
|
708
|
+
|
|
709
|
+
if value_data is None:
|
|
710
|
+
continue
|
|
711
|
+
|
|
712
|
+
file_flag = parameter_data.get("file", False)
|
|
713
|
+
value = self._format_parameter_value(
|
|
714
|
+
parameter, value_data, unit, file_flag, parameter_version
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
description = parameter_descriptions.get("description")
|
|
718
|
+
short_description = parameter_descriptions.get("short_description") or description
|
|
719
|
+
|
|
720
|
+
inst_class = parameter_descriptions.get("inst_class")
|
|
721
|
+
|
|
722
|
+
matching_instrument = parameter_data["instrument"] == array_element
|
|
723
|
+
if not names.is_design_type(array_element) and matching_instrument:
|
|
724
|
+
parameter = f"***{parameter}***"
|
|
725
|
+
parameter_version = f"***{parameter_version}***"
|
|
726
|
+
if not re.match(r"^\[.*\]\(.*\)$", value.strip()):
|
|
727
|
+
value = f"***{value}***"
|
|
728
|
+
description = f"***{description}***"
|
|
729
|
+
short_description = f"***{short_description}***"
|
|
730
|
+
|
|
731
|
+
# Group by class name
|
|
732
|
+
if inst_class not in class_grouped_data:
|
|
733
|
+
class_grouped_data[inst_class] = []
|
|
734
|
+
|
|
735
|
+
class_grouped_data[inst_class].append(
|
|
736
|
+
[
|
|
737
|
+
inst_class,
|
|
738
|
+
parameter,
|
|
739
|
+
parameter_version,
|
|
740
|
+
value,
|
|
741
|
+
description,
|
|
742
|
+
short_description,
|
|
743
|
+
]
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
data = []
|
|
747
|
+
for class_name in sorted(class_grouped_data.keys(), reverse=True):
|
|
748
|
+
sorted_class_data = sorted(class_grouped_data[class_name], key=lambda x: x[1])
|
|
749
|
+
data.extend(sorted_class_data)
|
|
750
|
+
|
|
751
|
+
return data
|
|
752
|
+
|
|
753
|
+
def produce_calibration_reports(self):
|
|
754
|
+
"""Write calibration reports."""
|
|
755
|
+
calibration_array_elements = self.db.get_array_elements(
|
|
756
|
+
self.model_version, collection="calibration_devices"
|
|
757
|
+
)
|
|
758
|
+
array_elements = calibration_array_elements.copy()
|
|
759
|
+
for element in calibration_array_elements:
|
|
760
|
+
design_model = self.db.get_design_model(
|
|
761
|
+
self.model_version, element, "calibration_devices"
|
|
762
|
+
)
|
|
763
|
+
if design_model and design_model not in array_elements:
|
|
764
|
+
array_elements.append(design_model)
|
|
765
|
+
|
|
766
|
+
for calibration_device in array_elements:
|
|
767
|
+
all_parameter_data = self.db.get_model_parameters(
|
|
768
|
+
site=names.get_site_from_array_element_name(calibration_device),
|
|
769
|
+
array_element_name=calibration_device,
|
|
770
|
+
collection="calibration_devices",
|
|
771
|
+
model_version=self.model_version,
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
output_filename = Path(self.output_path / (f"{calibration_device}.md"))
|
|
775
|
+
output_filename.parent.mkdir(parents=True, exist_ok=True)
|
|
776
|
+
data = self.get_calibration_data(all_parameter_data, calibration_device)
|
|
777
|
+
|
|
778
|
+
design_model = self.db.get_design_model(
|
|
779
|
+
self.model_version, calibration_device, "calibration_devices"
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
with output_filename.open("w", encoding="utf-8") as file:
|
|
783
|
+
file.write(f"# {calibration_device}\n")
|
|
784
|
+
file.write("\n\n")
|
|
785
|
+
|
|
786
|
+
if not names.is_design_type(calibration_device):
|
|
787
|
+
file.write(
|
|
788
|
+
"The design model can be found here: "
|
|
789
|
+
f"[{design_model}]"
|
|
790
|
+
f"({design_model}.md).\n\n"
|
|
791
|
+
)
|
|
792
|
+
file.write(
|
|
793
|
+
"Parameters shown in ***bold and italics*** are specific"
|
|
794
|
+
" to each array element.\n"
|
|
795
|
+
"Parameters without emphasis are inherited from the design model.\n"
|
|
796
|
+
)
|
|
797
|
+
file.write("\n\n")
|
|
798
|
+
|
|
799
|
+
for class_name, group in groupby(data, key=lambda x: x[0]):
|
|
800
|
+
group = sorted(group, key=lambda x: x[1])
|
|
801
|
+
file.write(f"## {class_name}\n\n")
|
|
802
|
+
self._write_to_file(group, file)
|
|
803
|
+
|
|
804
|
+
new_output_path = Path(self.output_path).parent.parent / "parameters"
|
|
805
|
+
new_output_path.mkdir(parents=True, exist_ok=True)
|
|
806
|
+
self.output_path = new_output_path
|
|
807
|
+
for calibration_device in array_elements:
|
|
808
|
+
self.site = names.get_site_from_array_element_name(calibration_device)
|
|
809
|
+
self.array_element = calibration_device
|
|
810
|
+
self.produce_model_parameter_reports(collection="calibration_devices")
|