Coverage for nilearn/interfaces/fmriprep/load_confounds_components.py: 18%
54 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"""Functions to noise components based on selected strategey.
4The _load_* functions of this module are indirectly used
5in nilearn.interfaces.fmriprep._load_noise_component.
7See an example below:
9.. code-block:: python
11 loaded_confounds = getattr(components, f"_load_{component}")(
12 confounds_raw, **params
13 )
15"""
17import numpy as np
18import pandas as pd
20from .load_confounds_compcor import find_compcor
21from .load_confounds_scrub import optimize_scrub
22from .load_confounds_utils import (
23 MissingConfoundError,
24 add_suffix,
25 check_params_confounds,
26 find_confounds,
27)
30def _load_motion(confounds_raw, motion):
31 """Load the motion regressors.
33 Parameters
34 ----------
35 confounds_raw : pandas.DataFrame
36 DataFrame of confounds.
38 motion : str
39 Motion strategy to use. Options are "basic",
40 "derivatives", "power2", or "full".
42 Returns
43 -------
44 pandas.DataFrame
45 DataFrame of motion regressors.
47 Raises
48 ------
49 MissingConfoundError
50 When motion regressors are not found or incomplete, raise error
51 as motion is not a valid choice of strategy.
52 """
53 motion_params = add_suffix(
54 ["trans_x", "trans_y", "trans_z", "rot_x", "rot_y", "rot_z"],
55 motion,
56 )
57 motion_regressor_check = check_params_confounds(
58 confounds_raw, motion_params
59 )
60 if isinstance(motion_regressor_check, list):
61 raise MissingConfoundError(params=motion_regressor_check)
63 if motion_regressor_check:
64 return confounds_raw[motion_params]
65 else:
66 raise MissingConfoundError(keywords=["motion"])
69def _load_high_pass(confounds_raw):
70 """Load the high pass filter regressors.
72 Parameters
73 ----------
74 confounds_raw : pandas.DataFrame
75 DataFrame of confounds.
77 Returns
78 -------
79 pandas.DataFrame
80 DataFrame of high pass filter regressors.
81 If not present in file, return an empty DataFrame.
82 """
83 high_pass_params = find_confounds(confounds_raw, ["cosine"])
84 return (
85 confounds_raw[high_pass_params] if high_pass_params else pd.DataFrame()
86 )
89def _load_wm_csf(confounds_raw, wm_csf):
90 """Load the regressors derived from the white matter and CSF masks.
92 Parameters
93 ----------
94 confounds_raw : pandas.DataFrame
95 DataFrame of confounds.
97 wm_csf : str
98 White matter and CSF strategy to use. Options are "basic",
99 "derivatives", "power2", or "full".
101 Returns
102 -------
103 pandas.DataFrame
104 DataFrame of white matter and CSF regressors.
106 Raises
107 ------
108 MissingConfoundError
109 When white matter and CSF regressors are not found, raise error as
110 wm_csf is not a valid choice of strategy.
111 """
112 wm_csf_params = add_suffix(["csf", "white_matter"], wm_csf)
113 if check_params_confounds(confounds_raw, wm_csf_params):
114 return confounds_raw[wm_csf_params]
115 else:
116 raise MissingConfoundError(keywords=["wm_csf"])
119def _load_global_signal(confounds_raw, global_signal):
120 """Load the regressors derived from the global signal.
122 Parameters
123 ----------
124 confounds_raw : pandas.DataFrame
125 DataFrame of confounds.
127 global_signal : str
128 Global signal strategy to use. Options are "basic",
129 "derivatives", "power2", or "full".
131 Returns
132 -------
133 pandas.DataFrame
134 DataFrame of global signal regressors.
136 Raises
137 ------
138 MissingConfoundError
139 When global signal regressors are not found, raise error as global
140 signal is not a valid choice of strategy.
141 """
142 global_params = add_suffix(["global_signal"], global_signal)
143 if check_params_confounds(confounds_raw, global_params):
144 return confounds_raw[global_params]
145 else:
146 raise MissingConfoundError(keywords=["global_signal"])
149def _load_compcor(confounds_raw, meta_json, compcor, n_compcor):
150 """Load compcor regressors.
152 Parameters
153 ----------
154 confounds_raw : pandas.DataFrame
155 DataFrame of confounds.
157 meta_json : dict
158 Dictionary of confounds meta data from the confounds.json file.
160 compcor : str
161 Compcor strategy to use. Options are "temporal_anat", "temporal",
162 "anat", or "combined".
164 n_compcor : int or str
165 Number of compcor components to retain. If "all", all components
166 are retained.
168 Returns
169 -------
170 pandas.DataFrame
171 DataFrame of compcor regressors.
173 Raises
174 ------
175 MissingConfoundError
176 When compcor regressors are not found, raise error as compcor is
177 not a valid choice of strategy.
178 """
179 compcor_cols = find_compcor(meta_json, compcor, n_compcor)
180 if check_params_confounds(confounds_raw, compcor_cols):
181 return confounds_raw[compcor_cols]
182 else:
183 raise MissingConfoundError(keywords=["compcor"])
186def _load_ica_aroma(confounds_raw, ica_aroma):
187 """Load the ICA-AROMA regressors.
189 Parameters
190 ----------
191 confounds_raw : pandas.DataFrame
192 DataFrame of confounds.
194 ica_aroma : str
195 ICA-AROMA strategy to use. Options are "full", "basic".
197 Returns
198 -------
199 pandas.DataFrame
200 DataFrame of ICA-AROMA regressors.
201 When ica_aroma is "full", return an empty DataFrame as the
202 ICA-AROMA regressors have been handled in the preprocessed bold
203 image.
205 Raises
206 ------
207 ValueError
208 When ica_aroma is not "full" or "basic".
209 """
210 if ica_aroma == "full":
211 return pd.DataFrame()
212 elif ica_aroma == "basic":
213 ica_aroma_params = find_confounds(confounds_raw, ["aroma"])
214 if not ica_aroma_params:
215 raise MissingConfoundError(keywords=["ica_aroma"])
216 return confounds_raw[ica_aroma_params]
217 else:
218 raise ValueError(
219 "Please select an option when using ICA-AROMA strategy."
220 f"Current input: {ica_aroma}"
221 )
224def _load_scrub(confounds_raw, scrub, fd_threshold, std_dvars_threshold):
225 """Remove volumes if FD and/or DVARS exceeds threshold.
227 Parameters
228 ----------
229 confounds_raw : pandas.DataFrame
230 DataFrame of confounds.
232 scrub : int, default=5
233 Minimal segment length.
234 Segment smaller than the given value will be removed.
236 fd_threshold : float
237 Threshold for the framewise displacement. Volumes with FD larger
238 than the threshold will be removed.
240 std_dvars_threshold : float
241 Threshold for the standard deviation of DVARS.
242 Volumes with DVARS larger than the threshold will be removed.
244 Returns
245 -------
246 motion_outlier_regressors : pandas.DataFrame
247 DataFrame of one-hot encoded motion outlier regressors.
248 """
249 n_scans = len(confounds_raw)
250 # Get indices of fd outliers
251 fd_outliers_index = np.where(
252 confounds_raw["framewise_displacement"] > fd_threshold
253 )[0]
254 dvars_outliers_index = np.where(
255 confounds_raw["std_dvars"] > std_dvars_threshold
256 )[0]
257 motion_outliers_index = np.sort(
258 np.unique(np.concatenate((fd_outliers_index, dvars_outliers_index)))
259 )
260 # when motion outliers were detected, remove segments with too few
261 # timeframes if desired
262 if scrub > 0 and len(motion_outliers_index) > 0:
263 motion_outliers_index = optimize_scrub(
264 motion_outliers_index, n_scans, scrub
265 )
266 # Make one-hot encoded motion outlier regressors
267 motion_outlier_regressors = pd.DataFrame(
268 np.transpose(np.eye(n_scans)[motion_outliers_index]).astype(int)
269 )
270 column_names = [
271 f"motion_outlier_{num}"
272 for num in range(np.shape(motion_outlier_regressors)[1])
273 ]
274 motion_outlier_regressors.columns = column_names
275 return motion_outlier_regressors
278def _load_non_steady_state(confounds_raw):
279 """Find non steady state regressors.
281 Parameters
282 ----------
283 confounds_raw : pandas.DataFrame
284 DataFrame of confounds.
286 Returns
287 -------
288 pandas.DataFrame
289 DataFrame of non steady state regressors generated by fMRIPrep.
290 If none were found, return an empty DataFrame.
291 """
292 nss_outliers = find_confounds(confounds_raw, ["non_steady_state"])
293 return confounds_raw[nss_outliers] if nss_outliers else pd.DataFrame()