Skip to content

Module run_analysis

main

def main()

Main entry point for the analysis script.

Module run_free_space_study

ConsoleLogger

class ConsoleLogger()

A console-based logger for headless script execution.

create_temp_config

def create_temp_config(base_config, frequency_mhz)

Creates a temporary configuration for a single free-space run.

main

def main()

Runs a free-space simulation for each available frequency to validate the antenna models and the core simulation pipeline.

Module run_parallel_studies

setup_console_logging

def setup_console_logging()

Sets up a basic console logger with color.

split_list_into_n

def split_list_into_n(items, n)

Split a list into n approximately equal parts.

calculate_split_factors

def calculate_split_factors(num_phantoms, num_items, target_splits)

Calculate optimal splitting factors for phantoms and items (frequencies/antennas). Prioritizes splitting phantoms first, then items.

Returns: (phantom_splits, item_splits) where phantom_splits * item_splits = target_splits

split_config

def split_config(config_path, num_splits, logger)

Splits the configuration file into a number of parallel configs using smart algorithm.

run_study_process

def run_study_process(args)

Runs the study for a given config file.

main

def main()

Main function to split configs and run studies in parallel.

Module run_study

ConsoleLogger

class ConsoleLogger()

A console-based logger to substitute for the GUI.

study_process_wrapper

def study_process_wrapper(queue, stop_event, config_filename, process_id)

This function runs in a separate process to execute the study. It sets up its own loggers and communicates with the main GUI process via a queue and a stop event.

main

def main()

Main entry point for running a study. It launches the GUI in the main process and the study in a separate process.

Module antenna

Antenna

class Antenna()

Manages antenna-specific properties and configurations.

__init__

def __init__(config: "Config", frequency_mhz: int)

Initializes the Antenna object.

Arguments:

  • config - The configuration object containing antenna settings.
  • frequency_mhz - The operating frequency in MHz.

get_config_for_frequency

def get_config_for_frequency() -> dict

Gets the antenna configuration for the current frequency.

Raises:

  • ValueError - If no configuration is defined for the frequency.

Returns:

The antenna configuration dictionary.

get_model_type

def get_model_type() -> str

Gets the antenna model type (e.g., 'PIFA', 'IFA').

get_source_entity_name

def get_source_entity_name() -> str

Gets the name of the source entity in the CAD model.

get_centered_antenna_path

def get_centered_antenna_path(centered_antennas_dir: str) -> str

Constructs the path to the centered .sab antenna file.

Arguments:

  • centered_antennas_dir - The directory for centered antenna files.

Returns:

The absolute path to the centered antenna model file.

Module colors

get_color

def get_color(log_type: str) -> str

Retrieves the colorama color code for a given log type.

Arguments:

  • log_type - The type of log message (e.g., 'info', 'warning').

Returns:

The colorama color code for the log type.

Module config

deep_merge

def deep_merge(source: dict, destination: dict) -> dict

Recursively merges two dictionaries, overwriting destination with source values.

Arguments:

  • source - The dictionary with values to merge.
  • destination - The dictionary to be merged into.

Returns:

The merged dictionary.

Config

class Config()

Manages loading and access of hierarchical JSON configurations.

__init__

def __init__(base_dir: str, config_filename: str = "near_field_config.json")

Initializes the Config object by loading all relevant configuration files.

Arguments:

  • base_dir - The base directory of the project.
  • config_filename - The name of the main configuration file to load.

get_setting

def get_setting(path: str, default=None)

Retrieves a nested setting using a dot-separated path.

Example:

get_setting("simulation_parameters.number_of_point_sensors")

Arguments:

  • path - The dot-separated path to the setting.
  • default - The default value to return if the setting is not found.

Returns:

The value of the setting, or the default value.

get_simulation_parameters

def get_simulation_parameters() -> dict

Gets the 'simulation_parameters' dictionary.

get_antenna_config

def get_antenna_config() -> dict

Gets the 'antenna_config' dictionary.

get_gridding_parameters

def get_gridding_parameters() -> dict

Gets the 'gridding_parameters' dictionary.

get_phantom_definition

def get_phantom_definition(phantom_name: str) -> dict

Gets the configuration for a specific phantom.

Arguments:

  • phantom_name - The name of the phantom.

Returns:

The configuration for the specified phantom.

get_material_mapping

def get_material_mapping(phantom_name: str) -> dict

Gets the material name mapping for a specific phantom.

Arguments:

  • phantom_name - The name of the phantom.

Returns:

The material mapping dictionary.

get_solver_settings

def get_solver_settings() -> dict

Gets the 'solver_settings' dictionary.

get_antenna_component_names

def get_antenna_component_names(antenna_model_type: str) -> list

Gets component names for a specific antenna model type.

Arguments:

  • antenna_model_type - The type of the antenna model (e.g., 'PIFA').

Returns:

A list of component names.

