CAP.calculate_metrics#
- CAP.calculate_metrics(subject_timeseries, runs=None, continuous_runs=False, metrics=('temporal_fraction', 'persistence', 'counts', 'transition_frequency'), tr=None, output_dir=None, prefix_filename=None, return_df=True, progress_bar=False)[source]#
Calculate Participant-wise CAP Metrics.
Calculates temporal dynamic metrics for each CAP across all participants. The metrics are calculated as described by Liu et al. (2018) and Yang et al. (2021) and include the following:
“temporal_fraction” (fraction of time): Proportion of total volumes spent in a single CAP over all volumes in a run.
predicted_subject_timeseries = [1, 2, 1, 1, 1, 3] target = 1 temporal_fraction = 4 / 6
“persistence” (dwell time): Average time spent in a single CAP before transitioning to another CAP (average consecutive/uninterrupted time).
predicted_subject_timeseries = [1, 2, 1, 1, 1, 3] target = 1 # Sequences for 1 are [1] and [1, 1, 1]; There are 2 contiguous sequences persistence = (1 + 3) / 2 # Turns average frames into average time = 4 tr = 2 if tr: persistence = ((1 + 3) / 2) * 2
“counts” (state initiation): Total number of initiations of a specific CAP across an entire run. An initiation is defined as the first occurrence of a CAP. If the same CAP is maintained in consecutively (indicating stability), it is still counted as a single initiation.
predicted_subject_timeseries = [1, 2, 1, 1, 1, 3] target = 1 # Initiations of CAP-1 occur at indices 0 and 2 counts = 2
“transition_frequency”: Total number of transitions to different CAPs across the entire run.
predicted_subject_timeseries = [1, 2, 1, 1, 1, 3] # Transitions between unique CAPs occur at indices 0 -> 1, 1 -> 2, and 4 -> 5 transition_frequency = 3
“transition_probability”: Probability of transitioning from one CAP to another CAP (or the same CAP). This is calculated as (Number of transitions from A to B) / (Total transitions from A). Note that the transition probability from CAP-A -> CAP-B is not the same as CAP-B -> CAP-A.
# Note last two numbers in the predicted timeseries are switched for this example predicted_subject_timeseries = [1, 2, 1, 1, 3, 1] # If three CAPs were identified in the analysis combinations = [ (1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3) ] # Represents transition from CAP-1 -> CAP-2 target = (1, 2) # There are 4 ones in the timeseries but only three transitions from 1 # 1 -> 2, 1 -> 1, 1 -> 3 n_transitions_from_1 = 3 # There is only one 1 -> 2 transition transition_probability = 1 / 3
Note
In the supplementary material for Yang et al., the mathematical relationship between temporal fraction, counts, and persistence is
temporal_fraction = (persistence * counts)/total_volumes. If persistence has been converted into time units (seconds), thentemporal_fraction = (persistence * counts) / (total_volumes * tr).- Parameters:
subject_timeseries (
SubjectTimeseriesorstr) – A dictionary mapping subject IDs to their run IDs and their associated timeseries (TRs x ROIs) as a NumPy array. Can also be a path to a serialized file containing this same structure. Refer to documentation forSubjectTimeseriesin the “See Also” section for an example structure.runs (
int,str,list[int],list[str], orNone, default=None) – The run IDs to calculate CAP metrics for (e.g.runs=[0, 1]orruns=["01", "02"]). If None, CAP metrics will be calculated for all detected run IDs even if only specific runs were used duringself.get_caps().continuous_runs (
bool, default=False) –If True, all runs will be treated as a single, uninterrupted run.
# CAP assignment of frames from for run_1 and run_2 run_1 = [0, 1, 1] run_2 = [2, 3, 3] # Computation of each CAP metric will be conducted on the combined vector continuous_runs = [0, 1, 1, 2, 3, 3]
Note
This parameter can be used together with
runsto filter the runs to combine.The run-ID in the dataframe will be converted to run-continuous to denote that runs were combined.
If only a single run available for a subject, the original run ID (as opposed to “run-continuous”) will be used.
metrics ({“temporal_fraction”, “persistence”, “counts”, “transition_frequency”, “transition_probability”},
list[str],tuple[str, ...], orNone, default=(“temporal_fraction”, “persistence”, “counts”, “transition_frequency”)) – The metrics to calculate. Available options include “temporal_fraction”, “persistence”, “counts”, “transition_frequency”, and “transition_probability”. Defaults to("temporal_fraction", "persistence", "counts", "transition_frequency")if None.tr (
floatorNone, default=None) – Repetition time (TR) in seconds. If provided, persistence will be calculated as the average uninterrupted time, in seconds, spent in each CAP. If not provided, persistence will be calculated as the average uninterrupted volumes (TRs), in TR units, spent in each state.output_dir (
strorNone, default=None) – Directory to savepandas.DataFrameas csv files. The directory will be created if it does not exist. Dataframes will not be saved if None.prefix_filename (
strorNone, default=None) – A prefix to append to the saved file names for eachpandas.DataFrame, ifoutput_diris provided.return_df (
str, default=True) – If True, returnspandas.DataFrameinside a dictionary, mapping each dataframe to their metric.progress_bar (
bool, default=False) – If True, displays a progress bar.
See also
neurocaps.typing.SubjectTimeseriesType definition for the subject timeseries dictionary structure. (See: SubjectTimeseries Documentation)
- Returns:
dict[str, pd.DataFrame] or dict[str, dict[str, pd.DataFrame]] – Dictionary containing pandas.DataFrame: Only returned if
return_dfis True.For “temporal_fraction”, “counts”, “persistence”, and “transition_frequency”: one
dataframe is returned for each requested metric.
For “transition_probability”: each group has a separate dataframe which is returned
in the from of dict[str, dict[str, pd.DataFrame]].
Important
Scaling: If standardization was requested in
self.get_caps(), then the columns/ROIs of thesubject_timeseriesprovided to this method will be scaled using group-specific means and standard deviations. These statistics are derived from the concatenated data of each group. This scaling ensures the subject’s data matches the distribution of the input data used for group-specific clustering, which is needed for accurate predictions when using group-specific k-means models. The group assignment for each subject is determined based on theself.subject_tableproperty.Group-Specific CAPs: If groups were specified, then each group uses their respective k-means models to compute metrics. The inclusion of all groups within the same dataframe (for “temporal_fraction”, “persistence”, “counts”, and “transition_frequency”) is primarily to reduce the number of dataframes generated. Hence, each CAP (e.g., “CAP-1”) is specific to its respective groups.
For instance, if their are two groups, Group A and Group B, each with their own CAPs:
A has 2 CAPs: “CAP-1” and “CAP-2”
B has 3 CAPs: “CAP-1”, “CAP-2”, and “CAP-3”
The resulting “temporal_fraction” dataframe (“persistence” and “counts” have a similar structure but “transition frequency” will only contain the “Subject_ID”, “Group”, and “Run” columns in addition to a “Transition_Frequency” column):
With Groups
Subject_ID
Group
Run
CAP-1
CAP-2
CAP-3
101
A
run-1
0.40
0.60
NaN
102
B
run-1
0.30
0.50
0.20
…
…
…
…
…
…
The “NaN” indicates that “CAP-3” is not applicable for Group A. Additionally, “NaN” will only be observed in instances when two or more groups are specified and have different number of CAPs. As mentioned previously, “CAP-1”, “CAP-2”, and “CAP-3” for Group A is distinct from Group B due to using separate k-means models.
Without Groups
Subject_ID
Group
Run
CAP-1
CAP-2
CAP-3
CAP-4
101
All Subjects
run-1
0.20
0
0
0.80
102
All Subjects
run-1
0.50
0.25
0.25
0
…
…
…
…
…
…
…
Transition Probability: For “transition_probability”, each group has a separate dataframe to containing the CAP transitions for each group.
Group A Transition Probability: Stored in
df_dict["transition_probability"]["A"]Group B Transition Probability: Stored in
df_dict["transition_probability"]["B"]
The resulting “transition_probability” for Group A:
Subject_ID
Group
Run
1.1
1.2
1.3
2.1
…
101
A
run-1
0.40
0.60
0
0.2
…
…
…
…
…
…
…
…
…
The resulting “transition_probability” for Group B:
Subject_ID
Group
Run
1.1
1.2
2.1
…
102
B
run-1
0.70
0.30
0.10
…
…
…
…
…
…
…
…
Here the columns indicate {from}.{to}. For instance, column 1.2 indicates the probability of transitioning from CAP-1 to CAP-2.
If no groups are specified, then the dataframe is stored in
df_dict["transition_probability"]["All Subjects"].References
Liu, X., Zhang, N., Chang, C., & Duyn, J. H. (2018). Co-activation patterns in resting-state fMRI signals. NeuroImage, 180, 485–494. https://doi.org/10.1016/j.neuroimage.2018.01.041
Yang, H., Zhang, H., Di, X., Wang, S., Meng, C., Tian, L., & Biswal, B. (2021). Reproducible coactivation patterns of functional brain networks reveal the aberrant dynamic state transition in schizophrenia. NeuroImage, 237, 118193. https://doi.org/10.1016/j.neuroimage.2021.118193