Atlas Workflow#

Cohort-level workflow that aggregates normalized tractography outputs into a statistical atlas and can optionally run post-atlas QC.

thesis.workflows.atlas#

Statistical Atlas Generation Workflow.

This is a cohort-level workflow that aggregates patient data.

Registration of the atlas workflow happens inside .workflow via the @workflow decorator; importing this package triggers that registration.

thesis.workflows.atlas.workflow#

Nipype workflow definition for the Atlas generator.

thesis.workflows.atlas.workflow.verify_requirements(config, context)[source]#

Verify cohort output directory exists.

Parameters:
Return type:

List[str]

thesis.workflows.atlas.workflow.build_workflow(*, atlas_dir, config, context)[source]#

Build the cohort-level atlas workflow.

Parameters:
Return type:

Workflow

Atlas internals#

Atlas generation — orchestration layer.

This module provides the main entry point for generating statistical atlases from cohort tractography data using numpy for computation.

Key features: - Full cohort stack loaded via nibabel and stacked into a (n_subjects, X, Y, Z) array - Vectorised statistics computation via NumPy (mean, std, cov, prob_threshold)

thesis.workflows.atlas.compute.generate_statistical_atlas(output_dir, atlas_dir, params, tractography_relpath='tractography/probtrackx2')[source]#

Generate a statistical reference atlas from cohort tractography data.

Discovers all patient warped fdt_paths.nii.gz files, normalises them using the configured method (waytotal, max, or softmax), stacks them into a (n_subjects, X, Y, Z) array, and computes five essential statistics: mean, std, std_error, cov, and prob_threshold using vectorised NumPy operations.

Parameters:
  • output_dir (str) – Base output directory containing patient subdirectories.

  • atlas_dir (str) – Directory where atlas NIfTI files will be saved.

  • params (AtlasParams) – Runtime parameters including normalization method and thresholds.

  • tractography_relpath (str) – Relative path under each patient directory where tractography output lives.

Return type:

List[str]

Returns:

List of absolute paths to the generated NIfTI files.

Raises:

ValueError – If no valid patient data is found.

class thesis.workflows.atlas.compute.QcParams[source]#

Bases: object

Runtime parameters for the atlas QC pass.

Mirrors the per-field inputs of thesis.workflows.atlas._qc.generate_atlas_qc() so the merged single-pass atlas+QC computation can forward them unchanged.

Variables:
  • subject_density_threshold – Intensity threshold used to binarize maps.

  • group_core_threshold – Occupancy threshold [0, 1] for the group core mask.

  • leave_one_out – Whether to compute leave-one-out Dice summaries.

  • leave_one_out_min_subjects – Minimum subjects required for leave-one-out.

  • compute_cv – Whether to compute a voxelwise coefficient of variation map.

  • cv_mean_threshold – Mean threshold applied when computing the CV map.

  • compute_log_stats – Whether to compute log-space summary metrics.

  • log_offset – Positive offset added before log-transform summaries.

  • qc_subdir – Subdirectory name under output_dir for QC artefacts.

Parameters:
  • subject_density_threshold (float)

  • group_core_threshold (float)

  • leave_one_out (bool)

  • leave_one_out_min_subjects (int)

  • compute_cv (bool)

  • cv_mean_threshold (float)

  • compute_log_stats (bool)

  • log_offset (float)

  • qc_subdir (str)

subject_density_threshold: float#
group_core_threshold: float#
leave_one_out: bool#
leave_one_out_min_subjects: int#
compute_cv: bool#
cv_mean_threshold: float#
compute_log_stats: bool#
log_offset: float#
qc_subdir: str = 'atlas_qc'#
__init__(subject_density_threshold, group_core_threshold, leave_one_out, leave_one_out_min_subjects, compute_cv, cv_mean_threshold, compute_log_stats, log_offset, qc_subdir='atlas_qc')#
Parameters:
  • subject_density_threshold (float)

  • group_core_threshold (float)

  • leave_one_out (bool)

  • leave_one_out_min_subjects (int)

  • compute_cv (bool)

  • cv_mean_threshold (float)

  • compute_log_stats (bool)

  • log_offset (float)

  • qc_subdir (str)

Return type:

None

thesis.workflows.atlas.compute.generate_atlas_with_qc(output_dir, atlas_dir, params, qc_params=None, qc_output_dir=None, tractography_relpath='tractography/probtrackx2')[source]#

Generate the statistical atlas and (optionally) QC in a single pass.

The cohort is discovered, normalised, and stacked into a single (n_subjects, X, Y, Z) array exactly once. Both the statistical-atlas outputs and the QC outputs are derived from that one in-memory stack, avoiding the redundant collect/stack/mean-std that the separate atlas and QC nodes previously performed. Only one stack is held in RAM at a time.

Every output file (atlas statistics, occupancy, core mask, optional CV map, and the QC JSON summary) is written to the same paths with the same numeric values as the previous two-node implementation.

Parameters:
  • output_dir (str) – Base output directory containing patient subdirectories (the cohort discovery root).

  • atlas_dir (str) – Directory where atlas NIfTI files will be saved.

  • params (AtlasParams) – Atlas runtime parameters (normalization, thresholds).

  • qc_params (Optional[QcParams]) – Optional QC runtime parameters. When None, QC is skipped and only the statistical atlas is produced.

  • qc_output_dir (Optional[str]) – Base directory under which the QC subdirectory is created. Required when qc_params is provided.

  • tractography_relpath (str) – Relative path under each patient directory where tractography output lives.

Return type:

List[str]

Returns:

List of absolute paths to all generated NIfTI/JSON files (atlas first, then QC outputs when QC is enabled).

Raises:

ValueError – If no valid patient data is found, or if qc_params is supplied without qc_output_dir.

Constants and runtime parameter dataclass for the atlas workflow.

Simplified to compute only essential statistics: mean, std, std_error, cov, prob_threshold.

thesis.workflows.atlas._params.DEFAULT_PRESENCE_VALUE: float = 0.1#

Default presence threshold fraction.

A voxel is considered ‘present’ when its normalised density exceeds this value. With waytotal normalization, 0.10 means the voxel must carry at least 10% of the total streamline count to be counted as present in prob_threshold.

thesis.workflows.atlas._params.DEFAULT_NORMALIZATION_METHOD: NormalizationMethod = NormalizationMethod.WAYTOTAL#

Default normalization method for streamline density volumes.

thesis.workflows.atlas._params.DEFAULT_COV_MEAN_THRESHOLD_PCT: float = 0.01#

Default atlas mean threshold fraction for CV computation.

CV is computed only where the voxel mean exceeds this fraction of the global maximum of the atlas mean map. Lower-signal voxels are set to 0.

class thesis.workflows.atlas._params.AtlasParams[source]#

Bases: object

Runtime parameters for atlas generation.

Variables:
  • presence_value – Threshold for prob_threshold calculation.

  • cov_mean_threshold_pct – Global atlas mean threshold fraction used to suppress low-signal voxels when computing cov.

  • normalization_method – Method for normalizing streamline volumes before combining (waytotal, max, or softmax).

Parameters:
__init__(presence_value=0.1, cov_mean_threshold_pct=0.01, normalization_method=NormalizationMethod.WAYTOTAL)#
Parameters:
Return type:

None

presence_value: float = 0.1#
cov_mean_threshold_pct: float = 0.01#
normalization_method: NormalizationMethod = 'waytotal'#

Numpy-based atlas statistics computation.

Computes five essential statistics over a cohort of patient tractography volumes: - mean: Average connectivity across all subjects - std: Standard deviation across all subjects - std_error: Standard error of the mean (std / sqrt(n)) - cov: Coefficient of variation (std / mean) for sufficiently strong mean signal - prob_threshold: Percentage of subjects where voxel exceeds presence threshold

thesis.workflows.atlas._statistics.compute_atlas_statistics(data, presence_value=0.1, cov_mean_threshold_pct=0.01)[source]#

Compute all atlas statistics from a stacked patient array.

Parameters:
  • data (ndarray) – Numpy array of shape (n_subjects, X, Y, Z) with normalised values.

  • presence_value (float) – Threshold for prob_threshold calculation. A voxel is counted as ‘present’ when its value exceeds this threshold.

  • cov_mean_threshold_pct (float) – Fraction of the global atlas mean maximum used to suppress low-signal voxels when computing cov.

Return type:

dict[str, ndarray]

Returns:

Dict mapping statistic names to numpy arrays, each of shape (X, Y, Z).

Example

>>> stats = compute_atlas_statistics(
...     patient_stack,
...     presence_value=0.10,
...     cov_mean_threshold_pct=0.01,
... )
>>> mean_map = stats["mean"]

Reusable pure QC metrics for tractography atlas evaluation.

These helpers operate on in-memory subject masks or tractography volumes and do not depend on workflow orchestration or reference-atlas comparisons.

thesis.workflows.atlas.qc_metrics.build_occupancy_map(subject_masks)[source]#

Compute voxelwise occupancy fraction across subjects.

Parameters:

subject_masks (ndarray) – Boolean-like array of shape (n_subjects, X, Y, Z[, ...]).

Return type:

ndarray

Returns:

Float occupancy map in the range [0.0, 1.0].

Raises:

ValueError – If the input stack is empty or has invalid dimensionality.

thesis.workflows.atlas.qc_metrics.threshold_core_mask(occupancy_map, threshold)[source]#

Create a group core mask by thresholding occupancy.

Parameters:
  • occupancy_map (ndarray) – Voxelwise occupancy map with values typically in [0.0, 1.0].

  • threshold (float) – Inclusive occupancy threshold for membership in the core mask.

Return type:

ndarray

Returns:

Boolean core mask.

Raises:

ValueError – If the threshold is outside [0.0, 1.0].

thesis.workflows.atlas.qc_metrics.dice_score(mask_a, mask_b, empty_value=1.0)[source]#

Compute the Dice similarity coefficient between two masks.

Parameters:
  • mask_a (ndarray) – First boolean-like mask.

  • mask_b (ndarray) – Second boolean-like mask with identical shape.

  • empty_value (float) – Value returned when both masks are empty.

Return type:

float

Returns:

Dice coefficient in the range [0.0, 1.0].

Raises:

ValueError – If mask shapes do not match.

thesis.workflows.atlas.qc_metrics.compute_subject_dice_against_core(subject_masks, core_threshold, core_mask=None)[source]#

Compute per-subject Dice scores against a group core mask.

Parameters:
  • subject_masks (ndarray) – Boolean-like array of shape (n_subjects, X, Y, Z[, ...]).

  • core_threshold (float) – Inclusive occupancy threshold used to define the group core. Ignored when core_mask is supplied.

  • core_mask (Optional[ndarray]) – Optional precomputed group core mask of shape subject_masks.shape[1:]. When provided, the occupancy map and core mask are not rebuilt, avoiding a duplicate full-stack reduction.

Return type:

ndarray

Returns:

One Dice score per subject.

Raises:

ValueError – If the input stack is invalid or the threshold is out of range.

thesis.workflows.atlas.qc_metrics.compute_leave_one_out_dice(subject_masks, core_threshold, minimum_subjects=2)[source]#

Compute leave-one-out Dice scores against cohort cores.

For each subject, the comparison core is rebuilt from all remaining subjects.

Parameters:
  • subject_masks (ndarray) – Boolean-like array of shape (n_subjects, X, Y, Z[, ...]).

  • core_threshold (float) – Inclusive occupancy threshold used to define each leave-one-out core.

  • minimum_subjects (int) – Minimum cohort size required for leave-one-out evaluation.

Return type:

ndarray

Returns:

One leave-one-out Dice score per subject.

Raises:

ValueError – If the input stack is invalid, the threshold is out of range, or there are fewer than minimum_subjects subjects.

thesis.workflows.atlas.qc_metrics.compute_map_coefficient_of_variation(value_maps, mean_threshold=0.0)[source]#

Compute voxelwise coefficient of variation across subjects.

Parameters:
  • value_maps (ndarray) – Numeric array of shape (n_subjects, X, Y, Z[, ...]).

  • mean_threshold (float) – Minimum mean required before reporting non-zero variation.

Return type:

ndarray

Returns:

Float voxelwise coefficient of variation map.

Raises:

ValueError – If the input stack is empty, has invalid dimensionality, or if mean_threshold is negative.

thesis.workflows.atlas.qc_metrics.summarize_dice_scores(dice_scores, leave_one_out_scores=None)[source]#

Summarize Dice-based QC scores for lightweight reporting.

Parameters:
  • dice_scores (ndarray) – Per-subject Dice scores against the group core.

  • leave_one_out_scores (Optional[ndarray]) – Optional leave-one-out Dice scores.

Return type:

dict[str, float]

Returns:

Dictionary with summary statistics suitable for logs or reports.

Raises:

ValueError – If any provided score array is empty.