get_manual_isolve

def get_manual_isolve() -> bool

Gets the 'manual_isolve' boolean flag.

get_freespace_expansion

def get_freespace_expansion() -> list

Gets the freespace antenna bounding box expansion in millimeters.

get_excitation_type

def get_excitation_type() -> str

Gets the simulation excitation type (e.g., 'Harmonic', 'Gaussian').

get_bandwidth

def get_bandwidth() -> float

Gets the simulation bandwidth in MHz for Gaussian excitation.

get_placement_scenario

def get_placement_scenario(scenario_name: str) -> dict

Gets the definition for a specific placement scenario.

Arguments:

  • scenario_name - The name of the placement scenario.

Returns:

The configuration for the placement scenario.

get_profiling_config

def get_profiling_config(study_type: str) -> dict

Gets the profiling configuration for a given study type.

Arguments:

  • study_type - The type of the study (e.g., 'near_field').

Returns:

The profiling configuration for the study type.

get_line_profiling_config

def get_line_profiling_config() -> dict

Gets the 'line_profiling' settings.

get_download_email

def get_download_email() -> str

Gets the download email from environment variables.

get_osparc_credentials

def get_osparc_credentials() -> dict

Gets oSPARC credentials from environment variables.

Raises:

  • ValueError - If required oSPARC credentials are not set.

Returns:

A dictionary containing oSPARC API credentials.

get_only_write_input_file

def get_only_write_input_file() -> bool

Gets the 'only_write_input_file' flag from 'execution_control'.

get_auto_cleanup_previous_results

def get_auto_cleanup_previous_results() -> list

Gets the 'auto_cleanup_previous_results' setting from 'execution_control'.

This setting determines which previous simulation files to automatically delete to preserve disk space. It should only be used in serial workflows.

Returns:

A list of file types to clean up (e.g., ["output", "input"]).

Module data_extractor

get_parameter_from_json

def get_parameter_from_json(file_path: str, json_path: str) -> Any

Extracts a nested parameter from a JSON file using a dot-separated path.

Arguments:

  • file_path - The path to the JSON file.
  • json_path - The dot-separated path to the nested key.

Returns:

The value found at the specified path, or None if not found.

get_parameter

def get_parameter(source_config: Dict[str, Any], context: Dict[str,
                                                               Any]) -> Any

Retrieves a parameter from a data source based on a configuration.

This function uses a source_config to determine the data source type (e.g., 'json') and access parameters. The context dictionary provides dynamic values for formatting file paths.

Arguments:

  • source_config - A dictionary defining the data source.
  • context - A dictionary with contextual information for formatting.

Returns:

The retrieved parameter value, or None on error.

Module gui_manager

QueueGUI

class QueueGUI(LoggingMixin)

A proxy for the main GUI, designed to operate in a separate process.

This class mimics the ProgressGUI interface but directs all calls to a multiprocessing.Queue, allowing a worker process to send thread-safe updates to the main GUI process.

__init__

def __init__(queue: "Queue", stop_event: "Event", profiler: "Profiler",
             progress_logger: "Logger", verbose_logger: "Logger")

Initializes the QueueGUI proxy.

Arguments:

  • queue - The queue for inter-process communication.
  • stop_event - An event to signal termination.
  • profiler - The profiler instance for ETA calculations.
  • progress_logger - Logger for progress messages.
  • verbose_logger - Logger for detailed messages.

log

def log(message: str, level: str = "verbose", log_type: str = "default")

Sends a log message to the main GUI process via the queue.

update_overall_progress

def update_overall_progress(current_step: int, total_steps: int)

Sends an overall progress update to the queue.

update_stage_progress

def update_stage_progress(stage_name: str, current_step: int,
                          total_steps: int)

Sends a stage-specific progress update to the queue.

start_stage_animation

def start_stage_animation(task_name: str, end_value: int)

Sends a command to start a progress bar animation.

end_stage_animation

def end_stage_animation()

Sends a command to stop the progress bar animation.

update_profiler

def update_profiler()

Sends the updated profiler object to the GUI process.

process_events

def process_events()

A no-op method for interface compatibility.

is_stopped

def is_stopped() -> bool

Checks if the main process has signaled a stop request.

ProgressGUI

class ProgressGUI(QWidget)

The main GUI for monitoring simulation progress.

Provides a real-time view of the study's progress, including progress bars, ETA, and a log of status messages. It runs in the main process and communicates with the worker process via a multiprocessing queue.

__init__

def __init__(queue: "Queue",
             stop_event: "Event",
             process,
             window_title: str = "Simulation Progress")

Initializes the ProgressGUI window.

Arguments:

  • queue - The queue for receiving messages from the worker process.
  • stop_event - An event to signal termination to the worker process.
  • process - The worker process running the study.
  • window_title - The title of the GUI window.

init_ui

def init_ui()

Initializes and arranges all UI widgets.

