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

1"""Functions to noise components based on selected strategey. 

2 

3 

4The _load_* functions of this module are indirectly used 

5in nilearn.interfaces.fmriprep._load_noise_component. 

6 

7See an example below: 

8 

9.. code-block:: python 

10 

11 loaded_confounds = getattr(components, f"_load_{component}")( 

12 confounds_raw, **params 

13 ) 

14 

15""" 

16 

17import numpy as np 

18import pandas as pd 

19 

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) 

28 

29 

30def _load_motion(confounds_raw, motion): 

31 """Load the motion regressors. 

32 

33 Parameters 

34 ---------- 

35 confounds_raw : pandas.DataFrame 

36 DataFrame of confounds. 

37 

38 motion : str 

39 Motion strategy to use. Options are "basic", 

40 "derivatives", "power2", or "full". 

41 

42 Returns 

43 ------- 

44 pandas.DataFrame 

45 DataFrame of motion regressors. 

46 

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) 

62 

63 if motion_regressor_check: 

64 return confounds_raw[motion_params] 

65 else: 

66 raise MissingConfoundError(keywords=["motion"]) 

67 

68 

69def _load_high_pass(confounds_raw): 

70 """Load the high pass filter regressors. 

71 

72 Parameters 

73 ---------- 

74 confounds_raw : pandas.DataFrame 

75 DataFrame of confounds. 

76 

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 ) 

87 

88 

89def _load_wm_csf(confounds_raw, wm_csf): 

90 """Load the regressors derived from the white matter and CSF masks. 

91 

92 Parameters 

93 ---------- 

94 confounds_raw : pandas.DataFrame 

95 DataFrame of confounds. 

96 

97 wm_csf : str 

98 White matter and CSF strategy to use. Options are "basic", 

99 "derivatives", "power2", or "full". 

100 

101 Returns 

102 ------- 

103 pandas.DataFrame 

104 DataFrame of white matter and CSF regressors. 

105 

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"]) 

117 

118 

119def _load_global_signal(confounds_raw, global_signal): 

120 """Load the regressors derived from the global signal. 

121 

122 Parameters 

123 ---------- 

124 confounds_raw : pandas.DataFrame 

125 DataFrame of confounds. 

126 

127 global_signal : str 

128 Global signal strategy to use. Options are "basic", 

129 "derivatives", "power2", or "full". 

130 

131 Returns 

132 ------- 

133 pandas.DataFrame 

134 DataFrame of global signal regressors. 

135 

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"]) 

147 

148 

149def _load_compcor(confounds_raw, meta_json, compcor, n_compcor): 

150 """Load compcor regressors. 

151 

152 Parameters 

153 ---------- 

154 confounds_raw : pandas.DataFrame 

155 DataFrame of confounds. 

156 

157 meta_json : dict 

158 Dictionary of confounds meta data from the confounds.json file. 

159 

160 compcor : str 

161 Compcor strategy to use. Options are "temporal_anat", "temporal", 

162 "anat", or "combined". 

163 

164 n_compcor : int or str 

165 Number of compcor components to retain. If "all", all components 

166 are retained. 

167 

168 Returns 

169 ------- 

170 pandas.DataFrame 

171 DataFrame of compcor regressors. 

172 

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"]) 

184 

185 

186def _load_ica_aroma(confounds_raw, ica_aroma): 

187 """Load the ICA-AROMA regressors. 

188 

189 Parameters 

190 ---------- 

191 confounds_raw : pandas.DataFrame 

192 DataFrame of confounds. 

193 

194 ica_aroma : str 

195 ICA-AROMA strategy to use. Options are "full", "basic". 

196 

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. 

204 

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 ) 

222 

223 

224def _load_scrub(confounds_raw, scrub, fd_threshold, std_dvars_threshold): 

225 """Remove volumes if FD and/or DVARS exceeds threshold. 

226 

227 Parameters 

228 ---------- 

229 confounds_raw : pandas.DataFrame 

230 DataFrame of confounds. 

231 

232 scrub : int, default=5 

233 Minimal segment length. 

234 Segment smaller than the given value will be removed. 

235 

236 fd_threshold : float 

237 Threshold for the framewise displacement. Volumes with FD larger 

238 than the threshold will be removed. 

239 

240 std_dvars_threshold : float 

241 Threshold for the standard deviation of DVARS. 

242 Volumes with DVARS larger than the threshold will be removed. 

243 

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 

276 

277 

278def _load_non_steady_state(confounds_raw): 

279 """Find non steady state regressors. 

280 

281 Parameters 

282 ---------- 

283 confounds_raw : pandas.DataFrame 

284 DataFrame of confounds. 

285 

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()