gammasimtools 0.22.0__py3-none-any.whl → 0.23.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/RECORD +114 -112
- simtools/_version.py +2 -2
- simtools/application_control.py +118 -0
- simtools/applications/calculate_incident_angles.py +17 -22
- simtools/applications/convert_all_model_parameters_from_simtel.py +28 -43
- simtools/applications/convert_geo_coordinates_of_array_elements.py +26 -45
- simtools/applications/convert_model_parameter_from_simtel.py +21 -41
- simtools/applications/db_add_file_to_db.py +12 -13
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +20 -33
- simtools/applications/db_add_value_from_json_to_db.py +28 -23
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +19 -34
- simtools/applications/db_generate_compound_indexes.py +11 -13
- simtools/applications/db_get_array_layouts_from_db.py +19 -39
- simtools/applications/db_get_file_from_db.py +15 -17
- simtools/applications/db_get_parameter_from_db.py +33 -35
- simtools/applications/db_inspect_databases.py +10 -11
- simtools/applications/db_upload_model_repository.py +13 -31
- simtools/applications/derive_ctao_array_layouts.py +16 -21
- simtools/applications/derive_mirror_rnda.py +9 -14
- simtools/applications/derive_photon_electron_spectrum.py +7 -10
- simtools/applications/derive_psf_parameters.py +13 -20
- simtools/applications/derive_trigger_rates.py +6 -9
- simtools/applications/docs_produce_array_element_report.py +22 -23
- simtools/applications/docs_produce_calibration_reports.py +26 -24
- simtools/applications/docs_produce_model_parameter_reports.py +15 -22
- simtools/applications/docs_produce_simulation_configuration_report.py +21 -22
- simtools/applications/generate_array_config.py +14 -33
- simtools/applications/generate_corsika_histograms.py +22 -43
- simtools/applications/generate_default_metadata.py +15 -36
- simtools/applications/generate_regular_arrays.py +11 -15
- simtools/applications/generate_simtel_event_data.py +23 -33
- simtools/applications/maintain_simulation_model_add_production.py +12 -19
- simtools/applications/maintain_simulation_model_compare_productions.py +10 -12
- simtools/applications/maintain_simulation_model_verify_production_tables.py +8 -11
- simtools/applications/merge_tables.py +14 -23
- simtools/applications/plot_array_layout.py +77 -54
- simtools/applications/plot_simtel_events.py +11 -13
- simtools/applications/plot_tabular_data.py +17 -38
- simtools/applications/plot_tabular_data_for_model_parameter.py +16 -23
- simtools/applications/print_version.py +14 -42
- simtools/applications/production_derive_corsika_limits.py +5 -9
- simtools/applications/production_derive_statistics.py +12 -25
- simtools/applications/production_generate_grid.py +20 -48
- simtools/applications/production_merge_corsika_limits.py +17 -21
- simtools/applications/run_application.py +12 -32
- simtools/applications/simulate_flasher.py +21 -25
- simtools/applications/simulate_illuminator.py +7 -14
- simtools/applications/simulate_pedestals.py +13 -13
- simtools/applications/simulate_prod.py +21 -33
- simtools/applications/simulate_prod_htcondor_generator.py +11 -25
- simtools/applications/submit_array_layouts.py +15 -18
- simtools/applications/submit_data_from_external.py +18 -34
- simtools/applications/submit_model_parameter_from_external.py +27 -40
- simtools/applications/validate_camera_efficiency.py +23 -21
- simtools/applications/validate_camera_fov.py +21 -26
- simtools/applications/validate_cumulative_psf.py +27 -35
- simtools/applications/validate_file_using_schema.py +15 -33
- simtools/applications/validate_optics.py +26 -32
- simtools/camera/camera_efficiency.py +0 -2
- simtools/configuration/commandline_parser.py +32 -4
- simtools/configuration/configurator.py +0 -5
- simtools/corsika/corsika_config.py +0 -5
- simtools/data_model/data_reader.py +0 -2
- simtools/data_model/metadata_collector.py +0 -2
- simtools/data_model/model_data_writer.py +0 -2
- simtools/data_model/validate_data.py +0 -2
- simtools/db/db_handler.py +0 -2
- simtools/io/hdf5_handler.py +0 -5
- simtools/io/legacy_data_handler.py +0 -5
- simtools/job_execution/job_manager.py +0 -3
- simtools/layout/array_layout.py +0 -2
- simtools/layout/telescope_position.py +0 -2
- simtools/model/array_model.py +2 -4
- simtools/model/calibration_model.py +0 -2
- simtools/model/camera.py +0 -2
- simtools/model/mirrors.py +0 -2
- simtools/model/model_parameter.py +30 -7
- simtools/model/model_utils.py +0 -5
- simtools/model/site_model.py +0 -2
- simtools/model/telescope_model.py +0 -2
- simtools/production_configuration/calculate_statistical_uncertainties_grid_point.py +0 -2
- simtools/production_configuration/derive_production_statistics.py +0 -2
- simtools/production_configuration/interpolation_handler.py +0 -2
- simtools/ray_tracing/psf_analysis.py +0 -2
- simtools/ray_tracing/ray_tracing.py +0 -2
- simtools/reporting/docs_auto_report_generator.py +108 -0
- simtools/reporting/docs_read_parameters.py +1 -7
- simtools/runners/corsika_runner.py +0 -2
- simtools/runners/corsika_simtel_runner.py +0 -2
- simtools/runners/simtel_runner.py +0 -2
- simtools/schemas/model_parameters/transit_time_random.schema.yml +29 -0
- simtools/simtel/simtel_config_reader.py +0 -2
- simtools/simtel/simtel_config_writer.py +31 -13
- simtools/simtel/simtel_io_metadata.py +3 -3
- simtools/simtel/simulator_array.py +9 -21
- simtools/simtel/simulator_camera_efficiency.py +0 -2
- simtools/simtel/simulator_light_emission.py +1 -3
- simtools/simtel/simulator_ray_tracing.py +0 -2
- simtools/simulator.py +0 -5
- simtools/testing/assertions.py +2 -2
- simtools/testing/configuration.py +17 -4
- simtools/utils/general.py +5 -13
- simtools/utils/geometry.py +0 -5
- simtools/utils/names.py +1 -13
- simtools/version.py +61 -0
- simtools/visualization/plot_array_layout.py +129 -23
- simtools/visualization/plot_incident_angles.py +0 -2
- simtools/visualization/plot_simtel_events.py +0 -11
- simtools/visualization/visualize.py +0 -12
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/entry_points.txt +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/top_level.txt +0 -0
|
@@ -5,6 +5,7 @@ import os
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
import simtools.utils.general as gen
|
|
8
|
+
import simtools.version as simtools_version
|
|
8
9
|
from simtools.io import ascii_handler
|
|
9
10
|
|
|
10
11
|
_logger = logging.getLogger(__name__)
|
|
@@ -130,11 +131,23 @@ def configure(config, tmp_test_directory, request):
|
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
def _skip_test_for_model_version(config, model_version_requested):
|
|
133
|
-
"""
|
|
134
|
-
|
|
134
|
+
"""
|
|
135
|
+
Skip test if model version requested is not supported.
|
|
136
|
+
|
|
137
|
+
Compares full and major.minor version strings.
|
|
138
|
+
"""
|
|
139
|
+
if not (config.get("model_version_use_current") and model_version_requested):
|
|
135
140
|
return
|
|
136
|
-
model_version_config = config["configuration"]["model_version"]
|
|
137
|
-
|
|
141
|
+
model_version_config = str(config["configuration"]["model_version"])
|
|
142
|
+
|
|
143
|
+
if (
|
|
144
|
+
simtools_version.compare_versions(
|
|
145
|
+
model_version_requested,
|
|
146
|
+
model_version_config,
|
|
147
|
+
level=simtools_version.version_kind(model_version_requested),
|
|
148
|
+
)
|
|
149
|
+
!= 0
|
|
150
|
+
):
|
|
138
151
|
raise VersionError(
|
|
139
152
|
f"Model version requested {model_version_requested} not supported for this test"
|
|
140
153
|
)
|
simtools/utils/general.py
CHANGED
|
@@ -13,17 +13,6 @@ from urllib.parse import urlparse
|
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
15
|
|
|
16
|
-
__all__ = [
|
|
17
|
-
"change_dict_keys_case",
|
|
18
|
-
"clear_default_sim_telarray_cfg_directories",
|
|
19
|
-
"collect_final_lines",
|
|
20
|
-
"collect_kwargs",
|
|
21
|
-
"get_log_excerpt",
|
|
22
|
-
"get_log_level_from_user",
|
|
23
|
-
"remove_substring_recursively_from_dict",
|
|
24
|
-
"set_default_kwargs",
|
|
25
|
-
]
|
|
26
|
-
|
|
27
16
|
_logger = logging.getLogger(__name__)
|
|
28
17
|
|
|
29
18
|
|
|
@@ -345,7 +334,7 @@ def resolve_file_patterns(file_names):
|
|
|
345
334
|
return _files
|
|
346
335
|
|
|
347
336
|
|
|
348
|
-
def pack_tar_file(tar_file_name, file_list):
|
|
337
|
+
def pack_tar_file(tar_file_name, file_list, sub_dir=None):
|
|
349
338
|
"""
|
|
350
339
|
Pack files into a tar.gz archive.
|
|
351
340
|
|
|
@@ -355,6 +344,8 @@ def pack_tar_file(tar_file_name, file_list):
|
|
|
355
344
|
Name of the output tar.gz file.
|
|
356
345
|
file_list: list
|
|
357
346
|
List of files to include in the archive.
|
|
347
|
+
sub_dir: str, optional
|
|
348
|
+
Subdirectory within the archive to place the files.
|
|
358
349
|
"""
|
|
359
350
|
file_list = [Path(f) for f in file_list]
|
|
360
351
|
base = Path(os.path.commonpath([f.resolve() for f in file_list]))
|
|
@@ -365,7 +356,8 @@ def pack_tar_file(tar_file_name, file_list):
|
|
|
365
356
|
|
|
366
357
|
with tarfile.open(tar_file_name, "w:gz") as tar:
|
|
367
358
|
for file in file_list:
|
|
368
|
-
|
|
359
|
+
arc_name = Path(sub_dir) / file.name if sub_dir else file.name
|
|
360
|
+
tar.add(file, arcname=str(arc_name))
|
|
369
361
|
|
|
370
362
|
|
|
371
363
|
def get_log_excerpt(log_file, n_last_lines=30):
|
simtools/utils/geometry.py
CHANGED
simtools/utils/names.py
CHANGED
|
@@ -28,18 +28,6 @@ from simtools.constants import (
|
|
|
28
28
|
|
|
29
29
|
_logger = logging.getLogger(__name__)
|
|
30
30
|
|
|
31
|
-
__all__ = [
|
|
32
|
-
"generate_file_name",
|
|
33
|
-
"get_array_element_type_from_name",
|
|
34
|
-
"get_site_from_array_element_name",
|
|
35
|
-
"sanitize_name",
|
|
36
|
-
"simtel_config_file_name",
|
|
37
|
-
"simtel_single_mirror_list_file_name",
|
|
38
|
-
"validate_array_element_id_name",
|
|
39
|
-
"validate_array_element_name",
|
|
40
|
-
"validate_site_name",
|
|
41
|
-
]
|
|
42
|
-
|
|
43
31
|
# Mapping of db collection names to class keys
|
|
44
32
|
db_collections_to_class_keys = {
|
|
45
33
|
"sites": ["Site"],
|
|
@@ -122,7 +110,7 @@ def site_names():
|
|
|
122
110
|
@cache
|
|
123
111
|
def array_element_design_types(array_element_type):
|
|
124
112
|
"""
|
|
125
|
-
Get array element
|
|
113
|
+
Get array element design type (e.g., 'design' or 'flashcam').
|
|
126
114
|
|
|
127
115
|
Default values are ['design', 'test'].
|
|
128
116
|
|
simtools/version.py
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
from packaging.version import InvalidVersion, Version
|
|
8
8
|
|
|
9
|
+
MAJOR_MINOR_PATCH = "major.minor.patch"
|
|
10
|
+
MAJOR_MINOR = "major.minor"
|
|
11
|
+
|
|
9
12
|
try:
|
|
10
13
|
try:
|
|
11
14
|
from ._dev_version import version
|
|
@@ -128,3 +131,61 @@ def sort_versions(version_list, reverse=False):
|
|
|
128
131
|
return [str(v) for v in sorted(map(Version, version_list), reverse=reverse)]
|
|
129
132
|
except InvalidVersion as exc:
|
|
130
133
|
raise ValueError(f"Invalid version in list: {version_list}") from exc
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def version_kind(version_string):
|
|
137
|
+
"""
|
|
138
|
+
Determine the kind of version string.
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
version_string : str
|
|
143
|
+
The version string to analyze.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
str
|
|
148
|
+
The kind of version string ("major.minor", "major.minor.patch", or "major").
|
|
149
|
+
"""
|
|
150
|
+
try:
|
|
151
|
+
ver = Version(version_string)
|
|
152
|
+
except InvalidVersion as exc:
|
|
153
|
+
raise ValueError(f"Invalid version string: {version_string}") from exc
|
|
154
|
+
if ver.release and len(ver.release) >= 3:
|
|
155
|
+
return MAJOR_MINOR_PATCH
|
|
156
|
+
if len(ver.release) == 2:
|
|
157
|
+
return MAJOR_MINOR
|
|
158
|
+
return "major"
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def compare_versions(version_string_1, version_string_2, level=MAJOR_MINOR_PATCH):
|
|
162
|
+
"""
|
|
163
|
+
Compare two versions at the given level: "major", "major.minor", "major.minor.patch".
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
version_string_1 : str
|
|
168
|
+
First version string to compare.
|
|
169
|
+
version_string_2 : str
|
|
170
|
+
Second version string to compare.
|
|
171
|
+
level : str, optional
|
|
172
|
+
Level of comparison: "major", "major.minor", or "major.minor.patch"
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
int
|
|
177
|
+
-1 if version_string_1 < version_string_2
|
|
178
|
+
0 if version_string_1 == version_string_2
|
|
179
|
+
1 if version_string_1 > version_string_2
|
|
180
|
+
"""
|
|
181
|
+
ver1 = Version(version_string_1).release
|
|
182
|
+
ver2 = Version(version_string_2).release
|
|
183
|
+
|
|
184
|
+
if level == "major":
|
|
185
|
+
ver1, ver2 = ver1[:1], ver2[:1]
|
|
186
|
+
elif level == MAJOR_MINOR:
|
|
187
|
+
ver1, ver2 = ver1[:2], ver2[:2]
|
|
188
|
+
elif level != MAJOR_MINOR_PATCH:
|
|
189
|
+
raise ValueError(f"Unknown level: {level}")
|
|
190
|
+
|
|
191
|
+
return (ver1 > ver2) - (ver1 < ver2)
|
|
@@ -13,8 +13,6 @@ from simtools.utils import geometry as transf
|
|
|
13
13
|
from simtools.utils import names
|
|
14
14
|
from simtools.visualization import legend_handlers as leg_h
|
|
15
15
|
|
|
16
|
-
__all__ = ["get_telescope_patch", "plot_array_layout"]
|
|
17
|
-
|
|
18
16
|
|
|
19
17
|
def plot_array_layout(
|
|
20
18
|
telescopes,
|
|
@@ -22,6 +20,9 @@ def plot_array_layout(
|
|
|
22
20
|
axes_range=None,
|
|
23
21
|
marker_scaling=1.0,
|
|
24
22
|
background_telescopes=None,
|
|
23
|
+
grayed_out_elements=None,
|
|
24
|
+
highlighted_elements=None,
|
|
25
|
+
legend_location="best",
|
|
25
26
|
):
|
|
26
27
|
"""
|
|
27
28
|
Plot telescope array layout.
|
|
@@ -38,6 +39,12 @@ def plot_array_layout(
|
|
|
38
39
|
Marker size scale factor.
|
|
39
40
|
background_telescopes : Table or None
|
|
40
41
|
Optional background telescope table.
|
|
42
|
+
grayed_out_elements : list or None
|
|
43
|
+
List of telescope names to plot as gray circles.
|
|
44
|
+
highlighted_elements : list or None
|
|
45
|
+
List of telescope names to plot with red circles around them.
|
|
46
|
+
legend_location : str
|
|
47
|
+
Location of the legend (default "best").
|
|
41
48
|
|
|
42
49
|
Returns
|
|
43
50
|
-------
|
|
@@ -46,55 +53,105 @@ def plot_array_layout(
|
|
|
46
53
|
"""
|
|
47
54
|
fig, ax = plt.subplots(1)
|
|
48
55
|
|
|
49
|
-
patches, plot_range = get_patches(
|
|
56
|
+
patches, plot_range, highlighted_patches = get_patches(
|
|
57
|
+
ax,
|
|
58
|
+
telescopes,
|
|
59
|
+
show_tel_label,
|
|
60
|
+
axes_range,
|
|
61
|
+
marker_scaling,
|
|
62
|
+
grayed_out_elements,
|
|
63
|
+
highlighted_elements,
|
|
64
|
+
)
|
|
50
65
|
|
|
51
66
|
if background_telescopes is not None:
|
|
52
|
-
bg_patches, bg_range = get_patches(
|
|
67
|
+
bg_patches, bg_range, _ = get_patches(
|
|
53
68
|
ax, background_telescopes, False, axes_range, marker_scaling
|
|
54
69
|
)
|
|
55
70
|
ax.add_collection(PatchCollection(bg_patches, match_original=True, alpha=0.1))
|
|
56
71
|
if axes_range is None:
|
|
57
72
|
plot_range = max(plot_range, bg_range)
|
|
58
73
|
|
|
59
|
-
update_legend(ax, telescopes)
|
|
60
|
-
finalize_plot(ax, patches, "Easting [m]", "Northing [m]", plot_range)
|
|
74
|
+
update_legend(ax, telescopes, grayed_out_elements, legend_location)
|
|
75
|
+
finalize_plot(ax, patches, "Easting [m]", "Northing [m]", plot_range, highlighted_patches)
|
|
61
76
|
|
|
62
77
|
return fig
|
|
63
78
|
|
|
64
79
|
|
|
65
|
-
def get_patches(
|
|
80
|
+
def get_patches(
|
|
81
|
+
ax,
|
|
82
|
+
telescopes,
|
|
83
|
+
show_tel_label,
|
|
84
|
+
axes_range,
|
|
85
|
+
marker_scaling,
|
|
86
|
+
grayed_out_elements=None,
|
|
87
|
+
highlighted_elements=None,
|
|
88
|
+
):
|
|
66
89
|
"""
|
|
67
90
|
Get plot patches and axis range.
|
|
68
91
|
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
ax : Axes
|
|
95
|
+
Matplotlib axes object.
|
|
96
|
+
telescopes : Table
|
|
97
|
+
Telescope data table.
|
|
98
|
+
show_tel_label : bool
|
|
99
|
+
Show telescope labels.
|
|
100
|
+
axes_range : float or None
|
|
101
|
+
Axis range, auto if None.
|
|
102
|
+
marker_scaling : float
|
|
103
|
+
Marker size scale factor.
|
|
104
|
+
grayed_out_elements : list or None
|
|
105
|
+
List of telescope names to plot as gray circles.
|
|
106
|
+
highlighted_elements : list or None
|
|
107
|
+
List of telescope names to plot with red circles around them.
|
|
108
|
+
|
|
69
109
|
Returns
|
|
70
110
|
-------
|
|
71
111
|
patches : list
|
|
72
112
|
List of telescope patches.
|
|
73
113
|
axes_range : float
|
|
74
114
|
Calculated or input axis range.
|
|
115
|
+
highlighted_patches : list
|
|
116
|
+
List of highlighted telescope patches.
|
|
75
117
|
"""
|
|
76
118
|
pos_x, pos_y = get_positions(telescopes)
|
|
77
119
|
telescopes["pos_x_rotated"] = Column(pos_x)
|
|
78
120
|
telescopes["pos_y_rotated"] = Column(pos_y)
|
|
79
121
|
|
|
80
|
-
patches, radii = create_patches(
|
|
122
|
+
patches, radii, highlighted_patches = create_patches(
|
|
123
|
+
telescopes, marker_scaling, show_tel_label, ax, grayed_out_elements, highlighted_elements
|
|
124
|
+
)
|
|
81
125
|
|
|
82
126
|
if axes_range:
|
|
83
|
-
return patches, axes_range
|
|
127
|
+
return patches, axes_range, highlighted_patches
|
|
84
128
|
|
|
85
129
|
r = max(radii).value
|
|
86
130
|
max_x = max(abs(pos_x.min().value), abs(pos_x.max().value)) + r
|
|
87
131
|
max_y = max(abs(pos_y.min().value), abs(pos_y.max().value)) + r
|
|
88
132
|
updated_axes_range = max(max_x, max_y) * 1.1
|
|
89
133
|
|
|
90
|
-
return patches, updated_axes_range
|
|
134
|
+
return patches, updated_axes_range, highlighted_patches
|
|
91
135
|
|
|
92
136
|
|
|
93
137
|
@u.quantity_input(x=u.m, y=u.m, radius=u.m)
|
|
94
|
-
def get_telescope_patch(name, x, y, radius):
|
|
138
|
+
def get_telescope_patch(name, x, y, radius, is_grayed_out=False):
|
|
95
139
|
"""
|
|
96
140
|
Create patch for a telescope.
|
|
97
141
|
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
name : str
|
|
145
|
+
Telescope name.
|
|
146
|
+
x : Quantity
|
|
147
|
+
X position.
|
|
148
|
+
y : Quantity
|
|
149
|
+
Y position.
|
|
150
|
+
radius : Quantity
|
|
151
|
+
Telescope radius.
|
|
152
|
+
is_grayed_out : bool
|
|
153
|
+
Whether to plot telescope in gray.
|
|
154
|
+
|
|
98
155
|
Returns
|
|
99
156
|
-------
|
|
100
157
|
patch : Patch
|
|
@@ -103,20 +160,23 @@ def get_telescope_patch(name, x, y, radius):
|
|
|
103
160
|
tel_type = names.get_array_element_type_from_name(name)
|
|
104
161
|
x, y, r = x.to(u.m), y.to(u.m), radius.to(u.m)
|
|
105
162
|
|
|
163
|
+
color = "gray" if is_grayed_out else leg_h.get_telescope_config(tel_type)["color"]
|
|
164
|
+
|
|
106
165
|
if tel_type == "SCTS":
|
|
107
166
|
return mpatches.Rectangle(
|
|
108
167
|
((x - r / 2).value, (y - r / 2).value),
|
|
109
168
|
width=r.value,
|
|
110
169
|
height=r.value,
|
|
111
|
-
fill=
|
|
112
|
-
color=
|
|
170
|
+
fill=is_grayed_out,
|
|
171
|
+
color=color,
|
|
113
172
|
)
|
|
114
173
|
|
|
115
174
|
return mpatches.Circle(
|
|
116
175
|
(x.value, y.value),
|
|
117
176
|
radius=r.value,
|
|
118
|
-
fill=tel_type.startswith("MST"),
|
|
119
|
-
|
|
177
|
+
fill=is_grayed_out or tel_type.startswith("MST"),
|
|
178
|
+
alpha=0.5 if is_grayed_out else 1.0,
|
|
179
|
+
color=color,
|
|
120
180
|
)
|
|
121
181
|
|
|
122
182
|
|
|
@@ -143,35 +203,71 @@ def get_positions(telescopes):
|
|
|
143
203
|
return transf.rotate(x, y, locale_rotate_angle) if locale_rotate_angle != 0 else (x, y)
|
|
144
204
|
|
|
145
205
|
|
|
146
|
-
def create_patches(
|
|
206
|
+
def create_patches(
|
|
207
|
+
telescopes, scale, show_label, ax, grayed_out_elements=None, highlighted_elements=None
|
|
208
|
+
):
|
|
147
209
|
"""
|
|
148
210
|
Create telescope patches and labels.
|
|
149
211
|
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
telescopes : Table
|
|
215
|
+
Telescope data table.
|
|
216
|
+
scale : float
|
|
217
|
+
Marker size scale factor.
|
|
218
|
+
show_label : bool
|
|
219
|
+
Show telescope labels.
|
|
220
|
+
ax : Axes
|
|
221
|
+
Matplotlib axes object.
|
|
222
|
+
grayed_out_elements : list or None
|
|
223
|
+
List of telescope names to plot as gray circles.
|
|
224
|
+
highlighted_elements : list or None
|
|
225
|
+
List of telescope names to plot with red circles around them.
|
|
226
|
+
|
|
150
227
|
Returns
|
|
151
228
|
-------
|
|
152
229
|
patches : list
|
|
153
230
|
Shape patches.
|
|
154
231
|
radii : list
|
|
155
232
|
Telescope radii.
|
|
233
|
+
highlighted_patches : list
|
|
234
|
+
List of highlighted telescope patches.
|
|
156
235
|
"""
|
|
157
|
-
patches, radii = [], []
|
|
236
|
+
patches, radii, highlighted_patches = [], [], []
|
|
158
237
|
fontsize, scale_factor = (4, 2) if len(telescopes) > 30 else (8, 1)
|
|
159
238
|
|
|
239
|
+
grayed_out_set = set(grayed_out_elements) if grayed_out_elements else set()
|
|
240
|
+
highlighted_set = set(highlighted_elements) if highlighted_elements else set()
|
|
241
|
+
|
|
160
242
|
for tel in telescopes:
|
|
161
243
|
name = get_telescope_name(tel)
|
|
162
244
|
radius = get_sphere_radius(tel)
|
|
163
245
|
radii.append(radius)
|
|
164
246
|
tel_type = names.get_array_element_type_from_name(name)
|
|
165
247
|
|
|
248
|
+
is_grayed_out = name in grayed_out_set
|
|
249
|
+
is_highlighted = name in highlighted_set
|
|
250
|
+
|
|
166
251
|
patches.append(
|
|
167
252
|
get_telescope_patch(
|
|
168
253
|
tel_type,
|
|
169
254
|
tel["pos_x_rotated"],
|
|
170
255
|
tel["pos_y_rotated"],
|
|
171
256
|
scale_factor * radius * scale,
|
|
257
|
+
is_grayed_out=is_grayed_out,
|
|
172
258
|
)
|
|
173
259
|
)
|
|
174
260
|
|
|
261
|
+
if is_highlighted:
|
|
262
|
+
highlight_patch = mpatches.Circle(
|
|
263
|
+
(tel["pos_x_rotated"].value, tel["pos_y_rotated"].value),
|
|
264
|
+
radius=(scale_factor * radius * scale * 4).value,
|
|
265
|
+
fill=False,
|
|
266
|
+
color="red",
|
|
267
|
+
linewidth=1,
|
|
268
|
+
)
|
|
269
|
+
highlighted_patches.append(highlight_patch)
|
|
270
|
+
|
|
175
271
|
if show_label:
|
|
176
272
|
ax.text(
|
|
177
273
|
tel["pos_x_rotated"].value,
|
|
@@ -182,7 +278,7 @@ def create_patches(telescopes, scale, show_label, ax):
|
|
|
182
278
|
fontsize=fontsize,
|
|
183
279
|
)
|
|
184
280
|
|
|
185
|
-
return patches, radii
|
|
281
|
+
return patches, radii, highlighted_patches
|
|
186
282
|
|
|
187
283
|
|
|
188
284
|
def get_telescope_name(tel):
|
|
@@ -213,10 +309,16 @@ def get_sphere_radius(tel):
|
|
|
213
309
|
return tel["sphere_radius"] if "sphere_radius" in tel.colnames else 10.0 * u.m
|
|
214
310
|
|
|
215
311
|
|
|
216
|
-
def update_legend(ax, telescopes):
|
|
312
|
+
def update_legend(ax, telescopes, grayed_out_elements=None, legend_location="best"):
|
|
217
313
|
"""Add legend for telescope types and counts."""
|
|
218
|
-
|
|
219
|
-
|
|
314
|
+
grayed_out_set = set(grayed_out_elements) if grayed_out_elements else set()
|
|
315
|
+
|
|
316
|
+
types = []
|
|
317
|
+
for tel in telescopes:
|
|
318
|
+
tel_name = get_telescope_name(tel)
|
|
319
|
+
if tel_name not in grayed_out_set:
|
|
320
|
+
types.append(names.get_array_element_type_from_name(tel_name))
|
|
321
|
+
|
|
220
322
|
counts = Counter(types)
|
|
221
323
|
|
|
222
324
|
objs, labels = [], []
|
|
@@ -239,12 +341,16 @@ def update_legend(ax, telescopes):
|
|
|
239
341
|
|
|
240
342
|
handler_map[telescope_type] = BaseLegendHandlerWrapper(telescope_type)
|
|
241
343
|
|
|
242
|
-
ax.legend(objs, labels, handler_map=handler_map, prop={"size": 11}, loc=
|
|
344
|
+
ax.legend(objs, labels, handler_map=handler_map, prop={"size": 11}, loc=legend_location)
|
|
243
345
|
|
|
244
346
|
|
|
245
|
-
def finalize_plot(ax, patches, x_title, y_title, axes_range):
|
|
347
|
+
def finalize_plot(ax, patches, x_title, y_title, axes_range, highlighted_patches=None):
|
|
246
348
|
"""Finalize plot appearance and limits."""
|
|
247
349
|
ax.add_collection(PatchCollection(patches, match_original=True))
|
|
350
|
+
|
|
351
|
+
if highlighted_patches:
|
|
352
|
+
ax.add_collection(PatchCollection(highlighted_patches, match_original=True))
|
|
353
|
+
|
|
248
354
|
ax.set(xlabel=x_title, ylabel=y_title)
|
|
249
355
|
ax.tick_params(labelsize=8)
|
|
250
356
|
ax.axis("square")
|
|
@@ -16,17 +16,6 @@ from simtools.data_model.metadata_collector import MetadataCollector
|
|
|
16
16
|
from simtools.visualization.plot_corsika_histograms import save_figs_to_pdf
|
|
17
17
|
from simtools.visualization.visualize import save_figure
|
|
18
18
|
|
|
19
|
-
__all__ = [
|
|
20
|
-
"generate_and_save_plots",
|
|
21
|
-
"plot_simtel_event_image",
|
|
22
|
-
"plot_simtel_integrated_pedestal_image",
|
|
23
|
-
"plot_simtel_integrated_signal_image",
|
|
24
|
-
"plot_simtel_peak_timing",
|
|
25
|
-
"plot_simtel_step_traces",
|
|
26
|
-
"plot_simtel_time_traces",
|
|
27
|
-
"plot_simtel_waveform_matrix",
|
|
28
|
-
]
|
|
29
|
-
|
|
30
19
|
_logger = logging.getLogger(__name__)
|
|
31
20
|
|
|
32
21
|
# Reusable literal constants (duplicated from visualize to avoid circular deps)
|
|
@@ -12,18 +12,6 @@ from astropy.table import QTable
|
|
|
12
12
|
from cycler import cycler
|
|
13
13
|
from matplotlib import gridspec
|
|
14
14
|
|
|
15
|
-
__all__ = [
|
|
16
|
-
"get_colors",
|
|
17
|
-
"get_lines",
|
|
18
|
-
"get_markers",
|
|
19
|
-
"plot_1d",
|
|
20
|
-
"plot_hist_2d",
|
|
21
|
-
"plot_table",
|
|
22
|
-
"save_figure",
|
|
23
|
-
"set_style",
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
|
|
27
15
|
COLORS = {}
|
|
28
16
|
COLORS["classic"] = [
|
|
29
17
|
"#ba2c54",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|