Skip to content

Getting Started

This guide covers the core APIs you'll interact with most frequently.

Initialization

Every TI-Toolbox session starts with logging setup and path management:

from tit import init, add_file_handler, get_path_manager

# Configure logging with terminal output (or use setup_logging for file-only)
init("INFO")

# Initialize the path manager singleton (BIDS-compliant paths)
pm = get_path_manager("/data/my_project")

# Access BIDS paths directly
mesh_path = pm.m2m("001")              # -> .../derivatives/SimNIBS/sub-001/m2m_001/
sims_path = pm.simulations("001")      # -> .../derivatives/SimNIBS/sub-001/Simulations/

Running Simulations

Configure and Run

from tit.sim import (
    SimulationConfig, Montage,
    run_simulation, load_montages,
)

# Load montages from the project's montage_list.json
montages = load_montages(
    montage_names=["motor_cortex"],
    project_dir="/data/my_project",
    eeg_net="GSN-HydroCel-185",
)

# Configure the simulation (montages are part of the config)
config = SimulationConfig(
    subject_id="001",
    project_dir="/data/my_project",
    montages=montages,
    conductivity="scalar",
    intensities=[1.0, 1.0],
    electrode_shape="ellipse",
    electrode_dimensions=[8.0, 8.0],
    gel_thickness=4.0,
)

# Run (auto-detects TI vs mTI based on number of electrode pairs)
results = run_simulation(config)

Simulation Types

  • TI (2-pair): Standard temporal interference with 2 electrode pairs
  • mTI (4+ pairs): Multi-channel TI with N electrode pairs (binary-tree combination)

Mode is auto-detected from the montage: 2 pairs -> TI, 4+ pairs -> mTI.

Analyzing Results

from tit.analyzer import Analyzer

# Spherical ROI analysis
analyzer = Analyzer(subject_id="001", simulation="motor_cortex", space="mesh")
result = analyzer.analyze_sphere(
    center=(-42, -20, 55),
    radius=10,
    coordinate_space="MNI",
    visualize=True,
)

# Access metrics
print(f"ROI Mean:     {result.roi_mean:.4f} V/m")
print(f"ROI Max:      {result.roi_max:.4f} V/m")
print(f"Focality:     {result.roi_focality:.2f}")
print(f"GM Mean:      {result.gm_mean:.4f} V/m")
print(f"N elements:   {result.n_elements}")

# Cortical atlas ROI analysis
result = analyzer.analyze_cortex(atlas="DK40", region="precentral-lh")

Group Analysis

from tit.analyzer import run_group_analysis

group_result = run_group_analysis(
    subject_ids=["001", "002", "003"],
    simulation="motor_cortex",
    space="mesh",
    analysis_type="spherical",
    center=(-42, -20, 55),
    radius=10,
    coordinate_space="MNI",
    visualize=True,
)

# group_result.subject_results: dict of per-subject AnalysisResult
# group_result.summary_csv_path: path to group_summary.csv
# group_result.comparison_plot_path: path to comparison bar chart PDF

Optimization

Flex-Search (Differential Evolution)

from tit.opt import FlexConfig, run_flex_search

config = FlexConfig(
    subject_id="001",
    project_dir="/data/my_project",
    goal="mean",              # "mean", "max", or "focality"
    postproc="max_TI",        # "max_TI", "dir_TI_normal", "dir_TI_tangential"
    current_mA=1.0,
    electrode=FlexConfig.ElectrodeConfig(shape="ellipse", dimensions=[8.0, 8.0]),
    roi=FlexConfig.SphericalROI(x=-42, y=-20, z=55, radius=10, use_mni=True),
    eeg_net="GSN-HydroCel-185",
    n_multistart=3,
)

result = run_flex_search(config)
print(f"Best value: {result.best_value}")
print(f"Output: {result.output_folder}")
from tit.opt import ExConfig, run_ex_search

config = ExConfig(
    subject_id="001",
    project_dir="/data/my_project",
    leadfield_hdf="/path/to/leadfield.hdf5",
    roi_name="motor_roi",
    electrodes=ExConfig.PoolElectrodes(electrodes=["C3", "C4", "F3", "F4", "P3", "P4"]),
)

result = run_ex_search(config)
print(f"Combinations tested: {result.n_combinations}")
print(f"Results CSV: {result.results_csv}")

Statistical Testing

from tit.stats import GroupComparisonConfig, run_group_comparison

# Load subjects from CSV (classmethod on GroupComparisonConfig)
subjects = GroupComparisonConfig.load_subjects("/data/subjects.csv")

config = GroupComparisonConfig(
    project_dir="/data/my_project",
    analysis_name="responder_comparison",
    subjects=subjects,
    test_type="unpaired",
    n_permutations=5000,
    alpha=0.05,
    cluster_threshold=0.05,
)

result = run_group_comparison(config)
print(f"Significant clusters: {result.n_significant_clusters}")
print(f"Output: {result.output_dir}")

Preprocessing

from tit.pre import run_pipeline

exit_code = run_pipeline(
    project_dir="/data/my_project",
    subject_ids=["001", "002"],
    convert_dicom=True,
    run_recon=True,
    parallel_recon=True,
    parallel_cores=4,
    create_m2m=True,
    run_tissue_analysis=True,
)

Individual Steps

Each preprocessing step can also be called independently:

from tit.pre import (
    run_dicom_to_nifti,
    run_recon_all,
    run_charm,
    run_tissue_analysis,
    run_subcortical_segmentations,
    run_qsiprep,
    run_qsirecon,
    extract_dti_tensor,
    discover_subjects,
    check_m2m_exists,
)

# Discover subjects from sourcedata
subjects = discover_subjects("/data/my_project")

# Check if head mesh already exists
if not check_m2m_exists("/data/my_project", "001"):
    run_charm("/data/my_project", "001", logger=my_logger)

Report Generation

TI-Toolbox generates interactive HTML reports for simulations, flex-search results, and preprocessing runs.

Simulation Reports

from tit.reporting import SimulationReportGenerator

report = SimulationReportGenerator(
    project_dir="/data/my_project",
    simulation_session_id="motor_cortex",
    subject_id="001",
)
report.add_simulation_parameters(
    conductivity_type="scalar",
    simulation_mode="TI",
    eeg_net="GSN-HydroCel-185",
    intensity_ch1=1.0,
    intensity_ch2=1.0,
)
report.add_montage(
    montage_name="motor_cortex",
    electrode_pairs=[("C3", "C4"), ("F3", "F4")],
    montage_type="TI",
)
output_path = report.generate()
print(f"Report: {output_path}")

Flex-Search Reports

from tit.reporting import create_flex_search_report

# Generate from optimization data dict
output_path = create_flex_search_report(
    project_dir="/data/my_project",
    subject_id="001",
    data=optimization_data,  # dict with optimization results
    output_path="/data/my_project/derivatives/ti-toolbox/reports/flex_report.html",
)

Preprocessing Reports

from tit.reporting import create_preprocessing_report

output_path = create_preprocessing_report(
    project_dir="/data/my_project",
    subject_id="001",
    processing_steps=[],  # auto-populated if auto_scan=True
    output_path=None,     # auto-generates BIDS-compliant path
    auto_scan=True,
)

Report Building Blocks (Reportlets)

Reports are assembled from reusable reportlets:

from tit.reporting import (
    ReportAssembler,
    ReportMetadata,
    MetadataReportlet,
    ImageReportlet,
    TableReportlet,
    ConductivityTableReportlet,
    SummaryCardsReportlet,
    MethodsBoilerplateReportlet,
    TIToolboxReferencesReportlet,
)

# Create a custom report
metadata = ReportMetadata(title="My Analysis", subject_id="001")
assembler = ReportAssembler(metadata=metadata, title="Custom Report")

section = assembler.add_section("results", "Results", description="Analysis output")
cards = SummaryCardsReportlet(title="Key Metrics")
cards.add_card(label="ROI Mean", value="0.152 V/m", color="#4CAF50")
section.add_reportlet(cards)

assembler.save("/data/output/report.html")

Mesh and NIfTI Tools

Standalone utilities for working with simulation outputs:

from tit.tools.mesh2nii import convert_mesh_dir
from tit.tools.montage_visualizer import visualize_montage

# Convert all meshes in a directory to NIfTI (subject + MNI space)
convert_mesh_dir(
    mesh_dir="/data/sim_output/TI/mesh",
    output_dir="/data/sim_output/TI/niftis",
    m2m_dir="/data/derivatives/SimNIBS/sub-001/m2m_001",
)

# Visualize electrode montage on the scalp
visualize_montage(
    montage_name="motor_cortex",
    electrode_pairs=[["E030", "E020"], ["E095", "E070"]],
    eeg_net="GSN-HydroCel-185",
    output_dir="/data/output/montage_imgs",
    sim_mode="U",  # "U" for TI, "M" for mTI
)

Key Concepts

BIDS Compliance

All paths are managed by PathManager, which enforces a BIDS-compliant directory structure. You never construct paths manually.

Field Types

  • TI_max: Maximum TI envelope magnitude (2-pair simulations)
  • TI_normal: TI field component normal to the cortical surface
  • TI_Max: Multi-channel TI maximum envelope (4-pair mTI simulations, from binary-tree combination)

Coordinate Spaces

  • Subject space: Native coordinates aligned to the individual's head mesh
  • MNI space: Standard MNI152 coordinates (transformed via SimNIBS)

Analysis Spaces

  • Mesh (space="mesh"): Surface-based analysis on the cortical mesh (weighted by node areas)
  • Voxel (space="voxel"): Volume-based analysis on NIfTI data (weighted by voxel volumes)