Analysis¶
The analysis module evaluates simulation results by computing statistics within regions of interest (ROIs). It supports spherical and cortical atlas ROIs in both mesh and voxel space.
graph LR
FIELD([Field Data]) --> ANALYZER[Analyzer]
ROI([ROI Specification]) --> ANALYZER
ANALYZER --> STATS([ROI Statistics])
ANALYZER --> VIZ([Visualizations])
ANALYZER --> CSV([CSV Export])
style FIELD fill:#1a3a5c,stroke:#48a,color:#fff
style ROI fill:#1a3a5c,stroke:#48a,color:#fff
style ANALYZER fill:#2d5a27,stroke:#4a8,color:#fff
style STATS fill:#1a5c4a,stroke:#4a8,color:#fff
style VIZ fill:#1a5c4a,stroke:#4a8,color:#fff
style CSV fill:#1a5c4a,stroke:#4a8,color:#fff
Single-Subject Analysis¶
Spherical ROI¶
from tit.analyzer import Analyzer
analyzer = Analyzer(
subject_id="001",
simulation="motor_cortex",
space="mesh",
tissue_type="GM", # "GM", "WM", or "both" (voxel only; mesh always uses GM)
)
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"ROI Min: {result.roi_min:.4f} V/m")
print(f"Focality: {result.roi_focality:.2f}")
print(f"GM Mean: {result.gm_mean:.4f} V/m")
print(f"GM Max: {result.gm_max:.4f} V/m")
print(f"N elements: {result.n_elements}")
Cortical Atlas ROI¶
The region parameter accepts a single region name or a list of region names
whose masks are combined into one ROI.
result = analyzer.analyze_cortex(atlas="DK40", region="precentral-lh")
# Multiple regions combined into a single ROI
result = analyzer.analyze_cortex(atlas="DK40", region=["precentral-lh", "postcentral-lh"])
Analysis Spaces¶
| Space | Method | Description |
|---|---|---|
"mesh" |
Surface-based | Analysis on the cortical mesh, weighted by node areas |
"voxel" |
Volume-based | Analysis on NIfTI data, weighted by voxel volumes |
When to Use Each Space
Use mesh space for cortical targets where surface geometry matters (e.g., normal/tangential field components). Use voxel space for deep brain targets or when you need MNI-aligned volumetric analysis.
ROI Types¶
Define a sphere by center coordinates and radius. Works in both MNI and subject coordinate spaces.
Use a predefined cortical atlas parcellation (e.g., Desikan-Killiany DK40, HCP_MMP1). A single region or a list of regions can be provided.
Result Metrics¶
Each analysis returns an AnalysisResult dataclass with these fields:
| Field | Description |
|---|---|
field_name |
SimNIBS field name (e.g., "TI_max") |
region_name |
Human-readable ROI identifier |
space |
"mesh" or "voxel" |
analysis_type |
"spherical" or "cortical" |
roi_mean |
Weighted mean field intensity within the ROI |
roi_max |
Maximum field intensity within the ROI |
roi_min |
Minimum field intensity within the ROI |
roi_focality |
Ratio of ROI mean intensity to whole-tissue mean |
gm_mean |
Mean field intensity across all gray matter (or tissue) |
gm_max |
Maximum field intensity across all gray matter (or tissue) |
normal_mean |
Mean of the normal-component field in the ROI (mesh only, optional) |
normal_max |
Max of the normal-component field in the ROI (mesh only, optional) |
normal_focality |
Focality of the normal-component field (mesh only, optional) |
percentile_95 |
95th percentile of field intensity (area/volume-weighted) |
percentile_99 |
99th percentile of field intensity |
percentile_99_9 |
99.9th percentile of field intensity |
focality_50_area |
Area/volume (cm^2) above 50% of 99.9th percentile |
focality_75_area |
Area/volume (cm^2) above 75% of 99.9th percentile |
focality_90_area |
Area/volume (cm^2) above 90% of 99.9th percentile |
focality_95_area |
Area/volume (cm^2) above 95% of 99.9th percentile |
n_elements |
Number of mesh nodes or voxels in the ROI |
total_area_or_volume |
Total area (mm^2, mesh) or volume (mm^3, voxel) of the ROI |
Group Analysis¶
Compare results across multiple subjects:
from tit.analyzer import run_group_analysis
group_result = run_group_analysis(
subject_ids=["001", "002", "003"],
simulation="motor_cortex",
space="mesh",
tissue_type="GM",
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
The run_group_analysis function also supports cortical atlas ROIs:
group_result = run_group_analysis(
subject_ids=["001", "002", "003"],
simulation="motor_cortex",
space="mesh",
analysis_type="cortical",
atlas="DK40",
region="precentral-lh",
visualize=True,
)
Statistical Testing¶
For formal group comparisons (e.g., responders vs non-responders), use the tit.stats module:
from tit.stats import GroupComparisonConfig, run_group_comparison
# Load subjects from CSV (columns: subject_id, simulation_name, response)
subjects = GroupComparisonConfig.load_subjects("/data/my_project/subjects.csv")
config = GroupComparisonConfig(
analysis_name="responder_comparison",
subjects=subjects,
test_type=GroupComparisonConfig.TestType.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"Significant voxels: {result.n_significant_voxels}")
The tit.stats module also supports voxel-wise correlation analysis via
CorrelationConfig and run_correlation.
API Reference¶
tit.analyzer.analyzer.AnalysisResult
dataclass
¶
AnalysisResult(field_name: str, region_name: str, space: str, analysis_type: str, roi_mean: float, roi_max: float, roi_min: float, roi_focality: float, gm_mean: float, gm_max: float, normal_mean: float | None = None, normal_max: float | None = None, normal_focality: float | None = None, percentile_95: float | None = None, percentile_99: float | None = None, percentile_99_9: float | None = None, focality_50_area: float | None = None, focality_75_area: float | None = None, focality_90_area: float | None = None, focality_95_area: float | None = None, n_elements: int = 0, total_area_or_volume: float = 0.0)
Immutable container for ROI analysis statistics.
Returned by :meth:Analyzer.analyze_sphere and
:meth:Analyzer.analyze_cortex.
Attributes¶
field_name : str
Name of the field that was analyzed (e.g. "TI_max").
region_name : str
Human-readable ROI label.
space : str
"mesh" or "voxel".
analysis_type : str
"spherical" or "cortical".
roi_mean : float
Area/volume-weighted mean field value inside the ROI.
roi_max : float
Maximum field value inside the ROI.
roi_min : float
Minimum field value inside the ROI.
roi_focality : float
Ratio of ROI mean to whole-GM mean (> 1 means the ROI is stronger
than the GM average).
gm_mean : float
Mean field value across all positive GM elements.
gm_max : float
Maximum field value across all GM elements.
normal_mean : float or None
Weighted mean of the normal-component field in the ROI (mesh only;
None when unavailable).
normal_max : float or None
Maximum normal-component field in the ROI.
normal_focality : float or None
Normal-component focality ratio.
percentile_95 : float or None
95th percentile of the whole-GM field distribution.
percentile_99 : float or None
99th percentile of the whole-GM field distribution.
percentile_99_9 : float or None
99.9th percentile of the whole-GM field distribution.
focality_50_area : float or None
Area/volume (cm2/cm3) where the field exceeds 50 % of the 99.9th
percentile value.
focality_75_area : float or None
Same for 75 % threshold.
focality_90_area : float or None
Same for 90 % threshold.
focality_95_area : float or None
Same for 95 % threshold.
n_elements : int
Number of mesh nodes or voxels in the ROI mask.
total_area_or_volume : float
Total surface area (mm^2) or volume (mm^3) of positive-valued ROI
elements.
See Also¶
Analyzer : Single-subject field analyzer. GroupResult : Container for multi-subject group analysis.
tit.analyzer.analyzer.Analyzer ¶
Analyzer(subject_id: str, simulation: str, space: str = 'mesh', tissue_type: str = 'GM', output_dir: str | None = None)
Unified analyzer for mesh and voxel field data.
Lazily loads the field file on first analysis call. All coordinate transforms and ROI masking are handled internally.
Parameters¶
subject_id : str
Subject identifier (without sub- prefix).
simulation : str
Simulation (montage) folder name.
space : str, optional
"mesh" or "voxel". Default "mesh".
tissue_type : str, optional
"GM", "WM", or "both". Only affects voxel analyses;
mesh analyses always use the GM cortical surface. Default "GM".
output_dir : str or None, optional
Override output directory. If None, derived from PathManager.
Attributes¶
subject_id : str
Subject identifier.
simulation : str
Simulation folder name.
space : str
Analysis space ("mesh" or "voxel").
tissue_type : str
Normalised tissue selection ("GM", "WM", or "BOTH").
field_path : pathlib.Path
Resolved path to the field file.
field_name : str
Short name of the field (e.g. "TI_max").
m2m_path : str
Path to the subject's m2m_* directory.
output_dir : str or None
Output directory override, or None.
Examples¶
from tit.analyzer import Analyzer analyzer = Analyzer("001", "montage_bipolar", space="mesh") result = analyzer.analyze_sphere( ... center=(-30.0, -20.0, 50.0), radius=10.0, ... ) print(result.roi_mean, result.roi_focality)
See Also¶
AnalysisResult : Container for single-subject analysis outputs. run_group_analysis : Multi-subject group analysis.
Source code in tit/analyzer/analyzer.py
analyze_sphere ¶
analyze_sphere(center: tuple[float, float, float], radius: float, coordinate_space: str = 'subject', visualize: bool = False) -> AnalysisResult
Analyze a spherical ROI.
Parameters¶
center : tuple of float
(x, y, z) coordinates of the sphere centre.
radius : float
Radius in mm.
coordinate_space : str, optional
"subject" (default) or "MNI". When "MNI",
coordinates are transformed to subject space via SimNIBS
mni2subject_coords.
visualize : bool, optional
Generate overlay, histogram, and CSV artifacts.
Returns¶
AnalysisResult ROI and whole-GM statistics for the spherical region.
Raises¶
FileNotFoundError If the required field or surface mesh file does not exist.
See Also¶
analyze_cortex : Atlas-based cortical ROI analysis.
Source code in tit/analyzer/analyzer.py
analyze_cortex ¶
Analyze a cortical atlas region.
Parameters¶
atlas : str
Atlas name recognised by SimNIBS (e.g. "DK40",
"HCP_MMP1"), or an absolute path to an atlas NIfTI
(voxel mode only).
region : str or list of str
Region name within the atlas (e.g. "lh.cuneus"), or a
list of region names whose masks are unioned into a single
combined ROI. Bare names like "cuneus" expand to both
hemispheres in mesh mode.
visualize : bool, optional
Generate overlay, histogram, and CSV artifacts.
Returns¶
AnalysisResult ROI and whole-GM statistics for the cortical region.
Raises¶
KeyError If a region name cannot be resolved in the atlas. FileNotFoundError If the atlas or field file does not exist.
See Also¶
analyze_sphere : Spherical ROI analysis.
Source code in tit/analyzer/analyzer.py
tit.analyzer.group.GroupResult
dataclass
¶
GroupResult(subject_results: dict[str, AnalysisResult], summary_csv_path: Path, comparison_plot_path: Path | None)
Outcome of a multi-subject group analysis.
Attributes¶
subject_results : dict of str to AnalysisResult
Mapping of subject ID to its
:class:~tit.analyzer.analyzer.AnalysisResult.
summary_csv_path : pathlib.Path
Path to the summary CSV (one row per subject plus an AVERAGE row).
comparison_plot_path : pathlib.Path or None
Path to the 2x2 comparison bar-chart PDF, or None if plotting
failed.
See Also¶
run_group_analysis : Factory function that produces this result. AnalysisResult : Per-subject analysis container.
tit.analyzer.group.run_group_analysis ¶
run_group_analysis(subject_ids: list[str], simulation: str, space: str = 'mesh', tissue_type: str = 'GM', analysis_type: str = 'spherical', center: tuple[float, float, float] | None = None, radius: float | None = None, coordinate_space: str = 'subject', atlas: str | None = None, region: str | list[str] | None = None, visualize: bool = False, output_dir: str | Path | None = None) -> GroupResult
Run the same ROI analysis across multiple subjects and summarise.
Dispatches to analyze_sphere or analyze_cortex on each subject,
builds a summary CSV (with an AVERAGE row), and generates a 2x2
comparison bar-chart PDF.
Parameters¶
subject_ids : list of str
Subject identifiers (without sub- prefix).
simulation : str
Simulation (montage) folder name, shared by all subjects.
space : str, optional
"mesh" or "voxel". Default "mesh".
tissue_type : str, optional
"GM", "WM", or "both" (voxel only). Default "GM".
analysis_type : str, optional
"spherical" or "cortical". Default "spherical".
center : tuple of float or None, optional
(x, y, z) sphere centre; required when analysis_type is
"spherical".
radius : float or None, optional
Sphere radius in mm; required when analysis_type is
"spherical".
coordinate_space : str, optional
"subject" or "MNI" (spherical only). Default "subject".
atlas : str or None, optional
Atlas name (cortical only).
region : str, list of str, or None, optional
Region name or list of region names (cortical only).
visualize : bool, optional
Generate per-subject visualization artifacts. Default False.
output_dir : str, pathlib.Path, or None, optional
Override output directory. If None, derived from PathManager.
Returns¶
GroupResult Per-subject results, the summary CSV path, and the comparison plot path.
Raises¶
KeyError
If analysis_type is not "spherical" or "cortical".
See Also¶
Analyzer : Single-subject analyzer used internally per subject. GroupResult : Container for the returned outcomes.
Source code in tit/analyzer/group.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |