RIS Optimization Module

This module provides functionalities for ray-tracing based RIS optimization for coverage enhancement.

class RIS_Opt.RIS_GUI(master)[source]

Bases: object

analyze_and_visualize_ris_configurations(input_file, improvement_threshold)[source]

Analyzes RIS configurations and creates visualizations.

Input:
  • input_file (str): Path to JSON metric data.

  • improvement_threshold (float): Performance gain threshold for optimization.

Output:

results (dict): Full analysis results with visualizations.

brush_cov_map(coverage_map, zero_indices)[source]

Modifies a 3D coverage map by masking walls of the scene to zero for smoother visibility.

This method updates the path_gain tensor of the coverage map by applying a mask that sets the values of specified wall indices (zero_indices) to zero, effectively removing their influence on the coverage visualization.

Important: This function requires an additional method set_value() to be added in sionna/rt/coverage_map.py, which allows updating the coverage map values.

Required Method in sionna/rt/coverage_map.py:

def set_value(self, new_value):
    """
    Sets a new value for the coverage map.

    :Input:
        - new_value (tf.Tensor): A tensor of shape [num_tx, num_cells_y, num_cells_x]
        representing the new coverage map values.
    """
    if hasattr(self, '_value'):
        if new_value.shape != self._value.shape:
            raise ValueError(f"Shape mismatch. Expected shape {self._path_gain.shape}, but got {new_value.shape}")

    self._path_gain = tf.cast(new_value, self._rdtype)
Input:
  • coverage_map (object): The coverage map object containing the 3D tensor path_gain.

  • zero_indices (list[list[list[int]]]): A list of indices representing the wall positions to be masked.

check_los(tx_position, rx_position)[source]

Verifies Line-of-Sight (LoS) between two points in the scene.

Input:
  • tx_position (list[float]): Transmitter position [x, y, z].

  • rx_position (list[float]): Receiver position [x, y, z].

Output:

output (bool): True if an unobstructed path exists, False otherwise.

clear_values()[source]

Clears the entry fields for the frequency, minimum path gain threshold, transmitter position (x, y, and z) and coverage map cell size.

clustering_algo()[source]

Performs clustering to select target points from low-power cell coordinates.

This method applies K-means clustering to group low-power cell locations and select the specified number of target points. The selected points are then plotted on the binary poor coverage map.

Output:
  • The selected targets (list[list[float]]): Shows the selected target coordinates in the GUI.

  • Binary poor coverage map with target points marked (visualization): Displays the plot with the binary poor coverage map and selected target points.

compute_combined_coverage()[source]

Computes and visualizes the combined TX+RIS coverage map, along with performance metrics.

Workflow:

  1. Configures RIS based on GUI parameters (size/position/phase profile).

  2. Computes the combined coverage map.

  3. Generates coverage gain visualization.

  4. Updates CDF comparison plot.

  5. Calculates new coverage metrics.

Output:
  • Figure (matplotlib.figure.Figure): A series of figures showing the combined coverage map, RIS coverage gain, and binary poor coverage map, along with the corresponding performance metrics and coverage ratios.

  • Text updates (str): Updates the GUI info label with coverage ratio and average path gain of low-power cells in the combined coverage map.

  • CDF plot (matplotlib.figure.Figure): Updates and displays the CDF of the coverage gain with and without RIS.

compute_opt_par()[source]

Computes performance metrics (average path gain of low-power cells and coverage ratio) after placing the RIS for all RIS parameter combinations.

Workflow:

  • Iterates through the number of targets and RIS width intervals

  • Tests all valid RIS positions for each configuration

  • Stores results in JSON files with metrics:
    • Average path gain of low-power cells

    • Coverage ratio

compute_potential_RIS_positions()[source]

Computes potential RIS positions along walls that maintain Line-of-Sight (LoS) to all target points.

This method identifies candidate RIS positions by:

  1. Validating the number of target points from GUI input

  2. Checking manual/optimized target point selection

  3. Scanning predefined walls with a specified step size (0.4 m by default)

  4. Verifying LoS between candidate positions and all target points

Output:

Binary poor coverage map with target points and feasible RIS positions marked (visualization): A plot with the binary poor coverage map, selected target points, and feasible RIS positions marked.

