Skip to content

mlueckel/FASTANS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FASTANS - Fast Targeted Functional Network Stimulation

DOI

FASTANS is an accelerated, Python-based implementation of the Targeted Functional Network Stimulation (TANS) approach described in Lynch et al. [1,2]. The github repository with the original Matlab code can be found here: https://github.com/cjl2007/Targeted-Functional-Network-Stimulation

🚀 While the original implementation usually takes several hours to run [2], FASTANS allows optimization of TMS coil placements within minutes, without any particular need for high performance computing or parallelization.

[1] Lynch, C. J., Elbau, I. G., Ng, T. H., Wolk, D., Zhu, S., Ayaz, A., ... & Liston, C. (2022). Automated optimization of TMS coil placement for personalized functional network engagement. Neuron, 110(20), 3263-3277.

[2] Lynch, C. J., Elbau, I. G., Zhu, S., Ayaz, A., Bukhari, H., Power, J. D., & Liston, C. (2023). Precision mapping and transcranial magnetic stimulation of individual-specific functional brain networks in humans. STAR protocols, 4(1), 102118.

Use cases

FASTANS supports three use cases/file format configurations (for illustration, see figure below). TMS coil placements can be optimized based on:

  1. Continuous FC maps in T1 volume space

    Example scripts:

    Negative FC target: FASTANS_TMS_optimization_pipeline_EXAMPLE_continuous_FC_volume_negative_FC.py

    Positive FC target: FASTANS_TMS_optimization_pipeline_EXAMPLE_continuous_FC_volume_negative_FC.py

  2. Continuous FC maps in surface space (fs_LR_32k)

    Example scripts:

    Negative FC target: FASTANS_TMS_optimization_pipeline_EXAMPLE_continuous_FC_surface_negative_FC.py

    Positive FC target: FASTANS_TMS_optimization_pipeline_EXAMPLE_continuous_FC_surface_positive_FC.py

  3. Parcellated FC maps in surface space (fs_LR_32k)

    Example script:

    FASTANS_TMS_optimization_pipeline_EXAMPLE_parcellated_FC_surface.py

Note: The example below follows use case 3.

Installation

  1. Download/clone this code repository.
  2. In the example script(s) above (FASTANS_TMS_optimization_pipeline_EXAMPLE_XXX.py) and FASTANS.py (within the code folder), edit the FASTANS_installation_folderpath variable according to your download location of the FASTANS code repository.
  3. Additionally: In the example script(s) above (FASTANS_TMS_optimization_pipeline_EXAMPLE_XXX.py), edit the simnibs_installation_path variable according to the location of your SimNIBS 4.5 installation - this is needed to find the correct TMS coil (.ccd) files provided by SimNIBS (usually stored in /SimNIBSInstallationFolder/resources/coil_models/Drakaki_BrainStim_2022/).

Software dependencies:

Recommended way of installing SimNIBS 4.5 (Linux):

  1. Download and install the Miniconda Python 3 distribution (https://www.anaconda.com/docs/getting-started/miniconda/install#linux-terminal-installer).
  2. Download the SimNIBS Linux environment file (https://github.com/simnibs/simnibs/blob/v4.5.0/environment_linux.yml).
  3. Run in a terminal window:
    export PATH="$HOME/miniconda3/bin:$PATH" # This part can change depending on your miniconda installation
    conda env create -f ~/Downloads/environment_linux.yml # This part can change depending on your download location of the SimNIBS Linux environment file
    conda activate simnibs_env
    pip install https://github.com/simnibs/simnibs/releases/download/v4.5.0/simnibs-4.5.0-cp311-cp311-linux_x86_64.whl
  4. Wihtin the SimNIBS conda environment, install a Python IDE, e.g., Spyder:
    pip install spyder
  5. (Optional) To setup the menu icons, file associations, the MATLAB library and add SimNIBS to the system path, run the postinstall_simnibs script:
    mkdir $HOME/SimNIBS
    postinstall_simnibs --setup-links -d $HOME/SimNIBS

Note: These instructions are largely based on the installation instructions given on the SimNIBS website: https://simnibs.github.io/simnibs/build/html/installation/conda.html

Example use

This tutorial uses example data available from: https://drive.google.com/drive/folders/10s5uoIkANYWtr-5KzDY7NOfsEsdqldGb?usp=drive_link

The example_data folder contains all necessary input files as well as all output files generated by FASTANS using the following configurations in the FASTANS_TMS_optimization_pipeline.py script. If you want to run the pipeline and generate the output files yourself, please adjust the paths according to your download path of the example data.

#=============================================================================
# FASTANS configuration
#=============================================================================

# Name of output folder
output_foldername = 'Frontoparietal'

# Full path to output folder
output_folderpath = os.path.join('/.../FASTANS/resources/example_data/FASTANS', output_foldername)

# Path to subject-specific SimNIBS m2m folder
m2m_folderpath = '/.../FASTANS/resources/example_data/m2m_FASTANS_example'

# Functional network map (.dlabel.nii/.dscalar.nii/.dtseries.nii file; 32k_fs_LR space)
FCmap_filepath = '/.../FASTANS/resources/example_data/PFM/PFM_Lynch2024priors.dlabel.nii'

# Subject midthickness surfaces (.surf.gii files; 32k_fs_LR space)
surface_midthickness_left_filepath = '/.../FASTANS/resources/example_data/data/anat/midthickness_surface_left.32k_fs_LR.surf.gii'
surface_midthickness_right_filepath = '/.../FASTANS/resources/example_data/data/anat/midthickness_surface_right.32k_fs_LR.surf.gii'

# Sulcal depth map (.dscalar.nii file; 32k_fs_LR space)
sulcal_depth_filepath = '/.../FASTANS/resources/example_data/data/anat/sulcal_depth.32k_fs_LR.dscalar.nii'

# Type of FC map ('metric' or 'parcellation') — this pipeline expects 'parcellation'.
FCmap_type = 'parcellation'

# Parcellation label IDs: targets and avoidance
target_ids = [9] # 9 = Frontoparietal
avoidance_ids = [13,14,1,2,3,4] # 13 = Salience, 14 = Cingulo-opercular, 1-4 = Default Mode (sub)networks

# Percentiles used to define E-field "hotspots" (higher = smaller, more focal)
hotspot_percentiles = np.arange(99.0, 99.9, 0.1)

# Search space restricting stimulation to left PFC (choose variant as needed)
search_space_filepath = os.path.join(FASTANS_installation_folderpath, 'resources', 'search_spaces', 'SearchSpace_PFC_L.dscalar.nii')
# Alternative search spaces:
# search_space_filepath = '/.../SearchSpace_PFC_L_noPCG.dscalar.nii'
# search_space_filepath = '/.../SearchSpace_PFC_L_noPCG+DMPFC.dscalar.nii'
# search_space_filepath = '/.../SearchSpace_PFC_L_noPCG+DMPFC+IFG.dscalar.nii'

# TMS coil model (SimNIBS naming); choose matching to actual hardware
coil_model = 'MagVenture_Cool-B65'

Example outputs can be inspected in Connectome Workbench viewer (wb_view) by loading the FASTANS_example.scene file.

This scene will visualize the following input and output files:

  1. The midthickness surfaces (upper row), incl. their inflated version (lower row).
Screenshot from 2025-08-30 19-27-20
  1. The individual functional network parcellation (derived from the precision functional mapping (PFM) procedure described below):
Screenshot from 2025-08-30 19-27-59
  1. The "target regions" -- in this case, the frontoparietal network. This output is generated using the following lines of code:
FASTANS.extract_parcel(FCmap_filepath, target_ids,
                       os.path.join(output_folderpath,
                       'TargetRegions.dlabel.nii'))
Screenshot from 2025-08-30 19-28-04
  1. The "avoidance regions -- in this case, the cingulo-opercular/action-mode, salience, and default mode (sub-) networks. This output is generated using the following lines of code:
FASTANS.extract_parcel(FCmap_filepath, avoidance_ids,
                       os.path.join(output_folderpath,
                       'AvoidanceRegions.dlabel.nii'))

Screenshot from 2025-08-30 19-28-09
  1. The "target patch", i.e., the largest patch of the frontoparietal target network within the search space (i.e., the left prefrontal cortex). This output is generated using the following lines of code:
FASTANS.mask_cifti(os.path.join(output_folderpath, 'TargetRegions.dlabel.nii'),
                   'SearchSpace',
                   search_space_filepath,
                   'binary')

FASTANS.cifti_extract_largest_cluster(os.path.join(output_folderpath, 'TargetRegions_SearchSpace.dlabel.nii'),
                                      surface_midthickness_left_filepath,
                                      surface_midthickness_right_filepath)
Screenshot from 2025-08-30 19-57-05
  1. The "target patch", i.e., the largest patch of the frontoparietal target network within the search space (i.e., the left prefrontal cortex), restricted to the gyral crown. This output is generated using the following lines of code:
FASTANS.mask_cifti(os.path.join(output_folderpath, 'TargetRegions_SearchSpace.dlabel.nii'),
                   'SulcalCrown',
                   sulcal_depth_filepath,
                   'metric',
                   mask_threshold=0.5)

FASTANS.cifti_extract_largest_cluster(os.path.join(output_folderpath, 'TargetRegions_SearchSpace_SulcalCrown.dlabel.nii'),
                                      surface_midthickness_left_filepath,
                                      surface_midthickness_right_filepath)
Screenshot from 2025-08-30 19-57-09
  1. The final E-field simulations resulting from the optimized TMS coil placement. This output is generated using the lines of code detailed further below.
Screenshot from 2025-08-30 19-57-13

Additionally, Gmsh can be used to inspect the search grids and final E-field simulation.

  1. Coarse search grid of TMS coil placements (step 1; zoomed-in version below). This output is generated using the following lines of code:
target_coordinates = FASTANS.extract_target_coordinates(os.path.join(output_folderpath, 'TargetRegions_SearchSpace_TargetPatch.dlabel.nii'),
                                                        surface_midthickness_left_filepath,
                                                        surface_midthickness_right_filepath)

search_grid_coarse = FASTANS.generate_search_grid(m2m_folderpath,
                                                  os.path.join(output_folderpath, 'SimNIBS', 'SearchGrid', 'Step1_coarse'),
                                                  target_coordinates,
                                                  coil_scalp_distance,
                                                  35,  # radius
                                                  10,  # resolution
                                                  30,  # angle resolution
                                                  [-90, 60])
Screenshot from 2025-08-30 19-55-46 Screenshot from 2025-08-30 19-56-00
  1. Fine search grid of TMS coil placements (step 2; zoomed-in version below). This output is generated using the following lines of code:
simulation_results_cortex = FASTANS.simnibs_accelerated_simulations_cortex(search_grid_coarse,
                                                                           coil_filepath,
                                                                           didt,
                                                                           m2m_folderpath,
                                                                           os.path.join(output_folderpath, 'SimNIBS', 'SearchGrid', 'Step1_coarse'),
                                                                           surface_midthickness_left_filepath,
                                                                           surface_midthickness_right_filepath)

best_coil_placements = FASTANS.extract_best_coil_placements_hotspot(simulation_results_cortex,
                                                                    search_grid_coarse,
                                                                    hotspot_percentiles,
                                                                    FCmap_filepath,
                                                                    target_ids,
                                                                    avoidance_ids,
                                                                    n_placements,
                                                                    surface_midthickness_left_filepath,
                                                                    surface_midthickness_right_filepath)

target_coordinates = best_coil_placements[0][0:3, 3]

search_grid_fine = FASTANS.generate_search_grid(m2m_folderpath,
                                                os.path.join(output_folderpath, 'SimNIBS', 'SearchGrid', 'Step2_fine'),
                                                target_coordinates,
                                                coil_scalp_distance,
                                                15,  # radius
                                                5,   # resolution
                                                10,  # angle resolution
                                                [-90, 80])

Screenshot from 2025-08-30 19-56-03 Screenshot from 2025-08-30 19-56-11
  1. Final E-field simulation. This output is generated using the following lines of code:
simulation_results_cortex = FASTANS.simnibs_accelerated_simulations_cortex(search_grid_fine,
                                                                           coil_filepath,
                                                                           didt,
                                                                           m2m_folderpath,
                                                                           os.path.join(output_folderpath, 'SimNIBS', 'SearchGrid', 'Step2_fine'),
                                                                           surface_midthickness_left_filepath,
                                                                           surface_midthickness_right_filepath)

best_coil_placements = FASTANS.extract_best_coil_placements_hotspot(simulation_results_cortex,
                                                                    search_grid_fine,
                                                                    hotspot_percentiles,
                                                                    FCmap_filepath,
                                                                    target_ids,
                                                                    avoidance_ids,
                                                                    n_placements,
                                                                    surface_midthickness_left_filepath,
                                                                    surface_midthickness_right_filepath)

FASTANS.run_final_simulation(output_foldername,
                             best_coil_placements,
                             m2m_folderpath,
                             coil_filepath,
                             coil_scalp_distance,
                             didt,
                             os.path.join(output_folderpath, 'SimNIBS', 'Simulations'),
                             surface_midthickness_left_filepath,
                             surface_midthickness_right_filepath)
Screenshot from 2025-08-30 19-56-25

Optional: If you want to generate the individual functional network parcellation yourself, run the following lines of code after adjusting paths according to your download path of the example data:

# Full path to output folder
output_folderpath = '/.../FASTANS/resources/example_data/PFM'

# Preprocessed functional (resting-state) timecourses (.dtseries.nii file; 32k_fs_LR space)
functional_data_filepath = '/.../FASTANS/resources/example_data/data/func/processed_restingstate_timecourses.dtseries.nii'

# Subject midthickness surfaces (.surf.gii files; 32k_fs_LR space)
surface_midthickness_left_filepath = '/.../FASTANS/resources/example_data/data/anat/midthickness_surface_left.32k_fs_LR.surf.gii'
surface_midthickness_right_filepath = '/.../FASTANS/resources/example_data/data/anat/midthickness_surface_right.32k_fs_LR.surf.gii'

# Lynch 2024 parcellation
FASTANS.fast_pfm(functional_data_filepath,
                 'Lynch2024',
                 output_folderpath,
                 surface_midthickness_left_filepath,
                 surface_midthickness_right_filepath)

About

A Python package for Fast Targeted Functional Network Stimulation (FASTANS).

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages