Leadfield-free TES Optimization

Introduction

The leadfield-free TES optimization supports standard 2-channel TES, focal center-surround Nx1 TES, TI stimulation and Tumor Treating Fields (TTF). Several quantities of interest (QoI) are supported, including:

  • for TES: Electric field magnitude (“magn”) and its normal component relative to the cortex orientation (“normal”)

  • for TIS: maximal envelope of TI field magnitude (“max_TI”) and envelope of the normal component of the TI field (“dir_TI_normal”)

  • for TTF: Electric field magnitude (“magn”), whereby the field magnitudes of the two array pairs will be averaged

The following optimization goals are available:

  • Maximize the QoI in a region-of-interest

  • Optimize the intensity-focality tradeoff between the QoI in the region-of-interest and the QoI in an avoidance region (e.g. the rest of the brain)

  • Maximize the intensity of the QoI in the region-of-interest, while making the field as unfocal as possible. This can be relevant for TTF, where the aim is to focus the treatment on a tumor region, while maintaing high intensities throughout the brain (as the cancer cells might already have infiltrated further regions).

Example 1: Optimizing the electric field magnitude for 2-channel TES

This example maximizes the electric field strength in a ROI around the left hand knob.

  • Python

    """
    Example to run TESoptimize with a standard TES montage to optimize the 
    field intensity in the ROI
    
    Copyright (c) 2024 SimNIBS developers. Licensed under the GPL v3.
    """
    from simnibs import opt_struct
    
    
    ''' Initialize structure '''
    opt = opt_struct.TesFlexOptimization()
    opt.subpath = 'm2m_ernie'                           # path of m2m folder containing the headmodel
    opt.output_folder = "tes_optimize_tes_intensity"
    
    ''' Set up goal function '''
    opt.goal = "mean"                                   # maximize the mean of field magnitude in the ROI
    opt.e_postproc = "magn"                             # postprocessing of e-fields ("magn": magnitude,
                                                        # "normal": normal component, "tangential": tangential component)
    
    ''' Define electrodes and array layout '''
    electrode_layout = opt.add_electrode_layout("ElectrodeArrayPair") # Pair of TES electrode arrays (here: 1 electrode per array)s
    electrode_layout.length_x = [70]                                  # x-dimension of electrodes
    electrode_layout.length_y = [50]                                  # y-dimension of electrodes
    electrode_layout.dirichlet_correction_detailed = False            # account for inhomogenous current distribution at electrode-skin interface (slow)
    electrode_layout.current = [0.002, -0.002]                        # electrode currents
    
    ''' Define ROI '''
    roi = opt.add_roi()
    roi.method = "surface"
    roi.surface_type = "central"                        # define ROI on central GM surfaces
    roi.roi_sphere_center_space = "subject"
    roi.roi_sphere_center = [-41.0, -13.0,  66.0]       # center of spherical ROI in subject space (in mm)
    roi.roi_sphere_radius = 20                          # radius of spherical ROI (in mm)
    # uncomment for visual control of ROI:
    #roi.subpath = opt.subpath
    #roi.write_visualization('','roi.msh')
    
    ''' Run optimization '''
    opt.run()
    

  • MATLAB

    %
    % Example to run TESoptimize with a standard TES montage to optimize the 
    % field intensity in the ROI
    %
    % Copyright (c) 2024 SimNIBS developers. Licensed under the GPL v3.
    %
    
    % Initialize structure
    opt = opt_struct('TesFlexOptimization');
    opt.subpath = 'm2m_ernie';                                % path of m2m folder containing the headmodel
    opt.output_folder = 'tes_optimize_tes_intensity';
    
    % Set up goal function
    opt.goal = 'mean';                                        % maximize the mean of field magnitude in the ROI
    opt.e_postproc = 'magn';                                  % postprocessing of e-fields ('magn': magnitude,
                                                              % 'normal': normal component, 'tangential': tangential component)
    
    % Define electrodes and array layout
    electrode_layout = opt_struct('ElectrodeArrayPair');      % Pair of TES electrode arrays (here: 1 electrode per array)
    electrode_layout.length_x = [70];                         % x-dimension of electrodes
    electrode_layout.length_y = [50];                         % y-dimension of electrodes
    electrode_layout.dirichlet_correction_detailed = false;   % account for inhomogenous current distribution at electrode-skin interface (slow)
    electrode_layout.current = [0.002, -0.002];               % electrode currents
    opt.electrode = electrode_layout;
    
    % Define ROI
    roi = opt_struct('RegionOfInterest');
    roi.method = 'surface';
    roi.surface_type = 'central';                             % define ROI on central GM surfaces
    roi.roi_sphere_center_space = 'subject';
    roi.roi_sphere_center = [-41.0, -13.0,  66.0];            % center of spherical ROI in subject space (in mm)
    roi.roi_sphere_radius = 20;                               % radius of spherical ROI (in mm)
    opt.roi{1} = roi;
    % uncomment for visual control of ROI:
    % roi.subpath = opt.subpath;
    % roi.fname_visu = 'roi';
    % run_simnibs(roi)
    
    % Run optimization
    run_simnibs(opt)
    