compute_tx_coverage()[source]

Computes and visualizes the TX-only coverage map for the scene.

Output:
  • TX-only coverage map (visualization): Displays the coverage map without RIS.

  • Coverage ratio (float): Percentage of the area above the minimum path gain threshold.

  • Low-power cell analysis (float): Computes the average path gain of weak coverage areas.

  • Binary poor coverage map (visualization): Highlights regions with insufficient power.

configure_ris()[source]

Configures the RIS based on the selected phase profile approach.

cov_ratio_selection()[source]

Opens a file dialog for JSON coverage ratio file selection.

create_ris()[source]

Initializes the RIS with specified dimensions and position.

customize_axes(tensor, ax)[source]

Customizes the axes of a coverage map plot.

This method adjusts the tick labels of the x and y axes based on the coverage map’s cell size and the outer wall thickness. The tick labels are rounded to one decimal place for clarity.

Input:
  • tensor (tf.Tensor): A 2D tensor representing the coverage map.

  • ax (matplotlib.axes.Axes): The Matplotlib axes object to customize.

data_file_selection()[source]

Opens a file dialog for JSON performance metric file selection.

draw_binary_poor_coverage_map(cm_no_ris_tensor, avg_path_gain_low_power_cells, cov_ratio)[source]

Generates a binary poor coverage map highlighting low-power cells.

This method visualizes areas with poor coverage in red and acceptable coverage in blue. Walls (zero-power cells) are overlaid in white. The method also annotates the plot with the selected path gain threshold, the average path gain of low-power cells, and the coverage ratio.

Input:
  • cm_no_ris_tensor (tf.Tensor): A 2D tensor representing the coverage map path gain for each transmitter.

  • avg_path_gain_low_power_cells (float): The average path gain of low-power cells (in dB).

  • cov_ratio (float): The percentage of area covered above the minimum path gain threshold.

Output:

fig2 (matplotlib.figure.Figure): The generated figure.

export_phase_profile(ris_pp_values, filename)[source]

Exports a given RIS phase profile to a JSON file with a specified filename.

This function takes a TensorFlow tensor representing the RIS phase profile, converts it into a standard Python list format, and saves the data as a JSON file.

Input:
  • ris_pp_values (tf.Tensor): The RIS phase profile values to be exported.

  • filename (str): The name (or path) of the JSON file where the phase profile will be saved.

find_RIS_positions_on_wall(wall, step_size)[source]

Identifies valid RIS positions along a specified wall segment.

Input:
  • wall (dict): A dictionary defining wall properties with keys:
    • “fixed_coord” (str): Fixed coordinate axis (‘x’ or ‘y’)

    • “fixed_value” (float): Fixed coordinate value

    • “variable_coord” (str): Variable coordinate axis

    • “min” (float): Minimum position along the variable axis

    • “max” (float): Maximum position along the variable axis

  • step_size (float): Increment step for position scanning (meters).

Output:

potential_RIS_pos (list[list[float]]): A list of valid RIS positions in format [x, y, z], rounded to 1 decimal point.

find_best_configs_per_width(data)[source]

Identifies the top-performing configuration for each RIS width.

Input:

data (dict): Dictionary of configuration-performance pairs.

Output:

best_configs (dict[float, tuple(str, float)]): Best configuration per width with performance.

find_optimal_configuration(best_configs_per_width, improvement_threshold)[source]

Finds the optimal RIS configuration based on the improvement threshold criterion.

Input:
  • best_configs_per_width (dict): Pre-filtered best configurations, where keys represent the widths and values are tuples containing configurations and performance metrics.

  • improvement_threshold (float): Minimum dB improvement required to consider a configuration as optimal.

Output:
  • result (dict): A dictionary containing the optimal configuration, performance metric, and progression analysis.
    • optimal_configuration (dict): Contains optimal configuration details, including the number of target points, RIS width, and position.
      • number_of_target_points (int): The number of target points for the optimal configuration.

      • ris_width (float): The width of the RIS in the optimal configuration.

      • position (dict): The position of the RIS in 3D space with x, y, and z coordinates.

    • performance_metric (float): The performance metric of the optimal configuration.

    • progression_analysis (list): A list of dictionaries, each representing the progression of configurations with width, config, performance, and improvement (if applicable).

get_num_positions()[source]

Retrieves and validates the number of target points.

hsv_plot_phase_profile(overall_phase_profile)[source]

Visualizes the RIS phase profile using HSV color mapping.

Input:

overall_phase_profile (tf.Tensor): A 2D tensor of phase values in radians.

Output:

HSV plot (matplotlib.figure.Figure): A plot of the RIS phase profile with HSV color mapping.

load_scenario()[source]

Loads the simulation scene based on the selected scenario and initializes the scene parameters.

This method reads the currently selected scenario from the GUI (via self.scenario_var) and loads the corresponding scene using the load_scene function. For some scenarios, it also sets up wall indices (self.zero_indices) and defines potential RIS placement positions (self.RIS_search_positions).

manual_pp_config()[source]

Loads a manually provided phase profile from a JSON file and applies it to the RIS.

manual_pp_file_selection()[source]

Opens file dialog to select a manual phase profile JSON file.

parse_config(config_str)[source]

Converts a configuration string to structured data.

Input:

config_str (str): A string representation of a configuration tuple.

Output:

parsed_config (tuple(int, float, tuple(float, float, float))): Parsed configuration containing (num_targets, width, position).

perf_metr_RIS_pos_func()[source]

Plots the performance metric and coverage ratio as a function of RIS position for a specified width.

plot_RIS_positions(potential_RIS_pos)[source]

Visualizes feasible RIS positions on the binary coverage map.

Input:

potential_RIS_pos (list[list[float]]): List of candidate RIS positions.

Output:

visualization (matplotlib.figure.Figure): A plot with the binary poor coverage map, selected target points, and feasible RIS positions marked.

plot_selected_targets()[source]

Plots the binary poor coverage map with selected target points.

This method visualizes the binary poor coverage map and overlays the selected target points using distinct markers for easy identification.

Workflow:

  1. Calls draw_binary_poor_coverage_map() to generate the base map.

  2. Plots the selected target points with green (‘#08ff00’) ‘x’ markers.

  3. Displays the final plot.

Output:

Binary poor coverage map with target points marked (visualization): Displays the plot with the binary poor coverage map and selected target points.

preview_scenario()[source]

Previews the current scenario by rendering the scene with the transmitter and RIS (if present).

This method configures and displays the simulation setup based on the selected scenario. It reads input parameters from the GUI, sets up the transmitter at the specified position, and optionally adds a RIS if dimensions are provided. The scene is then rendered from one or more camera viewpoints.

Output:

Rendered figures (matplotlib.figure.Figure): Figures rendered from different predefined camera viewpoints.

reset_scene_after_RIS_computation()[source]

Restores the original scene configuration after RIS feasible position analysis.

Workflow:

  • Removes temporary transmitters/receivers

  • Re-adds main transmitter with original position

run_opt_algorithm()[source]

Executes optimization analysis using selected data file.

Workflow:

  1. Loads precomputed metric data

  2. Identifies optimal configuration

  3. Generates performance visualization

select_below_threshold(tensor, threshold_db)[source]

Selects coordinates and values from a 2D coverage map tensor that fall below a given minimum path gain threshold.

Input:
  • tensor (tf.Tensor): A 2D tensor representing the coverage map.

  • threshold_db (float): The minimum path gain threshold in dB to filter the tensor values.

Output:
  • coords_below_threshold (list[list[float]]): Transformed coordinates (in meters) where path gain values are below the threshold.

  • value_list (list[float]): The path gain values at those coordinates.

  • indices (np.ndarray): The indices of the selected values in the original tensor.

sensitivity_analysis()[source]

Performs sensitivity analysis on the RIS-assisted performance under phase error.

Based on user selection, analyzes gradient-based, distance-based, and/or manual entry approaches. Adds random uniform phase error within a specified delta range and measures the performance metric which is the average path gain of low-power cells across multiple realizations.

Plots the average of the performance metric versus phase error magnitude, including error bars for variability. Also compares with the no-RIS baseline performance.

set_preset_values()[source]

Sets preset parameter values for the GUI entries.

This method resets and assigns default values to the frequency, minimum path gain threshold, and coverage map cell size entry fields. Additionally, it sets the transmitter’s coordinates based on the currently selected scenario.

set_target_points()[source]

Determines target points manually or using K-means algorithm.

show_phase_profiles()[source]

Shows RIS phase profiles for each target point separately as well as the overall reflection coefficient phase profile.

Output:

figure (matplotlib.figure.Figure): The phase profiles of the RIS configuration for each target point, as well as the overall reflection coefficient’s phase profile.

toggle_amp_fluc_entries()[source]
toggle_manual_pp_entry(selected_option)[source]

Shows the manual phase profile file selection when ‘Manual entry’ is chosen.

toggle_target_point_input()[source]

Toggles the target point input method between optimized and manual entry.

Workflow:
  • If “optimized” is selected, the manual input fields are hidden.

  • If “manual” is selected:
    1. Reads the number of target points from the GUI.

    2. Clears any existing manual input fields.

    3. Dynamically creates input fields for each target point (x, y, z).

    4. Displays the input fields for user entry.

visualize_performance_vs_width(best_configs_per_width, optimal_width=None, no_ris_performance=None)[source]

Generates an annotated performance plot with configuration details, showing the relationship between RIS width and performance. The plot includes the number of target points (N) and the RIS position (x, y, z) for each configuration. It also highlights the optimal RIS configuration if provided.

Input:
  • best_configs_per_width (dict): A dictionary where each key is a RIS width and each value is a tuple containing the configuration string and the corresponding performance (dB).

  • optimal_width (float): The RIS width corresponding to the optimal configuration, which will be highlighted on the plot. Default is None.

  • no_ris_performance (float): The baseline performance without RIS, which will be plotted at width 0.

Output:

plot (matplotlib.figure.Figure): The function generates a plot showing RIS performance versus width, annotated with configuration details and optional optimal RIS configuration highlights.

RIS_Opt.calculate_cdf(tensor)[source]

Calculates the cumulative distribution function (CDF) of path gains in a tensor.

Input:
  • tensor (tf.Tensor): A 2D TensorFlow tensor representing a coverage map with path gain values.

Output:
  • sorted_values_db (np.ndarray): Sorted path gain values converted to dB.

  • cdf (np.ndarray): The cumulative distribution function values.

RIS_Opt.calculate_coverage_ratio(tensor, threshold_db)[source]

Calculates the coverage ratio of the scenario from a coverage map tensor based on a minimum path gain threshold.

Input:
  • tensor (tf.Tensor): A 2D TensorFlow tensor representing the coverage map with path gain values.

  • threshold_db (float): The minimum path gain threshold in dB.

Output:

coverage_ratio (float): The coverage ratio as a percentage.

RIS_Opt.plot_multiple_cdfs(cdfs, labels)[source]

Plots multiple cumulative distribution functions (CDFs) on the same figure.

Input:
  • cdfs (list(tuple(np.ndarray, np.ndarray))): A list of tuples, where each tuple contains (sorted_values_db, cdf) for a CDF curve.

  • labels (list(str)): A list of strings representing the labels for each CDF.

Output:

figure (matplotlib.figure.Figure): A figure with multiple CDFs plotted, each with distinct marker styles and dashed lines for the CDFs of the distance-based configured RIS-aided scenarios.

RIS_Opt.selection(coords, k)[source]

Performs K-means clustering on a set of coordinates and returns the centroids to be appointed as the target points of the RIS.

This function clusters the provided 3D coordinates based on their x and y values using K-means, and assigns the z-value of the first coordinate to all centroids.

Input:
  • coords (list or np.ndarray): A list or NumPy array of coordinates, each specified as [x, y, z].

  • k (int): The number of clusters (centroids) to extract.

Output:

centroids (np.ndarray): An array of centroids as 3D points with the z-value inherited from the first input coordinate.

RIS_Opt.to_db(x)[source]

Converts a value from a linear scale to decibels (dB).

Input:

x (float or tf.Tensor): A numeric value or a TensorFlow tensor represented in linear scale.

Output:

dB (tf.Tensor): The value in decibels.