Skip to content

config

tit.stats.config

Configuration and result dataclasses for cluster-based permutation testing.

Pure Python -- no numpy, nibabel, pandas or other heavy dependencies; the participant CSV loaders read with the standard :mod:csv module. Mirrors the tit.opt.config / tit.sim.config pattern.

Public API

GroupComparisonConfig Configuration for two-group cluster-based permutation testing. GroupComparisonResult Result container for group comparison analysis. CorrelationConfig Configuration for correlation-based cluster permutation testing. CorrelationResult Result container for correlation analysis.

See Also

tit.stats.permutation : Orchestration functions that consume these configs.

GroupComparisonConfig dataclass

GroupComparisonConfig(analysis_name: str, subjects: list[Subject], test_type: TestType = UNPAIRED, alternative: Alternative = TWO_SIDED, cluster_threshold: float = 0.05, cluster_stat: ClusterStat = MASS, n_permutations: int = 1000, alpha: float = 0.05, n_jobs: int = -1, seed: int | None = None, tissue_type: TissueType = GREY, nifti_file_pattern: str | None = None, space: AnalysisSpace = MNI, fsaverage_field: str = 'TI_max', fsaverage_spacing: int = 5, group1_name: str = 'Responders', group2_name: str = 'Non-Responders', value_metric: str = 'Electric Field Magnitude', atlas_files: list[str] = list())

Configuration for cluster-based permutation testing between two groups.

Compares voxelwise field intensities between responders and non-responders using a t-test with cluster-based permutation correction for multiple comparisons.

Attributes

analysis_name : str Human-readable name for this analysis run. subjects : list of Subject Subject entries, each labelled as responder (1) or non-responder (0). test_type : TestType or str "unpaired" (default) or "paired" t-test. Strings are coerced to :class:TestType. alternative : Alternative or str Sidedness: "two-sided" (default), "greater" or "less". cluster_threshold : float Uncorrected p-value threshold for forming clusters. Default 0.05. cluster_stat : ClusterStat or str Cluster-level statistic used for permutation testing, "mass" (default) or "size". n_permutations : int Number of permutations for the null distribution. Default 1000; the smallest reportable p-value is 1 / (n + 1). alpha : float Family-wise error rate for significance. Default 0.05. n_jobs : int Number of parallel workers (-1, the default, for the global CPU limit -- :func:tit.cpu.cpu_limit; larger values are clamped to it). seed : int or None Seed of the permutation generator; None (default) draws a fresh one. Either way the seed used is written in the run's summary (analysis_summary.txt; surface_stats.json for fsaverage). tissue_type : TissueType or str Which tissue compartment to analyze: "grey" (default), "white" or "all". Ignored when space is "fsaverage". nifti_file_pattern : str or None Filename pattern for subject NIfTI files, with a {simulation_name} placeholder. If None (default), derived from tissue_type, e.g. "grey_{simulation_name}_TI_MNI_MNI_TI_max.nii.gz". space : AnalysisSpace or str Where the statistics run: "mni" (default, voxelwise on the MNI-space NIfTIs) or "fsaverage" (vertexwise on the per-subject fsaverage projections written by the simulator). fsaverage_field : str Surface field for space="fsaverage"; one of :data:tit.constants.FSAVG_FIELD_NAMES ("TI_max", "TI_normal", "hf_peak", "hf_rms"). Default "TI_max". fsaverage_spacing : int fsaverage ico spacing for space="fsaverage": 5 (default), 6 or 7. group1_name : str Display label for the responder group. Default "Responders". group2_name : str Display label for the non-responder group. Default "Non-Responders". value_metric : str Label for the field values in the summary. Default "Electric Field Magnitude". atlas_files : list of str Atlas filenames for overlap analysis (looked up in the bundled atlas directory). Default empty.

Raises

ValueError If subjects lacks at least one responder and one non-responder, if a response is not 0 or 1, if a paired test has unequal group sizes, if alpha or cluster_threshold is not strictly between 0 and 1, if n_permutations is not a whole number or is below floor(1 / alpha) (20 at alpha 0.05: with fewer, no p-value could fall below alpha), if a string value is not a member of its enum, or if fsaverage_field/fsaverage_spacing are invalid for space="fsaverage".

Examples

from tit.stats import GroupComparisonConfig subjects = [ ... GroupComparisonConfig.Subject("ernie", "L_Insula", response=1), ... GroupComparisonConfig.Subject("101", "L_Insula", response=0), ... ] cfg = GroupComparisonConfig( ... analysis_name="active_vs_sham", subjects=subjects, ... test_type="unpaired", alternative="two-sided", ... cluster_stat="mass", n_permutations=1000, tissue_type="grey", ... ) cfg.test_type is GroupComparisonConfig.TestType.UNPAIRED True cfg.nifti_file_pattern 'grey_{simulation_name}_TI_MNI_MNI_TI_max.nii.gz'

Subjects can also come from a CSV with columns subject_id, simulation_name, response:

subjects = GroupComparisonConfig.load_subjects("subjects.csv") # doctest: +SKIP

See Also

GroupComparisonResult : Result container returned by the analysis. run_group_comparison : Orchestration function that consumes this config.

TestType

Bases: StrEnum

Type of statistical test for group comparison.

Attributes

UNPAIRED : str "unpaired" -- independent-samples t-test. PAIRED : str "paired" -- paired-samples t-test (groups must be the same size and ordered pairwise).

Alternative

Bases: StrEnum

Sidedness of the test hypothesis.

Attributes

TWO_SIDED : str "two-sided". GREATER : str "greater" -- responders > non-responders. LESS : str "less" -- responders < non-responders.

Subject dataclass

Subject(subject_id: str, simulation_name: str, response: int)

A single subject in a group comparison analysis.

Attributes

subject_id : str Subject identifier (without sub- prefix). simulation_name : str Name of the simulation to load for this subject. response : int Group label -- 1 for responder, 0 for non-responder.

load_subjects classmethod

load_subjects(csv_path: str) -> list[Subject]

Load group comparison subjects from a CSV file.

Expected columns: subject_id, simulation_name, response (0 or 1). The sub- prefix is stripped from subject IDs automatically.

Parameters

csv_path : str Path to a CSV file with the required columns.

Returns

list of Subject Subject instances parsed from the CSV rows.

Raises

ValueError If required columns are missing, or a row lacks one of their values.

Source code in tit/stats/config.py
@classmethod
def load_subjects(cls, csv_path: str) -> list["GroupComparisonConfig.Subject"]:
    """Load group comparison subjects from a CSV file.

    Expected columns: ``subject_id``, ``simulation_name``, ``response``
    (0 or 1).  The ``sub-`` prefix is stripped from subject IDs
    automatically.

    Parameters
    ----------
    csv_path : str
        Path to a CSV file with the required columns.

    Returns
    -------
    list of Subject
        Subject instances parsed from the CSV rows.

    Raises
    ------
    ValueError
        If required columns are missing, or a row lacks one of their values.
    """
    subjects = []
    for line, row in _read_participant_rows(
        csv_path, {"subject_id", "simulation_name", "response"}
    ):
        if None in (row["subject_id"], row["simulation_name"], row["response"]):
            raise ValueError(
                f"CSV row {line}: subject_id, simulation_name and response are "
                "all required"
            )
        subjects.append(
            cls.Subject(
                subject_id=_participant_id(row["subject_id"]),
                simulation_name=row["simulation_name"],
                response=int(float(row["response"])),
            )
        )
    return subjects

CorrelationConfig dataclass

CorrelationConfig(analysis_name: str, subjects: list[Subject], correlation_type: CorrelationType = PEARSON, cluster_threshold: float = 0.05, cluster_stat: ClusterStat = MASS, n_permutations: int = 1000, alpha: float = 0.05, n_jobs: int = -1, seed: int | None = None, use_weights: bool = True, tissue_type: TissueType = GREY, nifti_file_pattern: str | None = None, space: AnalysisSpace = MNI, fsaverage_field: str = 'TI_max', fsaverage_spacing: int = 5, effect_metric: str = 'Effect Size', field_metric: str = 'Electric Field Magnitude', atlas_files: list[str] = list())

Configuration for correlation-based cluster permutation testing.

Tests voxelwise correlation between brain field intensities and a continuous behavioral or clinical measure (effect size) across subjects, with cluster-based permutation correction for multiple comparisons.

Attributes

analysis_name : str Human-readable name for this analysis run. subjects : list of Subject Subject entries with associated effect sizes. correlation_type : CorrelationType Pearson or Spearman rank correlation. cluster_threshold : float Uncorrected p-value threshold for forming clusters. cluster_stat : ClusterStat Cluster-level statistic used for permutation testing ("mass" or "size"). n_permutations : int Number of permutations for the null distribution. alpha : float Family-wise error rate for significance. n_jobs : int Number of parallel workers (-1 for the global CPU limit -- :func:tit.cpu.cpu_limit; larger values are clamped to it). seed : int or None Seed of the permutation generator; see :class:GroupComparisonConfig. use_weights : bool Whether to apply per-subject weights during correlation. Default True. tissue_type : TissueType or str Which tissue compartment to analyze: "grey" (default), "white" or "all". nifti_file_pattern : str or None Filename pattern for subject NIfTI files. If None, derived automatically from tissue_type. space : AnalysisSpace or str "mni" (default) or "fsaverage"; see :class:GroupComparisonConfig. fsaverage_field : str Surface field for space="fsaverage". Default "TI_max". fsaverage_spacing : int fsaverage ico spacing (5, 6 or 7). Default 5. effect_metric : str Label for the behavioral/clinical variable in plots. field_metric : str Label for the field intensity axis in plots. atlas_files : list of str Atlas filenames for overlap analysis (looked up in the bundled atlas directory).

Raises

