gammasimtools 0.5.1__py3-none-any.whl → 0.6.1__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.5.1.dist-info → gammasimtools-0.6.1.dist-info}/METADATA +80 -28
- gammasimtools-0.6.1.dist-info/RECORD +91 -0
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/WHEEL +1 -1
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/entry_points.txt +4 -2
- simtools/_version.py +14 -2
- simtools/applications/add_file_to_db.py +2 -1
- simtools/applications/compare_cumulative_psf.py +10 -15
- simtools/applications/db_development_tools/add_new_parameter_to_db.py +12 -6
- simtools/applications/derive_mirror_rnda.py +95 -71
- simtools/applications/generate_corsika_histograms.py +216 -131
- simtools/applications/generate_default_metadata.py +110 -0
- simtools/applications/generate_simtel_array_histograms.py +192 -0
- simtools/applications/get_file_from_db.py +1 -1
- simtools/applications/get_parameter.py +3 -3
- simtools/applications/make_regular_arrays.py +89 -93
- simtools/applications/{plot_layout_array.py → plot_array_layout.py} +15 -14
- simtools/applications/print_array_elements.py +81 -34
- simtools/applications/produce_array_config.py +2 -2
- simtools/applications/production.py +39 -5
- simtools/applications/sim_showers_for_trigger_rates.py +26 -30
- simtools/applications/simulate_prod.py +49 -107
- simtools/applications/submit_data_from_external.py +8 -10
- simtools/applications/tune_psf.py +16 -18
- simtools/applications/validate_camera_efficiency.py +63 -9
- simtools/applications/validate_camera_fov.py +9 -13
- simtools/applications/validate_file_using_schema.py +127 -0
- simtools/applications/validate_optics.py +13 -15
- simtools/camera_efficiency.py +73 -80
- simtools/configuration/commandline_parser.py +52 -22
- simtools/configuration/configurator.py +98 -33
- simtools/constants.py +9 -0
- simtools/corsika/corsika_config.py +28 -22
- simtools/corsika/corsika_default_config.py +282 -0
- simtools/corsika/corsika_histograms.py +328 -282
- simtools/corsika/corsika_histograms_visualize.py +162 -163
- simtools/corsika/corsika_runner.py +8 -4
- simtools/corsika_simtel/corsika_simtel_runner.py +18 -23
- simtools/data_model/data_reader.py +129 -0
- simtools/data_model/metadata_collector.py +346 -118
- simtools/data_model/metadata_model.py +123 -218
- simtools/data_model/model_data_writer.py +79 -22
- simtools/data_model/validate_data.py +96 -46
- simtools/db_handler.py +67 -42
- simtools/io_operations/__init__.py +0 -0
- simtools/io_operations/hdf5_handler.py +112 -0
- simtools/{io_handler.py → io_operations/io_handler.py} +51 -22
- simtools/job_execution/job_manager.py +1 -1
- simtools/layout/{layout_array.py → array_layout.py} +168 -199
- simtools/layout/geo_coordinates.py +196 -0
- simtools/layout/telescope_position.py +12 -12
- simtools/model/array_model.py +16 -14
- simtools/model/camera.py +5 -8
- simtools/model/mirrors.py +136 -73
- simtools/model/model_utils.py +1 -69
- simtools/model/telescope_model.py +32 -25
- simtools/psf_analysis.py +26 -19
- simtools/ray_tracing.py +54 -26
- simtools/schemas/data.metaschema.yml +400 -0
- simtools/schemas/metadata.metaschema.yml +566 -0
- simtools/simtel/simtel_config_writer.py +14 -5
- simtools/simtel/simtel_histograms.py +266 -83
- simtools/simtel/simtel_runner.py +8 -7
- simtools/simtel/simtel_runner_array.py +7 -8
- simtools/simtel/simtel_runner_camera_efficiency.py +48 -2
- simtools/simtel/simtel_runner_ray_tracing.py +61 -25
- simtools/simulator.py +43 -50
- simtools/utils/general.py +232 -286
- simtools/utils/geometry.py +163 -0
- simtools/utils/names.py +294 -142
- simtools/visualization/legend_handlers.py +115 -9
- simtools/visualization/visualize.py +13 -13
- gammasimtools-0.5.1.dist-info/RECORD +0 -83
- simtools/applications/plot_simtel_histograms.py +0 -120
- simtools/applications/validate_schema_files.py +0 -135
- simtools/corsika/corsika_output_visualize.py +0 -345
- simtools/data_model/validate_schema.py +0 -285
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/LICENSE +0 -0
- {gammasimtools-0.5.1.dist-info → gammasimtools-0.6.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A collection of functions related to geometrical transformations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
import astropy.units as u
|
|
8
|
+
import numpy as np
|
|
9
|
+
from astropy.coordinates.errors import UnitsError
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"convert_2d_to_radial_distr",
|
|
13
|
+
"rotate",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
_logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def convert_2d_to_radial_distr(hist_2d, xaxis, yaxis, bins=50, max_dist=1000):
|
|
20
|
+
"""
|
|
21
|
+
Convert a 2d histogram of positions, e.g. photon positions on the ground, to a 1D distribution.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
hist_2d: numpy.ndarray
|
|
26
|
+
The histogram counts.
|
|
27
|
+
xaxis: numpy.array
|
|
28
|
+
The values of the x axis (histogram bin edges) on the ground.
|
|
29
|
+
yaxis: numpy.array
|
|
30
|
+
The values of the y axis (histogram bin edges) on the ground.
|
|
31
|
+
bins: float
|
|
32
|
+
Number of bins in distance.
|
|
33
|
+
max_dist: float
|
|
34
|
+
Maximum distance to consider in the 1D histogram, usually in meters.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
np.array
|
|
39
|
+
The values of the 1D histogram with size = int(max_dist/bin_size).
|
|
40
|
+
np.array
|
|
41
|
+
The bin edges of the 1D histogram with size = int(max_dist/bin_size) + 1.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
# Check if the histogram will make sense
|
|
46
|
+
bins_step = 2 * max_dist / bins # in the 2d array, the positive and negative direction count.
|
|
47
|
+
for axis in [xaxis, yaxis]:
|
|
48
|
+
if (bins_step < np.diff(axis)).any():
|
|
49
|
+
msg = (
|
|
50
|
+
f"The histogram with number of bins {bins} and maximum distance of {max_dist} "
|
|
51
|
+
f"resulted in a bin size smaller than the original array. Please adjust those "
|
|
52
|
+
f"parameters to increase the bin size and avoid nan in the histogram values."
|
|
53
|
+
)
|
|
54
|
+
_logger.warning(msg)
|
|
55
|
+
break
|
|
56
|
+
|
|
57
|
+
grid_2d_x, grid_2d_y = np.meshgrid(xaxis[:-1], yaxis[:-1]) # [:-1], since xaxis and yaxis are
|
|
58
|
+
# the hist bin_edges (n + 1).
|
|
59
|
+
# radial_distance_map maps the distance to the center from each element in a square matrix.
|
|
60
|
+
radial_distance_map = np.sqrt(grid_2d_x**2 + grid_2d_y**2)
|
|
61
|
+
# The sorting and unravel_index give us the two indices for the position of the sorted element
|
|
62
|
+
# in the original 2d matrix
|
|
63
|
+
sorted_indices = np.unravel_index(
|
|
64
|
+
np.argsort(radial_distance_map, axis=None), np.shape(radial_distance_map)
|
|
65
|
+
)
|
|
66
|
+
x_indices_sorted, y_indices_sorted = sorted_indices[0], sorted_indices[1]
|
|
67
|
+
|
|
68
|
+
# We construct a 1D array with the histogram counts sorted according to the distance to the
|
|
69
|
+
# center.
|
|
70
|
+
hist_sorted = np.array(
|
|
71
|
+
[hist_2d[i_x, i_y] for i_x, i_y in zip(x_indices_sorted, y_indices_sorted)]
|
|
72
|
+
)
|
|
73
|
+
distance_sorted = np.sort(radial_distance_map, axis=None)
|
|
74
|
+
|
|
75
|
+
# For larger distances, we have more elements in a slice 'dr' in radius, hence, we need to
|
|
76
|
+
# acount for it using weights below.
|
|
77
|
+
|
|
78
|
+
weights, radial_bin_edges = np.histogram(distance_sorted, bins=bins, range=(0, max_dist))
|
|
79
|
+
histogram_1d = np.empty_like(weights, dtype=float)
|
|
80
|
+
|
|
81
|
+
for i_radial, _ in enumerate(radial_bin_edges[:-1]):
|
|
82
|
+
# Here we sum all the events within a radial interval 'dr' and then divide by the number of
|
|
83
|
+
# bins that fit this interval.
|
|
84
|
+
indices_to_sum = (distance_sorted >= radial_bin_edges[i_radial]) * (
|
|
85
|
+
distance_sorted < radial_bin_edges[i_radial + 1]
|
|
86
|
+
)
|
|
87
|
+
if weights[i_radial] != 0:
|
|
88
|
+
histogram_1d[i_radial] = np.sum(hist_sorted[indices_to_sum]) / weights[i_radial]
|
|
89
|
+
else:
|
|
90
|
+
histogram_1d[i_radial] = 0
|
|
91
|
+
return histogram_1d, radial_bin_edges
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@u.quantity_input(rotation_angle_phi=u.rad, rotation_angle_theta=u.rad)
|
|
95
|
+
def rotate(x, y, rotation_around_z_axis, rotation_around_y_axis=0):
|
|
96
|
+
"""
|
|
97
|
+
Transform the x and y coordinates of the telescopes according to two rotations:
|
|
98
|
+
`rotation_angle_around_z_axis` gives the rotation on the observation plane (x, y) and
|
|
99
|
+
`rotation_angle_around_y_axis` allows to rotate the observation plane in space.
|
|
100
|
+
The function returns the rotated x and y values in the same unit given.
|
|
101
|
+
The direction of rotation of the elements in the plane is counterclockwise, i.e.,
|
|
102
|
+
the rotation of the coordinate system is clockwise.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
x: numpy.array or list
|
|
107
|
+
x positions of the entries (e.g. telescopes), usually in meters.
|
|
108
|
+
y: numpy.array or list
|
|
109
|
+
y positions of the entries (e.g. telescopes), usually in meters.
|
|
110
|
+
rotation_angle_around_z_axis: astropy.units.rad
|
|
111
|
+
Angle to rotate the array in the observation plane (around z axis) in radians.
|
|
112
|
+
rotation_angle_around_y_axis: astropy.units.rad
|
|
113
|
+
Angle to rotate the observation plane around the y axis in radians.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
2-tuple of list
|
|
118
|
+
x and y positions of the rotated entry (e.g. telescopes) positions.
|
|
119
|
+
|
|
120
|
+
Raises
|
|
121
|
+
------
|
|
122
|
+
TypeError:
|
|
123
|
+
If type of x and y parameters are not valid.
|
|
124
|
+
RuntimeError:
|
|
125
|
+
If the length of x and y are different.
|
|
126
|
+
UnitsError:
|
|
127
|
+
If the unit of x and y are different.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
allowed_types = (list, np.ndarray, u.Quantity, float, int)
|
|
131
|
+
if not all(isinstance(variable, (allowed_types)) for variable in [x, y]):
|
|
132
|
+
raise TypeError("x and y types are not valid! Cannot perform transformation.")
|
|
133
|
+
|
|
134
|
+
if not isinstance(x, (list, np.ndarray)):
|
|
135
|
+
x = [x]
|
|
136
|
+
if not isinstance(y, (list, np.ndarray)):
|
|
137
|
+
y = [y]
|
|
138
|
+
|
|
139
|
+
if (
|
|
140
|
+
np.sum(
|
|
141
|
+
np.array([isinstance(x, type_now) for type_now in allowed_types[:-2]])
|
|
142
|
+
* np.array([isinstance(y, type_now) for type_now in allowed_types[:-2]])
|
|
143
|
+
)
|
|
144
|
+
== 0
|
|
145
|
+
):
|
|
146
|
+
raise TypeError("x and y are not from the same type! Cannot perform transformation.")
|
|
147
|
+
|
|
148
|
+
if len(x) != len(y):
|
|
149
|
+
raise RuntimeError(
|
|
150
|
+
"Cannot perform coordinate transformation when x and y have different lengths."
|
|
151
|
+
)
|
|
152
|
+
if all(isinstance(variable, (u.Quantity)) for variable in [x, y]):
|
|
153
|
+
if not isinstance(x[0].unit, type(y[0].unit)):
|
|
154
|
+
raise UnitsError(
|
|
155
|
+
"Cannot perform coordinate transformation when x and y have different units."
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
x_trans = np.cos(rotation_around_y_axis) * (
|
|
159
|
+
x * np.cos(rotation_around_z_axis) - y * np.sin(rotation_around_z_axis)
|
|
160
|
+
)
|
|
161
|
+
y_trans = x * np.sin(rotation_around_z_axis) + y * np.cos(rotation_around_z_axis)
|
|
162
|
+
|
|
163
|
+
return x_trans, y_trans
|