process_queue

def process_queue()

Processes messages from the worker process queue to update the UI.

tray_icon_activated

def tray_icon_activated(reason)

Handles activation of the system tray icon.

hide_to_tray

def hide_to_tray()

Hides the main window and shows the system tray icon.

show_from_tray

def show_from_tray()

Shows the main window from the system tray.

stop_study

def stop_study()

Sends a stop signal to the worker process.

update_overall_progress

def update_overall_progress(current_step: int, total_steps: int)

Updates the overall progress bar.

update_stage_progress

def update_stage_progress(stage_name: str, current_step: int,
                          total_steps: int)

Updates the stage-specific progress bar.

start_stage_animation

def start_stage_animation(estimated_duration: float, end_step: int)

Starts a smooth animation for the stage progress bar.

Arguments:

  • estimated_duration - The estimated time in seconds for the task.
  • end_step - The target step value for the animation.

end_stage_animation

def end_stage_animation()

Stops the stage progress bar animation.

update_animation

def update_animation()

Updates the progress bar animation frame by frame.

update_status

def update_status(message: str, log_type: str = "default")

Appends a message to the status log text box.

update_clock

def update_clock()

Updates the elapsed time and ETA labels.

study_finished

def study_finished(error: bool = False)

Handles study completion, stopping timers and updating the UI.

closeEvent

def closeEvent(event)

Handles the window close event, ensuring worker process termination.

Module logging_manager

ColorFormatter

class ColorFormatter(logging.Formatter)

A custom log formatter that applies color to terminal output.

format

def format(record: logging.LogRecord) -> str

Formats the log record by adding color codes.

Arguments:

  • record - The log record to format.

Returns:

The formatted and colorized log message.

setup_loggers

def setup_loggers(
        process_id: str = None) -> tuple[logging.Logger, logging.Logger, str]

Initializes and configures the dual-logging system.

Sets up two loggers: 1. 'progress': For high-level, user-facing updates. 2. 'verbose': For detailed, internal debugging information.

Also handles log rotation to prevent excessive disk usage.

Arguments:

  • process_id - An identifier for the process to ensure unique log filenames in parallel runs.

Returns:

A tuple containing the progress logger, verbose logger, and the session timestamp.

shutdown_loggers

def shutdown_loggers()

Safely shuts down all logging handlers to release file locks.

LoggingMixin

class LoggingMixin()

A mixin class that provides a standardized logging interface.

Provides a _log method that directs messages to the appropriate logger ('progress' or 'verbose') and, if available, to the GUI.

Module profiler

Profiler

class Profiler()

Manages execution time tracking, ETA estimation, and study phase management.

This class divides a study into phases (setup, run, extract), calculates weighted progress, and estimates the time remaining. It also saves updated time estimates to a configuration file after each run, making it self-improving.

__init__

def __init__(execution_control: dict, profiling_config: dict, study_type: str,
             config_path: str)

Initializes the Profiler.

Arguments:

  • execution_control - A dictionary indicating which study phases are active.
  • profiling_config - A dictionary with historical timing data.
  • study_type - The type of the study (e.g., 'near_field').
  • config_path - The file path to the profiling configuration.

set_total_simulations

def set_total_simulations(total: int)

Sets the total number of simulations for the study.

set_project_scope

def set_project_scope(total_projects: int)

Sets the total number of projects to be processed.

set_current_project

def set_current_project(project_index: int)

Sets the index of the currently processing project.

start_stage

def start_stage(phase_name: str, total_stages: int = 1)

Marks the beginning of a new study phase or stage.

Arguments:

  • phase_name - The name of the phase being started.
  • total_stages - The total number of stages within this phase.

end_stage

def end_stage()

Marks the end of a study phase and records its duration.

complete_run_phase

def complete_run_phase()

Stores the total duration of the 'run' phase from its subtasks.

get_weighted_progress

def get_weighted_progress(phase_name: str,
                          phase_progress_ratio: float) -> float

Calculates the overall study progress based on phase weights.

Arguments:

  • phase_name - The name of the current phase.
  • phase_progress_ratio - The progress of the current phase (0.0 to 1.0).

Returns:

The total weighted progress percentage.

get_subtask_estimate

def get_subtask_estimate(task_name: str) -> float

Retrieves the estimated time for a specific subtask.

Arguments:

  • task_name - The name of the subtask.

Returns:

The estimated duration in seconds.

get_time_remaining

def get_time_remaining(current_stage_progress: float = 0.0) -> float

Estimates the total time remaining for the study.

This considers completed phases, current phase progress, and estimated time for all future phases.

Arguments:

  • current_stage_progress - The progress of the current stage (0.0 to 1.0).

Returns:

The estimated time remaining in seconds.

update_and_save_estimates

def update_and_save_estimates()

Updates the profiling configuration with the latest average times and saves it.

This makes the profiler's estimates self-improving over time.

