Coverage for physped/core/lattice_selection.py: 0%
76 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-01 09:28 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-01 09:28 +0000
1"""This module contains functions to select a single point or a range of
2values in the configuration file.
4The only purpose is to let the user make a selection along the discretization
5lattice.
6"""
8import logging
10import numpy as np
11from omegaconf import DictConfig, OmegaConf
13from physped.core.digitizers import digitize_coordinates_to_lattice
14from physped.utils.functions import periodic_angular_conditions
16log = logging.getLogger(__name__)
19# ! The functions below are used to select a single point in the config file
22def validate_value_within_lattice(
23 selected_value: float, bins: dict, dimension: str
24) -> None:
25 """Check if the selected value is outside the lattice.
27 Args:
28 selected_value: The selected value in one of the dimensions.
29 bins: The bins of the lattice in all the dimensions.
30 dimension: The dimension of the given value.
32 Raises:
33 ValueError: If the selected value is outside the lattice.
34 """
35 left_bound = bins[dimension][0]
36 right_bound = bins[dimension][-1]
37 outside_lattice = (selected_value < left_bound) or (
38 selected_value > right_bound
39 )
40 if outside_lattice:
41 raise ValueError(
42 f"Selected {dimension} value ({selected_value}) is outside the "
43 f"lattice. Please select a value within the range "
44 f"[{left_bound},{right_bound}]."
45 )
48def validate_point_within_lattice(
49 selected_point: DictConfig, grid_bins: dict
50) -> None:
51 """Validate the selection.
53 Args:
54 selected_point: The selected point.
55 grid_bins: The bins of the lattice in all the dimensions.
56 """
57 for dimension, value in selected_point.items():
58 validate_value_within_lattice(value, grid_bins, dimension)
59 log.info("The selected point is located within the grid.")
62def get_boundaries_that_enclose_the_selected_bin(
63 bin_index: int, bins: np.ndarray
64) -> dict:
65 left_bound = bins[bin_index]
66 right_bound = bins[bin_index + 1]
67 return [left_bound, right_bound]
70def evaluate_selection_point(config: DictConfig) -> DictConfig:
71 selection = config.params.selection
72 selected_point = selection.point
73 grid_bins = config.params.grid.bins
75 selected_point.theta_periodic = periodic_angular_conditions(
76 selected_point.theta, grid_bins["theta"]
77 )
78 validate_point_within_lattice(selected_point, grid_bins)
79 selected_point.x_index = digitize_coordinates_to_lattice(
80 selected_point.x, grid_bins["x"]
81 )
82 selected_point.y_index = digitize_coordinates_to_lattice(
83 selected_point.y, grid_bins["y"]
84 )
85 selected_point.r_index = digitize_coordinates_to_lattice(
86 selected_point.r, grid_bins["r"]
87 )
88 selected_point.theta_index = digitize_coordinates_to_lattice(
89 selected_point.theta_periodic, grid_bins["theta"]
90 )
91 selected_point.k_index = digitize_coordinates_to_lattice(
92 selected_point.k, grid_bins["k"]
93 )
94 return config
97# ! The functions below are used to select a range of values in the config file
100def is_selected_range_within_grid(
101 selected_range: OmegaConf, grid_bins: dict
102) -> None:
103 for dimension in ["x", "y", "r", "theta", "k"]:
104 for value in selected_range[dimension]:
105 validate_value_within_lattice(value, grid_bins, dimension)
106 log.info("The selected range is located within the grid.")
109def is_range_decreasing(selected_range: OmegaConf):
110 """
111 Check if the range is increasing.
113 Raises:
114 ValueError: If the range is decreasing
116 Args:
117 selected_range (OmegaConf): The selection.
118 """
119 range_decreasing = selected_range[0] > selected_range[1]
120 if range_decreasing:
121 raise ValueError(
122 "The selected range is invalid. The range must be increasing."
123 )
126def is_selected_range_valid(selected_range: OmegaConf) -> None:
127 """
128 Validate the selection.
130 Args:
131 selection: The selection.
132 """
133 for dimension in ["x", "y", "r", "theta", "k"]:
134 is_range_decreasing(selected_range[dimension])
135 log.info("The selected range is valid.")
138def get_boundaries_that_enclose_the_selected_range(
139 selected_range: OmegaConf, bins: dict
140) -> dict:
141 left_bound = bins[selected_range[0]]
142 right_bound = bins[selected_range[1] + 1]
143 return [float(left_bound), float(right_bound)]
146def evaluate_selection_range(config: DictConfig) -> DictConfig:
147 selected_range = config.params.selection.range
148 grid_bins = config.params.grid.bins
149 selected_range.theta_periodic = periodic_angular_conditions(
150 selected_range.theta, grid_bins["theta"]
151 ).tolist()
153 is_selected_range_valid(selected_range)
154 is_selected_range_within_grid(selected_range, grid_bins)
155 selected_range.x_indices = digitize_coordinates_to_lattice(
156 selected_range.x, grid_bins["x"]
157 ).tolist()
158 selected_range.y_indices = digitize_coordinates_to_lattice(
159 selected_range.y, grid_bins["y"]
160 ).tolist()
161 selected_range.r_indices = digitize_coordinates_to_lattice(
162 selected_range.r, grid_bins["r"]
163 ).tolist()
164 selected_range.theta_indices = digitize_coordinates_to_lattice(
165 selected_range.theta_periodic, grid_bins["theta"]
166 ).tolist()
167 selected_range.k_indices = digitize_coordinates_to_lattice(
168 selected_range.k, grid_bins["k"]
169 ).tolist()
171 selected_range.x_bounds = get_boundaries_that_enclose_the_selected_range(
172 selected_range.x_indices, grid_bins["x"]
173 )
174 selected_range.y_bounds = get_boundaries_that_enclose_the_selected_range(
175 selected_range.y_indices, grid_bins["y"]
176 )
177 selected_range.r_bounds = get_boundaries_that_enclose_the_selected_range(
178 selected_range.r_indices, grid_bins["r"]
179 )
180 selected_range.theta_bounds = (
181 get_boundaries_that_enclose_the_selected_range(
182 selected_range.theta_indices, grid_bins["theta"]
183 )
184 )
185 selected_range.k_bounds = get_boundaries_that_enclose_the_selected_range(
186 selected_range.k_indices, grid_bins["k"]
187 )
189 log.debug("x bins: %s", [np.round(x, 2) for x in grid_bins["x"]])
190 log.debug(
191 "range: %s ---> %s ---> %s",
192 selected_range.x,
193 selected_range.x_indices,
194 [np.round(x, 2) for x in selected_range.x_bounds],
195 )
196 log.debug("y bins: %s", [np.round(x, 2) for x in grid_bins["y"]])
197 log.debug(
198 "range: %s ---> %s ---> %s",
199 selected_range.y,
200 selected_range.y_indices,
201 [np.round(x, 2) for x in selected_range.y_bounds],
202 )
203 log.debug("r bins: %s", [np.round(x, 2) for x in grid_bins["r"]])
204 log.debug(
205 "range: %s ---> %s ---> %s",
206 selected_range.r,
207 selected_range.r_indices,
208 [np.round(x, 2) for x in selected_range.r_bounds],
209 )
210 log.debug("theta bins: %s", [np.round(x, 2) for x in grid_bins["theta"]])
211 log.debug(
212 "range: %s ---> %s ---> %s",
213 selected_range.theta,
214 selected_range.theta_indices,
215 [np.round(x, 2) for x in selected_range.theta_bounds],
216 )
217 log.debug("k bins: %s", [np.round(x, 2) for x in grid_bins["k"]])
218 log.debug(
219 "range: %s ---> %s ---> %s",
220 selected_range.k,
221 selected_range.k_indices,
222 [np.round(x, 2) for x in selected_range.k_bounds],
223 )
224 return config