neurocaps.analysis.CAP#

class CAP(parcel_approach=None, groups=None)[source]#

Co-Activation Patterns (CAPs) Class.

Performs k-means clustering for CAP identification, computes various temporal dynamics metrics (including counts, temporal fraction, persistence, transition frequency, and transition probability), provides multiple visualizations (such as heatmaps, outer products, correlation matrices, and cosine similarity radar plots that shows the network correspondence to both positive and negative CAP activations), and enables conversion of CAPs to NIfTI statistical maps.

Parameters:
  • parcel_approach (ParcelConfig, ParcelApproach, or str, default=None) –

    Specifies the parcellation approach for segmenting NifTI images into distinct regions-of-interests (ROIs). Supported parcellation aproaches includes “Schaefer”, “AAL”, and “Custom” (user-defined).

    The parcel_approach requires a nested dictionary with:

    • First Level Key: The parcellation name (e.g., “Schaefer”, “AAL”, “Custom”)

    • Second Level Keys (subkeys):

      • ”maps”: Mapping of regions to coordinates.

      • ”nodes”: Node definitions for each region.

      • ”regions”: List of anatomical region names (see “Custom Parcellations” in Notes section for detailed structure requirements).

    There are 3 valid input options for this parameter:

    • Use the initialization parameters from TimeseriesExtractor (e.g., n_rois, yeo_networks, resolution_mm for “Schaefer”, or version for “AAL”) to generate the above structure.

    • Provide a nested dictionary with the required structure (first level key of the parcellation name with subkeys - “maps”, “nodes”, and “regions”).

    • Load configuration from a pickle file containing the valid nested dictionary.

    Note: This parameter is required for several visualization functions in this class but can be set later using the parcel_approach property.

  • groups (dict[str, list[str]] or None, default=None) –

    A mapping of group names to unique subject IDs. If specified, then separate analyses are performed on groups (i.e., group-specific k-means models, group-specific visualization, etc). If None, then the analyses will be performed on all subjects and the default group name is “All Subjects”. The structure should be as follows:

    {
        "GroupName1": ["1", "2", "3"],
        "GroupName2": ["4", "5", "6"],
    }
    

Properties#

parcel_approach: ParcelApproach

A dictionary containing information about the parcellation. Can also be used as a setter, which accepts a dictionary or a dictionary saved as a pickle file. The structure is as follows:

# Structure of Schaefer
{
    "Schaefer":
    {
        "maps": "path/to/parcellation.nii.gz",
        "nodes": ["LH_Vis1", "LH_SomSot1", "RH_Vis1", "RH_SomSot1"],
        "regions": ["Vis", "SomSot"]
    }
}

# Structure of AAL
{
    "AAL":
    {
        "maps": "path/to/parcellation.nii.gz",
        "nodes": ["Precentral_L", "Precentral_R", "Frontal_Sup_L", "Frontal_Sup_R"],
        "regions": ["Precentral", "Frontal"]
    }
}

Refer to the example for “Custom” in the Note section below for the expected structure.

groups: dict[str, list[str]] or None:

A mapping of groups names to unique subject IDs.

subject_table: dict[str, str] or None

A dictionary generated when self.get_caps() is used. Operates as a lookup table that pairs each subject ID with the associated group. Also can be used as a setter. The structure is as follows.

{
    "Subject-ID": "GroupName",
    "Subject-ID": "GroupName",
}
n_clusters: int, list[int], or None

An integer or list of integers (if cluster_selection_method is not None) that was used for sklearn.cluster.KMeans in self.get_caps().

cluster_selection_method: str or None:

The cluster selection method used in self.get_caps() to identify the optimal number of clusters.

n_cores: int or None

Number of cores specified in self.get_caps() to use for multiprocessing with Joblib.

runs: int, list[int | str], or None

The run IDs specified in self.get_caps().

standardize: bool or None

A boolean denoting whether the features of the concatenated timeseries data are standardized if standardization was requested in self.get_caps().

means: dict[str, np.array] or None

A dictionary mapping groups to their associated NumPy array containing the means of each feature (ROI) if standardize is True in self.get_caps(). The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: 1 x ROIs
}
stdev: dict[str, np.array] or None

A dictionary mapping groups to their associated NumPy array containing the sample standard deviation of each feature (ROI) if standardize is True in self.get_caps(). The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: 1 x ROIs
}
concatenated_timeseries: dict[str, np.array] or None

A dictionary mapping each group to their associated concatenated NumPy array [(participants x TRs) x ROIs] when self.get_caps() is used. Note, if there are memory issues, del self.concatenated_timeseries can be used to delete property and have it only return None. The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: (participants x TRs) x ROIs
}
kmeans: dict[str, sklearn.cluster.KMeans] or None

A dictionary mapping group-specific sklearn.cluster.KMeans model to each group when self.get_caps() is used. If cluster_selection_method is used, the model stored in this property is the optimal k-means model. The structure is as follows:

{
    "GroupName": sklearn.cluster.KMeans,
}
caps: dict[str, dict[str, np.array]] or None

A dictionary mapping the cluster centroids, extracted from the k-means model, to each group after self.get_caps() is used. The structure is as follows:

{
    "GroupName": {
        "CAP-1": np.array([...]), # Shape: 1 x ROIs
        "CAP-2": np.array([...]), # Shape: 1 x ROIs
    }

}
cluster_scores: dict[str, str | dict[str, float]] or None

A dictionary mapping groups to the assessed cluster sizes and corresponding score of a specific cluster_selection_method available in self.get_caps(). The structure is as follows:

{
    "Cluster_Selection_Method": str,  # e.g., "elbow", "davies_bouldin", "silhouette", or "variance_ratio"
    "Scores": {
        "GroupName": {
            2: float,  # Score for 2 clusters
            3: float,  # Score for 3 clusters
            4: float,  # Score for 4 clusters
        },
    }
}
optimal_n_clusters: dict[str, int] or None

A dictionary mapping groups to their optimal cluster sizes if cluster_selection_method is not None in self.get_caps(). The structure is as follows:

{
    "GroupName": int,
}
variance_explained: dict[str, float] or None

A dictionary mapping groups to a float representing the total variance explained by their respective model stored in self.kmeans. The structure is as follows:

{
    "GroupName": float,
}
region_means: dict[str, dict[str, list[str] | np.array]] or None

A dictionary mapping group to their CAPs and corresponding NumPy array (1 x regions) containing the averaged value of each region or network if visual_scope set to “regions” in self.caps2plot(). The position of elements corresponds to the region in the “Regions” list (mean value at the 0th index corresponds to the region at the 0th index). The structure is as follows:

{
    "GroupName": {
        "Regions": [...],
        "CAP-1": np.array([...]), # Shape: 1 x regions
        "CAP-2": np.array([...]), # Shape: 1 x regions
    }

}

Changed in version 0.23.4: Replaces self.region_caps and adds the “Regions” key for each group. For backwards compatibility, self.region_caps, which doesn’t include the is the “Regions” key is still available.

outer_products: dict[str, dict[str, np.array]] or None

A dictionary mapping group to their CAPs and corresponding NumPy array (ROIs x ROIs) containing the outer product if plot_options set to “outer_product” self.caps2plot(). The structure is as follows:

{
    "GroupName": {
        "CAP-1": np.array([...]), # Shape: ROIs x ROIs
        "CAP-2": np.array([...]), # Shape: ROIs x ROIs
    }

}
cosine_similarity: dict[str, dict[str, list[str] | np.array]] or None

A dictionary mapping each group to their CAPs and their associated “High Amplitude” and “Low Amplitude” list containing the cosine similarities. Each group contains a “Regions” key, consisting of a list of regions or networks. The position of the cosine similarities in the “High Amplitude” and “Low Amplitude” lists, corresponds to the region in the “Regions” list (cosine similarity value in 0th index belongs to region in 0th index). The structure is as follows:

{
    "GroupName": {
        "Regions": [...],
        "CAP-1": {
            "High Amplitude": [...], # Shape: 1 x Regions
            "Low Amplitude": [...]   # Shape: 1 x Regions
        }
        "CAP-2": {
            "High Amplitude": [...], # Shape: 1 x Regions
            "Low Amplitude": [...]   # Shape: 1 x Regions
        }
    }
}

See also

neurocaps.typing.ParcelConfig

Type definition representing the configuration options and structure for the Schaefer and AAL parcellations.

neurocaps.typing.ParcelApproach

Type definition representing the structure of the Schaefer, AAL, and Custom parcellation approaches.

Note

Default Group Name: If no groups were specified, the default group name will always be “All Subjects” to denote that the data of all subjects in the analysis were used to derive the CAPs. This is done to retain the same nesting structure for each property regardless if groups are specified.

Custom Parcellations: If using a “Custom” parcellation approach, ensure that the parcellation is lateralized (where each region/network has nodes in the left and right hemisphere). This is due to certain visualization functions assuming that each region consists of left and right hemisphere nodes. Additionally, certain visualization functions in this class also assume that the background label is 0. Therefore, do not add a background label in the “nodes” or “regions” keys.

The recognized subkeys for the “Custom” parcellation approach includes:

  • “maps”: Directory path containing the parcellation in a supported format (e.g., .nii or .nii.gz for NifTI).

  • “nodes”: A list or numpy array of all node labels arranged in ascending order based on their numerical IDs from the parcellation. The 0th index should contain the label corresponding to the lowest, non-background numerical ID.

  • “regions”: A dictionary defining major brain regions or networks, with each region containing “lh” (left hemisphere) and “rh” (right hemisphere) subkeys listing node indices.

Refer to the NeuroCAPs’ Parcellation Documentation for more detailed explanations and example structures for the “nodes” and “regions” subkeys.

Note: Different subkeys are required depending on the function used. Refer to the Note section under each function for information regarding the subkeys required for that specific function.

Methods

calculate_metrics(subject_timeseries[, tr, ...])

Compute Participant-wise CAP Metrics.

caps2corr([output_dir, suffix_title, ...])

Generate Pearson Correlation Matrix for CAPs.

caps2niftis(output_dir[, suffix_filename, ...])

Standalone Method to Convert CAPs to NifTI Statistical Maps.

caps2plot([output_dir, suffix_title, ...])

Generate Heatmaps and Outer Product Plots for CAPs.

caps2radar([output_dir, suffix_title, ...])

Generate Radar Plots for CAPs using Cosine Similarity.

caps2surf([output_dir, suffix_title, ...])

Project CAPs onto Surface Plots.

get_caps(subject_timeseries[, runs, ...])

Perform K-Means Clustering to Identify CAPs.