save_estimates

def save_estimates()

Saves the final profiling estimates at the end of the study.

Module project_manager

ProjectCorruptionError

class ProjectCorruptionError(Exception)

Custom exception raised for errors related to corrupted or locked project files.

ProjectManager

class ProjectManager(LoggingMixin)

Manages the lifecycle of Sim4Life (.smash) project files.

Handles creation, opening, saving, and validation of project files, ensuring robustness against file corruption and locks.

__init__

def __init__(config: "Config",
             verbose_logger: "Logger",
             progress_logger: "Logger",
             gui: "QueueGUI" = None)

Initializes the ProjectManager.

Arguments:

  • config - The main configuration object.
  • verbose_logger - Logger for detailed output.
  • progress_logger - Logger for high-level progress updates.
  • gui - The GUI proxy for inter-process communication.

create_or_open_project

def create_or_open_project(phantom_name: str,
                           frequency_mhz: int,
                           scenario_name: str = None,
                           position_name: str = None,
                           orientation_name: str = None)

Creates a new project or opens an existing one based on the 'do_setup' flag.

Arguments:

  • phantom_name - The name of the phantom model.
  • frequency_mhz - The simulation frequency in MHz.
  • scenario_name - The base name of the placement scenario.
  • position_name - The name of the position within the scenario.
  • orientation_name - The name of the orientation within the scenario.

Raises:

  • ValueError - If required parameters are missing or study_type is unknown.
  • FileNotFoundError - If do_setup is false and the project file does not exist.
  • ProjectCorruptionError - If the project file is corrupted.

create_new

def create_new()

Creates a new, empty project in memory.

Closes any open document, deletes the existing project file and its cache, then creates a new unsaved project.

open

def open()

Opens an existing project after performing validation checks.

Raises:

  • ProjectCorruptionError - If the project file is invalid, locked, or cannot be opened by Sim4Life.

save

def save()

Saves the currently active project to its designated file path.

Raises:

  • ValueError - If the project path has not been set.

close

def close()

Closes the currently active Sim4Life document.

cleanup

def cleanup()

Closes any open project.

reload_project

def reload_project()

Saves, closes, and re-opens the project to load simulation results.

Module results_extractor

ResultsExtractor

class ResultsExtractor(LoggingMixin)

Orchestrates post-processing and data extraction from simulation results.

Coordinates modules to extract power, SAR, and sensor data from a Sim4Life simulation, then manages report generation and cleanup.

__init__

def __init__(config: "Config",
             simulation: "s4l_v1.simulation.emfdtd.Simulation",
             phantom_name: str,
             frequency_mhz: int,
             scenario_name: str,
             position_name: str,
             orientation_name: str,
             study_type: str,
             verbose_logger: "Logger",
             progress_logger: "Logger",
             free_space: bool = False,
             gui: "QueueGUI" = None,
             study: "BaseStudy" = None)

Initializes the ResultsExtractor.

Arguments:

  • config - The configuration object for the study.
  • simulation - The simulation object to extract results from.
  • phantom_name - The name of the phantom model used.
  • frequency_mhz - The simulation frequency in MHz.
  • scenario_name - The base name of the placement scenario.
  • position_name - The name of the position within the scenario.
  • orientation_name - The name of the orientation within the scenario.
  • study_type - The type of the study (e.g., 'near_field').
  • verbose_logger - Logger for detailed output.
  • progress_logger - Logger for progress updates.
  • free_space - Flag indicating if the simulation was run in free space.
  • gui - The GUI proxy for updates.
  • study - The parent study object.

extract

def extract()

Orchestrates the extraction of all relevant data from the simulation.

This is the main entry point for the class. It coordinates extraction modules for power, SAR, and sensor data, then saves the results.

Module simulation_runner

SimulationRunner

class SimulationRunner(LoggingMixin)

Manages simulation execution via the Sim4Life API or iSolve.exe.

__init__

def __init__(config: "Config",
             project_path: str,
             simulations: Union["s4l_v1.simulation.emfdtd.Simulation",
                                List["s4l_v1.simulation.emfdtd.Simulation"]],
             verbose_logger: "Logger",
             progress_logger: "Logger",
             gui: "QueueGUI" = None,
             study: "BaseStudy" = None)

Initializes the SimulationRunner.

Arguments:

  • config - The configuration object for the study.
  • project_path - The file path to the Sim4Life project.
  • simulations - A single simulation or a list of simulations to run.
  • verbose_logger - Logger for detailed, verbose output.
  • progress_logger - Logger for high-level progress updates.
  • gui - The GUI proxy for sending updates to the main process.
  • study - The parent study object for profiling and context.

run_all

def run_all()

Runs all simulations in the list, managing GUI animations.

run

def run(simulation: "s4l_v1.simulation.emfdtd.Simulation")

Runs a single simulation, wrapped in a subtask for timing.