ValueError If fewer than 3 subjects are given, if an effect size is not a finite number or every effect size is equal (the correlation is undefined), if use_weights is on and a weight is not a positive finite number, or for the alpha/cluster_threshold/ n_permutations rules of :class:GroupComparisonConfig.

See Also

CorrelationResult : Result container returned by the analysis. run_correlation : Orchestration function that consumes this config.

CorrelationType

Bases: StrEnum

Type of correlation coefficient to compute.

Subject dataclass

Subject(subject_id: str, simulation_name: str, effect_size: float, weight: float = 1.0)

A single subject in a correlation analysis.

Attributes

subject_id : str Subject identifier (without sub- prefix). simulation_name : str Name of the simulation to load for this subject. effect_size : float Continuous behavioral or clinical measure to correlate with field intensity. weight : float Per-subject weight (default 1.0).

load_subjects classmethod

load_subjects(csv_path: str) -> list[Subject]

Load correlation subjects from a CSV file.

Expected columns: subject_id, simulation_name, effect_size. Optional column: weight. Rows with NaN subject_id or effect_size are silently skipped. The sub- prefix is stripped from subject IDs automatically.

Parameters

csv_path : str Path to a CSV file with the required columns.

Returns

list of Subject Subject instances parsed from valid CSV rows.

Raises

ValueError If required columns are missing, a kept row has no simulation_name, or no valid subjects are found.

Source code in tit/stats/config.py
@classmethod
def load_subjects(cls, csv_path: str) -> list["CorrelationConfig.Subject"]:
    """Load correlation subjects from a CSV file.

    Expected columns: ``subject_id``, ``simulation_name``,
    ``effect_size``.  Optional column: ``weight``.  Rows with NaN
    ``subject_id`` or ``effect_size`` are silently skipped.  The ``sub-``
    prefix is stripped from subject IDs automatically.

    Parameters
    ----------
    csv_path : str
        Path to a CSV file with the required columns.

    Returns
    -------
    list of Subject
        Subject instances parsed from valid CSV rows.

    Raises
    ------
    ValueError
        If required columns are missing, a kept row has no simulation_name, or
        no valid subjects are found.
    """
    subjects = []
    for line, row in _read_participant_rows(
        csv_path, {"subject_id", "simulation_name", "effect_size"}
    ):
        if row["subject_id"] is None or row["effect_size"] is None:
            continue
        if row["simulation_name"] is None:
            raise ValueError(f"CSV row {line}: simulation_name is required")
        weight = row.get("weight")
        subjects.append(
            cls.Subject(
                subject_id=_participant_id(row["subject_id"]),
                simulation_name=row["simulation_name"],
                effect_size=float(row["effect_size"]),
                weight=1.0 if weight is None else float(weight),
            )
        )

    if not subjects:
        raise ValueError("No valid subjects found in CSV")
    return subjects

GroupComparisonResult dataclass

GroupComparisonResult(success: bool, output_dir: str, n_responders: int, n_non_responders: int, n_significant_voxels: int, n_significant_clusters: int, cluster_threshold: float, analysis_time: float, clusters: list, log_file: str)

Result of a group comparison permutation test.

Attributes

success : bool Whether the analysis completed without error. output_dir : str Absolute path to the directory containing all outputs (NIfTI maps, plots, summary text, log). n_responders : int Number of responder subjects included. n_non_responders : int Number of non-responder subjects included. n_significant_voxels : int Total voxels surviving cluster-corrected threshold. n_significant_clusters : int Number of spatially contiguous clusters that survived permutation correction. cluster_threshold : float Cluster-level statistic threshold derived from the permutation null distribution at the requested alpha. analysis_time : float Wall-clock duration of the full analysis in seconds. clusters : list of dict One entry per significant cluster, containing size, mass, peak coordinates, and atlas overlap info. log_file : str Absolute path to the analysis log file.

See Also

GroupComparisonConfig : Configuration that produced this result. run_group_comparison : Function that returns this result.

CorrelationResult dataclass

CorrelationResult(success: bool, output_dir: str, n_subjects: int, n_significant_voxels: int, n_significant_clusters: int, cluster_threshold: float, analysis_time: float, clusters: list, log_file: str)

Result of a correlation-based cluster permutation test.

Attributes

success : bool Whether the analysis completed without error. output_dir : str Absolute path to the directory containing all outputs (NIfTI maps, plots, summary text, log). n_subjects : int Number of subjects included in the analysis. n_significant_voxels : int Total voxels surviving cluster-corrected threshold. n_significant_clusters : int Number of spatially contiguous clusters that survived permutation correction. cluster_threshold : float Cluster-level statistic threshold derived from the permutation null distribution at the requested alpha. analysis_time : float Wall-clock duration of the full analysis in seconds. clusters : list of dict One entry per significant cluster, containing size, mass, peak coordinates, mean/peak correlation coefficients, and atlas overlap info. log_file : str Absolute path to the analysis log file.

See Also

CorrelationConfig : Configuration that produced this result. run_correlation : Function that returns this result.