Skip to content

group

tit.analyzer.group

Multi-subject group analysis.

Runs per-subject ROI analyses in-process via :class:Analyzer, aggregates the results into a summary CSV with an AVERAGE row, and produces a 2x2 comparison bar-chart saved as PDF.

GroupResult dataclass

GroupResult(subject_results: dict[str, AnalysisResult], summary_csv_path: Path, comparison_plot_path: Path | None)

Outcome of a multi-subject group analysis.

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 subject_ids 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. Returns a :class:GroupResult.

Source code in tit/analyzer/group.py
def 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 *subject_ids* 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.  Returns a :class:`GroupResult`.
    """
    out = _resolve_output_dir(output_dir)

    # File handler so group analysis logs are persisted
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    log_file = out / f"group_analysis_{timestamp}.log"
    add_file_handler(log_file)

    logger.info(
        "Group analysis started: %d subjects, space=%s, type=%s",
        len(subject_ids),
        space,
        analysis_type,
    )

    dispatch: dict[str, callable] = {
        "spherical": lambda a: a.analyze_sphere(
            center=center,
            radius=radius,
            coordinate_space=coordinate_space,
            visualize=visualize,
        ),
        "cortical": lambda a: a.analyze_cortex(
            atlas=atlas,
            region=region,
            visualize=visualize,
        ),
    }
    analyze_fn = dispatch[analysis_type]

    results: dict[str, AnalysisResult] = {}
    for sid in subject_ids:
        logger.info("Analyzing subject %s", sid)
        results[sid] = analyze_fn(Analyzer(sid, simulation, space, tissue_type))

    df = _build_summary_df(results)
    csv_path = out / "group_summary.csv"
    df.to_csv(csv_path, index=False, float_format="%.3f")
    logger.info("Summary CSV written to %s", csv_path)

    plot_path = _generate_comparison_plot(df, out)
    logger.info("Comparison plot written to %s", plot_path)

    return GroupResult(
        subject_results=results,
        summary_csv_path=csv_path,
        comparison_plot_path=plot_path,
    )