Module utils

StudyCancelledError

class StudyCancelledError(Exception)

Custom exception to indicate that the study was cancelled by the user.

Profiler

class Profiler()

A simple profiler to track and estimate execution time for a series of runs.

__init__

def __init__(config_path: str, study_type: str = "sensitivity_analysis")

Initializes the simple Profiler.

Arguments:

  • config_path - The file path to the profiling configuration JSON.
  • study_type - The key for the study-specific configuration.

start_study

def start_study(total_runs: int)

Starts a new study, resetting counters.

start_run

def start_run()

Marks the beginning of a single run.

end_run

def end_run()

Marks the end of a single run and records its duration.

get_average_run_time

def get_average_run_time() -> float

Gets the average run time, prioritizing measured times over historical estimates.

get_time_remaining

def get_time_remaining() -> float

Estimates the time remaining for the entire study.

save_estimates

def save_estimates()

Saves the new average run time to the configuration file.

get_elapsed

def get_elapsed() -> float

Gets the total elapsed time since the study started.

Returns:

The elapsed time in seconds.

subtask

@contextlib.contextmanager
def subtask(name: str)

A context manager to time a subtask.

format_time

def format_time(seconds: float) -> str

Formats seconds into a human-readable string (e.g., 1m 23s).

non_blocking_sleep

def non_blocking_sleep(seconds: int)

A non-blocking sleep that processes GUI events.

profile

@contextlib.contextmanager
def profile(study: "BaseStudy", phase_name: str)

A context manager to profile a block of code (a 'phase').

profile_subtask

@contextlib.contextmanager
def profile_subtask(study: "BaseStudy",
                    task_name: str,
                    instance_to_profile=None)

A context manager for a 'subtask'.

Handles: - High-level timing via study.profiler. - GUI stage animation. - Optional, detailed line-by-line profiling if configured.

ensure_s4l_running

def ensure_s4l_running()

Ensures that the Sim4Life application is running.

open_project

def open_project(project_path: str)

Opens a Sim4Life project or creates a new one in memory.

delete_project_file

def delete_project_file(project_path: str)

Deletes the project file if it exists.

suppress_stdout_stderr

@contextlib.contextmanager
def suppress_stdout_stderr()

A context manager that redirects stdout and stderr to devnull.

Module src.analysis.analyzer

Analyzer

class Analyzer()

Analyzes simulation results using a strategy pattern.

__init__

def __init__(config: "Config", phantom_name: str,
             strategy: "BaseAnalysisStrategy")

Initializes the Analyzer.

Arguments:

  • config - The configuration object for the study.
  • phantom_name - The name of the phantom model being analyzed.
  • strategy - The analysis strategy to use.

run_analysis

def run_analysis()

Runs the full analysis pipeline using the selected strategy.

Module src.analysis.base_strategy

BaseAnalysisStrategy

class BaseAnalysisStrategy(ABC)

Abstract base class for analysis strategies.

__init__

def __init__(config: "Config", phantom_name: str)

Initializes the analysis strategy.

Arguments:

  • config - The main configuration object.
  • phantom_name - The name of the phantom being analyzed.

get_results_base_dir

@abstractmethod
def get_results_base_dir() -> str

Gets the base directory for results.

get_plots_dir

@abstractmethod
def get_plots_dir() -> str

Gets the directory for saving plots.

load_and_process_results

@abstractmethod
def load_and_process_results(analyzer: "Analyzer")

Loads and processes all relevant simulation results.

Arguments:

  • analyzer - The main analyzer instance calling the strategy.

get_normalization_factor

@abstractmethod
def get_normalization_factor(frequency_mhz: int,
                             simulated_power_w: float) -> float

Calculates the normalization factor for SAR values.

Arguments:

  • frequency_mhz - The simulation frequency in MHz.
  • simulated_power_w - The input power from the simulation in Watts.

Returns:

The calculated normalization factor.

extract_data

@abstractmethod
def extract_data(pickle_data: dict, frequency_mhz: int, detailed_name: str,
                 scenario_name: str, sim_power: float,
                 norm_factor: float) -> tuple[dict, list]

Extracts and structures data from a single simulation's result files.

Arguments:

  • pickle_data - Data loaded from the .pkl result file.
  • frequency_mhz - The simulation frequency.
  • detailed_name - The detailed name of the placement or scenario.
  • scenario_name - The general scenario name.
  • sim_power - The simulated input power in Watts.
  • norm_factor - The normalization factor to apply.

Returns:

A tuple containing the main result entry and a list of organ-specific entries.

apply_bug_fixes

@abstractmethod
def apply_bug_fixes(result_entry: dict) -> dict

Applies workarounds for known data inconsistencies.

Arguments:

  • result_entry - The data entry for a single simulation result.

Returns:

The corrected result entry.

calculate_summary_stats

