Source code for physped.core.lattice_selection

"""This module contains functions to select a single point or a range of
values in the configuration file.

The only purpose is to let the user make a selection along the discretization
lattice.
"""

import logging

import numpy as np
from omegaconf import DictConfig, OmegaConf

from physped.core.digitizers import digitize_coordinates_to_lattice
from physped.utils.functions import periodic_angular_conditions

log = logging.getLogger(__name__)


# ! The functions below are used to select a single point in the config file


[docs] def validate_value_within_lattice( selected_value: float, bins: dict, dimension: str ) -> None: """Check if the selected value is outside the lattice. Args: selected_value: The selected value in one of the dimensions. bins: The bins of the lattice in all the dimensions. dimension: The dimension of the given value. Raises: ValueError: If the selected value is outside the lattice. """ left_bound = bins[dimension][0] right_bound = bins[dimension][-1] outside_lattice = (selected_value < left_bound) or ( selected_value > right_bound ) if outside_lattice: raise ValueError( f"Selected {dimension} value ({selected_value}) is outside the " f"lattice. Please select a value within the range " f"[{left_bound},{right_bound}]." )
[docs] def validate_point_within_lattice( selected_point: DictConfig, grid_bins: dict ) -> None: """Validate the selection. Args: selected_point: The selected point. grid_bins: The bins of the lattice in all the dimensions. """ for dimension, value in selected_point.items(): validate_value_within_lattice(value, grid_bins, dimension) log.info("The selected point is located within the grid.")
[docs] def get_boundaries_that_enclose_the_selected_bin( bin_index: int, bins: np.ndarray ) -> dict: left_bound = bins[bin_index] right_bound = bins[bin_index + 1] return [left_bound, right_bound]
[docs] def evaluate_selection_point(config: DictConfig) -> DictConfig: selection = config.params.selection selected_point = selection.point grid_bins = config.params.grid.bins selected_point.theta_periodic = periodic_angular_conditions( selected_point.theta, grid_bins["theta"] ) validate_point_within_lattice(selected_point, grid_bins) selected_point.x_index = digitize_coordinates_to_lattice( selected_point.x, grid_bins["x"] ) selected_point.y_index = digitize_coordinates_to_lattice( selected_point.y, grid_bins["y"] ) selected_point.r_index = digitize_coordinates_to_lattice( selected_point.r, grid_bins["r"] ) selected_point.theta_index = digitize_coordinates_to_lattice( selected_point.theta_periodic, grid_bins["theta"] ) selected_point.k_index = digitize_coordinates_to_lattice( selected_point.k, grid_bins["k"] ) return config
# ! The functions below are used to select a range of values in the config file
[docs] def is_selected_range_within_grid( selected_range: OmegaConf, grid_bins: dict ) -> None: for dimension in ["x", "y", "r", "theta", "k"]: for value in selected_range[dimension]: validate_value_within_lattice(value, grid_bins, dimension) log.info("The selected range is located within the grid.")
[docs] def is_range_decreasing(selected_range: OmegaConf): """ Check if the range is increasing. Raises: ValueError: If the range is decreasing Args: selected_range (OmegaConf): The selection. """ range_decreasing = selected_range[0] > selected_range[1] if range_decreasing: raise ValueError( "The selected range is invalid. The range must be increasing." )
[docs] def is_selected_range_valid(selected_range: OmegaConf) -> None: """ Validate the selection. Args: selection: The selection. """ for dimension in ["x", "y", "r", "theta", "k"]: is_range_decreasing(selected_range[dimension]) log.info("The selected range is valid.")
[docs] def get_boundaries_that_enclose_the_selected_range( selected_range: OmegaConf, bins: dict ) -> dict: left_bound = bins[selected_range[0]] right_bound = bins[selected_range[1] + 1] return [float(left_bound), float(right_bound)]
[docs] def evaluate_selection_range(config: DictConfig) -> DictConfig: selected_range = config.params.selection.range grid_bins = config.params.grid.bins selected_range.theta_periodic = periodic_angular_conditions( selected_range.theta, grid_bins["theta"] ).tolist() is_selected_range_valid(selected_range) is_selected_range_within_grid(selected_range, grid_bins) selected_range.x_indices = digitize_coordinates_to_lattice( selected_range.x, grid_bins["x"] ).tolist() selected_range.y_indices = digitize_coordinates_to_lattice( selected_range.y, grid_bins["y"] ).tolist() selected_range.r_indices = digitize_coordinates_to_lattice( selected_range.r, grid_bins["r"] ).tolist() selected_range.theta_indices = digitize_coordinates_to_lattice( selected_range.theta_periodic, grid_bins["theta"] ).tolist() selected_range.k_indices = digitize_coordinates_to_lattice( selected_range.k, grid_bins["k"] ).tolist() selected_range.x_bounds = get_boundaries_that_enclose_the_selected_range( selected_range.x_indices, grid_bins["x"] ) selected_range.y_bounds = get_boundaries_that_enclose_the_selected_range( selected_range.y_indices, grid_bins["y"] ) selected_range.r_bounds = get_boundaries_that_enclose_the_selected_range( selected_range.r_indices, grid_bins["r"] ) selected_range.theta_bounds = ( get_boundaries_that_enclose_the_selected_range( selected_range.theta_indices, grid_bins["theta"] ) ) selected_range.k_bounds = get_boundaries_that_enclose_the_selected_range( selected_range.k_indices, grid_bins["k"] ) log.debug("x bins: %s", [np.round(x, 2) for x in grid_bins["x"]]) log.debug( "range: %s ---> %s ---> %s", selected_range.x, selected_range.x_indices, [np.round(x, 2) for x in selected_range.x_bounds], ) log.debug("y bins: %s", [np.round(x, 2) for x in grid_bins["y"]]) log.debug( "range: %s ---> %s ---> %s", selected_range.y, selected_range.y_indices, [np.round(x, 2) for x in selected_range.y_bounds], ) log.debug("r bins: %s", [np.round(x, 2) for x in grid_bins["r"]]) log.debug( "range: %s ---> %s ---> %s", selected_range.r, selected_range.r_indices, [np.round(x, 2) for x in selected_range.r_bounds], ) log.debug("theta bins: %s", [np.round(x, 2) for x in grid_bins["theta"]]) log.debug( "range: %s ---> %s ---> %s", selected_range.theta, selected_range.theta_indices, [np.round(x, 2) for x in selected_range.theta_bounds], ) log.debug("k bins: %s", [np.round(x, 2) for x in grid_bins["k"]]) log.debug( "range: %s ---> %s ---> %s", selected_range.k, selected_range.k_indices, [np.round(x, 2) for x in selected_range.k_bounds], ) return config