Coverage for nilearn/interfaces/fmriprep/load_confounds_compcor.py: 16%
39 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 12:32 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 12:32 +0200
1"""Helper function for load_compcor."""
3prefix_compcor = {
4 "temporal_anat_combined": ["t", "a"],
5 "temporal_anat_separated": ["t", "a", "w", "c"],
6 "temporal": ["t"],
7 "anat_combined": ["a"],
8 "anat_separated": ["a", "w", "c"],
9}
10anat_masker = {
11 "combined": ["combined"],
12 "separated": ["WM", "CSF"],
13 None: None,
14}
17def find_compcor(confounds_json, compcor, n_compcor):
18 """Build list for the number of compcor components.
20 Parameters
21 ----------
22 confounds_json : :obj:`dict`
23 Dictionary of confounds from the confounds.json file.
24 compcor : :obj:`str`
25 Compcor strategy to use. Options are "temporal_anat", "temporal",
26 "anat", or "combined".
27 n_compcor : :obj:`int` or :obj:`str`
28 Number of compcor components to retain. If "all", all components
29 are retained.
31 Returns
32 -------
33 collector : :obj:`list`
34 List of compcor components to retain.
35 """
36 prefix_set, anat_mask = _check_compcor_method(compcor)
38 collector = []
39 for prefix in prefix_set:
40 # all possible compcor confounds in order
41 all_compcor_name = [
42 comp for comp in confounds_json if f"{prefix}_comp_cor" in comp
43 ]
44 # filter by prefix first (anat vs temporal)
45 compcor_cols_filt = _prefix_confound_filter(prefix, all_compcor_name)
46 if prefix == "a":
47 # apply acompor mask option if relevant, and select top components
48 compcor_cols_filt = _acompcor_mask(
49 confounds_json, anat_mask, compcor_cols_filt, n_compcor
50 )
51 else:
52 # select top components
53 compcor_cols_filt = _select_compcor(compcor_cols_filt, n_compcor)
54 # Aggregate components across all masks
55 collector += compcor_cols_filt
56 return collector
59def _select_compcor(compcor_cols, n_compcor):
60 """Retain a specified number of compcor components.
62 Parameters
63 ----------
64 compcor_cols : :obj:`list`
65 List of compcor components column names filtered by user
66 selected CompCor strategy.
67 n_compcor : :obj:`int` or :obj:`str`
68 Number of compcor components to retain. If "all", all components
69 are retained.
71 Returns
72 -------
73 compcor_cols : :obj:`list`
74 List of compcor components column names to retain.
75 """
76 # only select if not "all", or less components are requested than there
77 # actually is
78 if (n_compcor != "all") and (n_compcor < len(compcor_cols)):
79 compcor_cols = compcor_cols[:n_compcor]
80 return compcor_cols
83def _check_compcor_method(compcor):
84 """Load compcor options and check if method is acceptable.
86 Parameters
87 ----------
88 compcor : :obj: `str`
89 Compcor strategy to use. Options are "temporal_anat", "temporal",
90 "anat", or "combined".
92 Returns
93 -------
94 prefix_set : :obj:`list`
95 List of prefixes to use for compcor components.
96 anat_mask : :obj:`list`
97 List of anatomical masks to use for acompcor.
98 """
99 # get relevant prefix from compcor strategy
100 prefix_set = prefix_compcor[compcor]
101 # get relevant compcor mask
102 check_masktype = compcor.split("_")
103 anat_mask_type = None if len(check_masktype) == 1 else check_masktype[-1]
104 anat_mask = anat_masker[anat_mask_type]
105 return prefix_set, anat_mask
108def _acompcor_mask(confounds_json, anat_mask, compcor_cols_filt, n_compcor):
109 """Filter according to acompcor mask(s) and select top components.
111 Parameters
112 ----------
113 confounds_json : :obj: `dict`
114 Dictionary of confounds from the confounds.json file.
115 anat_mask : :obj:`list`
116 List of anatomical masks to use for acompcor.
117 compcor_cols_filt : :obj:`list`
118 List of compcor components column names filtered by user
119 selected CompCor strategy.
120 n_compcor : :obj:`int` or :obj:`str`
121 Number of compcor components to retain. If "all", all components
122 are retained.
124 Returns
125 -------
126 collector : :obj:`list`
127 List of compcor components column names to retain.
128 """
129 collector = []
130 for mask in anat_mask:
131 cols = _json_mask(compcor_cols_filt, confounds_json, mask)
132 cols = _select_compcor(cols, n_compcor)
133 collector += cols
134 return collector
137def _json_mask(compcor_cols_filt, confounds_json, mask):
138 """Extract anat compcor components with a given mask.
140 Parameters
141 ----------
142 compcor_cols_filt : :obj:`list`
143 List of compcor components column names filtered by user
144 selected CompCor strategy.
145 confounds_json : :obj:`dict`
146 Dictionary of confounds from the confounds.json file.
147 mask : :obj:`str`
148 Mask to use for acompcor.
150 Returns
151 -------
152 compcor_cols_filt : :obj:`list`
153 List of compcor components column names filtered by type of
154 acompcor mask.
155 """
156 return [
157 compcor_col
158 for compcor_col in compcor_cols_filt
159 if confounds_json[compcor_col]["Mask"] in mask
160 ]
163def _prefix_confound_filter(prefix, all_compcor_name):
164 """Get confound columns by prefix and acompcor mask.
166 Parameters
167 ----------
168 prefix : :obj:`str`
169 Prefix to use for compcor components.
170 all_compcor_name : :obj:`list`
171 List of all compcor components column names.
173 Returns
174 -------
175 compcor_cols_filt : :obj:`list`
176 List of compcor components column names filtered by prefix.
177 """
178 compcor_cols_filt = []
179 for nn in range(len(all_compcor_name)):
180 nn_str = str(nn).zfill(2)
181 compcor_col = f"{prefix}_comp_cor_{nn_str}"
182 compcor_cols_filt.append(compcor_col)
183 return compcor_cols_filt