@abstractmethod
def calculate_summary_stats(results_df: pd.DataFrame) -> pd.DataFrame

Calculates summary statistics from the aggregated results.

Arguments:

  • results_df - DataFrame with all aggregated simulation results.

Returns:

A DataFrame with summary statistics.

generate_plots

@abstractmethod
def generate_plots(analyzer: "Analyzer", plotter: "Plotter",
                   results_df: pd.DataFrame,
                   all_organ_results_df: pd.DataFrame)

Generates all plots relevant to this analysis strategy.

Arguments:

  • analyzer - The main analyzer instance.
  • plotter - The plotter instance to use for generating plots.
  • results_df - DataFrame with main aggregated results.
  • all_organ_results_df - DataFrame with detailed organ-level results.

Module src.analysis.far_field_strategy

FarFieldAnalysisStrategy

class FarFieldAnalysisStrategy(BaseAnalysisStrategy)

Analysis strategy for far-field simulations.

get_results_base_dir

def get_results_base_dir() -> str

Gets the base directory for far-field results.

get_plots_dir

def get_plots_dir() -> str

Gets the directory for saving far-field plots.

get_normalization_factor

def get_normalization_factor(frequency_mhz: int,
                             simulated_power_w: float) -> float

Returns the normalization factor for far-field analysis (always 1.0).

apply_bug_fixes

def apply_bug_fixes(result_entry: dict) -> dict

No bug fixes needed for far-field data.

calculate_summary_stats

def calculate_summary_stats(results_df: pd.DataFrame) -> pd.DataFrame

Calculates summary statistics for far-field results.

Module src.analysis.near_field_strategy

NearFieldAnalysisStrategy

class NearFieldAnalysisStrategy(BaseAnalysisStrategy)

Analysis strategy for near-field simulations.

get_results_base_dir

def get_results_base_dir() -> str

Gets the base directory for near-field results.

get_plots_dir

def get_plots_dir() -> str

Gets the directory for saving near-field plots.

load_and_process_results

def load_and_process_results(analyzer: "Analyzer")

Iterates through near-field simulation results and processes each one.

get_normalization_factor

def get_normalization_factor(frequency_mhz: int,
                             simulated_power_w: float) -> float

Calculates the normalization factor based on the target power.

Arguments:

  • frequency_mhz - The simulation frequency in MHz.
  • simulated_power_w - The input power from the simulation in Watts.

Returns:

The calculated normalization factor, or 1.0 if not possible.

extract_data

def extract_data(pickle_data: dict, frequency_mhz: int, placement_name: str,
                 scenario_name: str, sim_power: float,
                 norm_factor: float) -> tuple[dict, list]

Extracts and normalizes SAR data from a single near-field result.

Arguments:

  • pickle_data - Data loaded from the .pkl result file.
  • frequency_mhz - The simulation frequency.
  • placement_name - The detailed name of the placement.
  • scenario_name - The general scenario name (e.g., 'by_cheek').
  • sim_power - The simulated input power in Watts.
  • norm_factor - The normalization factor to apply to SAR values.

Returns:

A tuple containing the main result entry and a list of organ-specific entries.

apply_bug_fixes

def apply_bug_fixes(result_entry: dict) -> dict

Applies a workaround for Head SAR being miscategorized as Trunk SAR.

Arguments:

  • result_entry - The data entry for a single simulation result.

Returns:

The corrected result entry.

calculate_summary_stats

def calculate_summary_stats(results_df: pd.DataFrame) -> pd.DataFrame

Calculates summary statistics, including completion progress.

Arguments:

  • results_df - DataFrame with all aggregated simulation results.

Returns:

A DataFrame with mean SAR values and a 'progress' column.

generate_plots

def generate_plots(analyzer: "Analyzer", plotter: "Plotter",
                   results_df: pd.DataFrame,
                   all_organ_results_df: pd.DataFrame)

Generates all plots for the near-field analysis.

Includes bar charts for average SAR, line plots for psSAR, and boxplots for SAR distribution.

Arguments:

  • analyzer - The main analyzer instance.
  • plotter - The plotter instance for generating plots.
  • results_df - DataFrame with main aggregated results.
  • all_organ_results_df - DataFrame with detailed organ-level results.

Module src.analysis.plotter

Plotter

class Plotter()

Generates various plots from simulation results.

__init__

def __init__(plots_dir: str)

Initializes the Plotter and creates the output directory.

Arguments:

  • plots_dir - The directory where all generated plots will be saved.

plot_average_sar_bar

def plot_average_sar_bar(scenario_name: str, avg_results: pd.DataFrame,
                         progress_info: pd.Series)

Plots a bar chart of average Head and Trunk SAR per frequency.

Arguments:

  • scenario_name - The name of the placement scenario (e.g., 'by_cheek').
  • avg_results - DataFrame with average SAR values, indexed by frequency.
  • progress_info - Series with completion progress for each frequency.