The optimization will create the Gmsh output file ernie_tes_flex_opt_surface_mesh.msh with the ROI, the optimized field and the electrode positions. The optimized electrode positions are listed in the summary.txt. In addition, the results folder contains visualizations (electrode_channel…png) for control of the electrode array layouts.

../_images/tes_intensity_opt.png

Example 2: Optimizing the focality of TI stimulation

This example optimizes the intensity - focality tradeoff of TIS, focused on the left hand knob. This requires the defintion of two regions: The first will be used as target ROI, the second will be the avoidance area (or “non-ROI). In addition, two thresholds are defined - the optimization goal is to ensure that the QoI (here: maxTI) is lower than the first threshold in the avoidance region, while it exceeds the second threshold in the ROI.

  • Python

    """
    Example to run TESoptimize for Temporal Interference (TI) to optimize the 
    focality in the ROI vs non-ROI
    
    Copyright (c) 2024 SimNIBS developers. Licensed under the GPL v3.
    """
    from simnibs import opt_struct
    
    
    ''' Initialize structure '''
    opt = opt_struct.TesFlexOptimization()
    opt.subpath = 'm2m_ernie'                               # path of m2m folder containing the headmodel
    opt.output_folder = "tes_optimize_ti_focality"
    
    ''' Set up goal function '''
    opt.goal = "focality"                                   # optimize the focality of "max_TI" in the ROI ("max_TI" defined by e_postproc)
    opt.threshold = [0.1, 0.2]                              # define threshold(s) of the electric field in V/m in the non-ROI and the ROI:
                                                            # if one threshold is defined, it is the goal that the e-field in the non-ROI is lower than this value and higher than this value in the ROI
                                                            # if two thresholds are defined, the first one is the threshold of the non-ROI and the second one is for the ROI
    opt.e_postproc = "max_TI"                               # postprocessing of e-fields
                                                            # "max_TI": maximal envelope of TI field magnitude
                                                            # "dir_TI_normal": envelope of normal component
                                                            # "dir_TI_tangential": envelope of tangential component
    ''' Define first electrode pair '''
    electrode_layout = opt.add_electrode_layout("ElectrodeArrayPair")   # Pair of TES electrode arrays (here: 1 electrode per array)
    electrode_layout.radius = [10]                                      # radii of electrodes
    electrode_layout.current = [0.002, -0.002]                          # electrode currents
    
    ''' Define second electrode pair '''
    electrode_layout = opt.add_electrode_layout("ElectrodeArrayPair")
    electrode_layout.radius = [10]
    electrode_layout.current = [0.002, -0.002]
    
    ''' Define ROI '''
    roi = opt.add_roi()
    roi.method = "surface"
    roi.surface_type = "central"                            # define ROI on central GM surfaces
    roi.roi_sphere_center_space = "subject"
    roi.roi_sphere_center = [-41.0, -13.0,  66.0]           # center of spherical ROI in subject space (in mm)
    roi.roi_sphere_radius = 20                              # radius of spherical ROI (in mm)
    # uncomment for visual control of ROI:
    #roi.subpath = opt.subpath
    #roi.write_visualization('','roi.msh')
    
    ''' Define non-ROI '''
    # all of GM surface except a spherical region with 25 mm around roi center
    non_roi = opt.add_roi()
    non_roi.method = "surface"
    non_roi.surface_type = "central"
    non_roi.roi_sphere_center_space = "subject"
    non_roi.roi_sphere_center = [-41.0, -13.0,  66.0]
    non_roi.roi_sphere_radius = 25
    non_roi.roi_sphere_operator = ["difference"]                             # take difference between GM surface and the sphere region
    # uncomment for visual control of non-ROI:
    #non_roi.subpath = opt.subpath
    #non_roi.write_visualization('','non-roi.msh')
    
    ''' Run optimization '''
    opt.run()
    

  • MATLAB

    %
    % Example to run TESoptimize for Temporal Interference (TI) to optimize the 
    % focality in the ROI vs non-ROI
    %
    % Copyright (c) 2024 SimNIBS developers. Licensed under the GPL v3.
    %
    
    % Initialize structure
    opt = opt_struct('TesFlexOptimization');
    opt.subpath = 'm2m_ernie';                              % path of m2m folder containing the headmodel
    opt.output_folder = 'tes_optimize_ti_focality';
    
    % Set up goal function
    opt.goal = 'focality';                                  % optimize the focality of 'max_TI' in the ROI ('max_TI' defined by e_postproc)
    opt.threshold = [0.1, 0.2];                             % define threshold(s) of the electric field in V/m in the non-ROI and the ROI:
                                                            % if one threshold is defined, it is the goal that the e-field in the non-ROI is lower than this value and higher than this value in the ROI
                                                            % if two thresholds are defined, the first one is the threshold of the non-ROI and the second one is for the ROI
    opt.e_postproc = 'max_TI';                              % postprocessing of e-fields
                                                            % 'max_TI': maximal envelope of TI field magnitude
                                                            % 'dir_TI_normal': envelope of normal component
                                                            % 'dir_TI_tangential': envelope of tangential component
    % Define first electrode pair
    electrode_layout = opt_struct('ElectrodeArrayPair');    % Pair of TES electrode arrays (here: 1 electrode per array)
    electrode_layout.radius = [10];                         % radii of electrodes
    electrode_layout.current = [0.002, -0.002];             % electrode currents
    opt.electrode{1} = electrode_layout;
    
    % Define second electrode pair
    electrode_layout = opt_struct('ElectrodeArrayPair');
    electrode_layout.radius = [10];
    electrode_layout.current = [0.002, -0.002];
    opt.electrode{2} = electrode_layout;
    
    % Define ROI
    roi = opt_struct('RegionOfInterest');
    roi.method = 'surface';
    roi.surface_type = 'central';                           % define ROI on central GM surfaces
    roi.roi_sphere_center_space = 'subject';
    roi.roi_sphere_center = [-41.0, -13.0,  66.0];          % center of spherical ROI in subject space (in mm)
    roi.roi_sphere_radius = 20;                             % radius of spherical ROI (in mm)
    opt.roi{1} = roi;
    % uncomment for visual control of ROI:
    % roi.subpath = opt.subpath;
    % roi.fname_visu = 'roi';
    % run_simnibs(roi)
    
    % Define non-ROI
    % all of GM surface except a spherical region with 25 mm around roi center
    non_roi = opt_struct('RegionOfInterest');
    non_roi.method = 'surface';
    non_roi.surface_type = 'central';
    non_roi.roi_sphere_center_space = 'subject';
    non_roi.roi_sphere_center = [-41.0, -13.0,  66.0];
    non_roi.roi_sphere_radius = 25;
    non_roi.roi_sphere_operator = ['difference'];           % take difference between GM surface and the sphere region
    opt.roi{2} = non_roi;
    % uncomment for visual control of the ROI before running the optimization:
    % non_roi.subpath = opt.subpath;
    % non_roi.fname_visu = 'non-roi';
    % run_simnibs(non_roi)
    
    % Run optimization
    run_simnibs(opt)
    

The optimization will create the Gmsh output file ernie_tes_flex_opt_surface_mesh.msh with the optimized field, electrode positions, ROI, and avoidance region. The optimized electrode positions are listed in the summary.txt. In addition, the results folder contains visualizations (electrode_channel…png) for control of the electrode array layouts.

../_images/ti_focality_opt.png

Notes

  • The optimization uses the MKL Pardiso direct solver for accelerating the simulations. The SimNIBS standard FEM solver can be chosen optionally to reduce memory consumption, but will also substantially slow down the optimization.

  • 32GB main memory are recommended, even thougth some optimizations will run with 16GB main memory.

  • Optimization is performed using the differential evolution algorithm, which is stochastic in nature. As such, solutions will differ between repeated optimization runs, even though the achieved final cost will be very close to each other.

  • For TTF, we recommend setting constrain_electrode_locations to True, which will restrict the locations for each of the four electrode arrays to frontal, left and right parietal, and occipital. This speeds up the search by reducing the likelihood for overlapping configurations. The restriction is applied to the centers of the arrays, so that half of an array can still move into the neighboring skin areas, keeping sufficient flexibility for the optimization.

../_images/tes_flex_opt_skinregions.png