plot_whole_body_sar_bar

def plot_whole_body_sar_bar(avg_results: pd.DataFrame)

Plots a bar chart of the average Whole-Body SAR per frequency.

Arguments:

  • avg_results - DataFrame with average SAR values, indexed by frequency.

plot_peak_sar_line

def plot_peak_sar_line(summary_stats: pd.DataFrame)

Plots the peak SAR across frequencies for far-field.

plot_pssar_line

def plot_pssar_line(scenario_name: str, avg_results: pd.DataFrame)

Plots a line chart of the average psSAR10g for different tissue groups.

Arguments:

  • scenario_name - The name of the placement scenario.
  • avg_results - DataFrame with average psSAR10g values for various tissues.

plot_sar_distribution_boxplots

def plot_sar_distribution_boxplots(scenario_name: str,
                                   scenario_results_df: pd.DataFrame)

Creates boxplots to show the distribution of SAR values for each metric.

Arguments:

  • scenario_name - The name of the placement scenario.
  • scenario_results_df - DataFrame with detailed results for the scenario.

plot_far_field_distribution_boxplot

def plot_far_field_distribution_boxplot(results_df: pd.DataFrame,
                                        metric: str = "SAR_whole_body")

Generates a boxplot for the distribution of a given metric in far-field results.

plot_sar_heatmap

def plot_sar_heatmap(organ_df: pd.DataFrame, group_df: pd.DataFrame,
                     tissue_groups: dict)

Generates the combined heatmap for Min, Avg, and Max SAR.

plot_peak_sar_heatmap

def plot_peak_sar_heatmap(organ_df: pd.DataFrame,
                          group_df: pd.DataFrame,
                          tissue_groups: dict,
                          value_col: str = "peak_sar_10g_mw_kg",
                          title: str = "Peak SAR")

Generates a combined heatmap for a given peak SAR metric.

Module src.analysis.strategies

BaseAnalysisStrategy

class BaseAnalysisStrategy(ABC)

Abstract base class for analysis strategies.

__init__

def __init__(config, phantom_name)

Initializes the analysis strategy.

Arguments:

  • config Config - The main configuration object.
  • phantom_name str - The name of the phantom being analyzed.

get_results_base_dir

@abstractmethod
def get_results_base_dir()

Returns the base directory where results for this strategy are stored.

get_plots_dir

@abstractmethod
def get_plots_dir()

Returns the directory where plots for this strategy should be saved.

load_and_process_results

@abstractmethod
def load_and_process_results(analyzer)

Loads and processes all relevant simulation results for the analysis.

Arguments:

  • analyzer Analyzer - The main analyzer instance calling the strategy.

get_normalization_factor

@abstractmethod
def get_normalization_factor(frequency_mhz, simulated_power_w)

Calculates the normalization factor to apply to SAR values.

Arguments:

  • frequency_mhz int - The simulation frequency in MHz.
  • simulated_power_w float - The input power from the simulation in Watts.

Returns:

  • float - The calculated normalization factor.

extract_data

@abstractmethod
def extract_data(pickle_data, frequency_mhz, detailed_name, scenario_name,
                 sim_power, norm_factor)

Extracts and structures data from a single simulation's result files.

Arguments:

  • pickle_data dict - Data loaded from the .pkl result file.
  • frequency_mhz int - The simulation frequency.
  • detailed_name str - The detailed name of the placement or scenario.
  • scenario_name str - The general scenario name.
  • sim_power float - The simulated input power in Watts.
  • norm_factor float - The normalization factor to apply.

Returns:

  • tuple - A tuple containing the main result entry (dict) and a list of organ-specific entries (list of dicts).

apply_bug_fixes

@abstractmethod
def apply_bug_fixes(result_entry)

Applies any necessary workarounds or fixes for known data inconsistencies.

Arguments:

  • result_entry dict - The data entry for a single simulation result.

Returns:

  • dict - The corrected result entry.

calculate_summary_stats

@abstractmethod
def calculate_summary_stats(results_df)

Calculates summary statistics from the aggregated results DataFrame.

Arguments:

  • results_df pd.DataFrame - The DataFrame containing all aggregated simulation results.

Returns:

  • pd.DataFrame - A DataFrame with summary statistics.

generate_plots

@abstractmethod
def generate_plots(analyzer, plotter, results_df, all_organ_results_df)

Generates all plots relevant to this analysis strategy.

Arguments:

  • analyzer Analyzer - The main analyzer instance.
  • plotter Plotter - The plotter instance to use for generating plots.
  • results_df pd.DataFrame - The DataFrame with main aggregated results.
  • all_organ_results_df pd.DataFrame - The DataFrame with detailed organ-level results.

NearFieldAnalysisStrategy

class NearFieldAnalysisStrategy(BaseAnalysisStrategy)

Analysis strategy for near-field simulations.

get_results_base_dir

def get_results_base_dir()

Returns the base directory for near-field results.

get_plots_dir

def get_plots_dir()

Returns the directory for saving near-field plots.

load_and_process_results

def load_and_process_results(analyzer)

Iterates through near-field simulation results and processes each one.

get_normalization_factor

def get_normalization_factor(frequency_mhz, simulated_power_w)

Calculates the normalization factor based on the target power defined in the antenna configuration.

Arguments:

  • frequency_mhz int - The simulation frequency in MHz.
  • simulated_power_w float - The input power from the simulation in Watts.

Returns:

  • float - The calculated normalization factor. Returns 1.0 if normalization is not possible.

extract_data

def extract_data(pickle_data, frequency_mhz, placement_name, scenario_name,
                 sim_power, norm_factor)

Extracts and normalizes SAR data from a single near-field simulation result.

Arguments:

  • pickle_data dict - Data loaded from the .pkl result file.
  • frequency_mhz int - The simulation frequency.
  • placement_name str - The detailed name of the placement.
  • scenario_name str - The general scenario name (e.g., 'by_cheek').
  • sim_power float - The simulated input power in Watts.
  • norm_factor float - The normalization factor to apply to SAR values.

Returns:

  • tuple - A tuple containing the main result entry (dict) and a list of organ-specific entries.

apply_bug_fixes

def apply_bug_fixes(result_entry)

Applies a workaround for a known issue where Head SAR is miscategorized as Trunk SAR.

Arguments:

  • result_entry dict - The data entry for a single simulation result.

Returns:

  • dict - The corrected result entry.

calculate_summary_stats

def calculate_summary_stats(results_df)

Calculates summary statistics, including completion progress for each scenario.

Arguments:

  • results_df pd.DataFrame - The DataFrame containing all aggregated simulation results.

Returns:

  • pd.DataFrame - A DataFrame with mean SAR values and a 'progress' column.

generate_plots

def generate_plots(analyzer, plotter, results_df, all_organ_results_df)

Generates all plots for the near-field analysis.

This includes bar charts for average SAR, line plots for psSAR, and boxplots for SAR distribution.

Arguments:

  • analyzer Analyzer - The main analyzer instance.
  • plotter Plotter - The plotter instance to use for generating plots.
  • results_df pd.DataFrame - The DataFrame with main aggregated results.
  • all_organ_results_df pd.DataFrame - The DataFrame with detailed organ-level results.

FarFieldAnalysisStrategy

class FarFieldAnalysisStrategy(BaseAnalysisStrategy)

Analysis strategy for far-field simulations.

Module src.antenna

Antenna

class Antenna()

Manages antenna-specific properties and configurations.

__init__

def __init__(config: "Config", frequency_mhz: int)

Initializes the Antenna object.

Arguments:

  • config - The configuration object containing antenna settings.
  • frequency_mhz - The operating frequency in MHz.

get_config_for_frequency

def get_config_for_frequency() -> dict

Gets the antenna configuration for the current frequency.

Raises:

  • ValueError - If no configuration is defined for the frequency.

Returns:

The antenna configuration dictionary.

get_model_type

def get_model_type() -> str

Gets the antenna model type (e.g., 'PIFA', 'IFA').

get_source_entity_name

def get_source_entity_name() -> str

Gets the name of the source entity in the CAD model.

get_centered_antenna_path

def get_centered_antenna_path(centered_antennas_dir: str) -> str

Constructs the path to the centered .sab antenna file.

Arguments:

  • centered_antennas_dir - The directory for centered antenna files.

Returns:

The absolute path to the centered antenna model file.

Module src.colors

get_color

def get_color(log_type: str) -> str

Retrieves the colorama color code for a given log type.

Arguments:

  • log_type - The type of log message (e.g., 'info', 'warning').

Returns:

The colorama color code for the log type.

Module src.config

deep_merge

def deep_merge(source: dict, destination: dict) -> dict

Recursively merges two dictionaries, overwriting destination with source values.

Arguments:

  • source - The dictionary with values to merge.
  • destination - The dictionary to be merged into.

Returns:

The merged dictionary.

Config

class Config()

Manages loading and access of hierarchical JSON configurations.

__init__

def __init__(base_dir: str, config_filename: str = "near_field_config.json")

Initializes the Config object by loading all relevant configuration files.

Arguments:

  • base_dir - The base directory of the project.
  • config_filename - The name of the main configuration file to load.

get_setting

def get_setting(path: str, default=None)

Retrieves a nested setting using a dot-separated path.

Example:

get_setting("simulation_parameters.number_of_point_sensors")

Arguments:

  • path - The dot-separated path to the setting.
  • default - The default value to return if the setting is not found.

Returns:

The value of the setting, or the default value.

get_simulation_parameters

def get_simulation_parameters() -> dict

Gets the 'simulation_parameters' dictionary.

<a id="src.config.Config.get