Coverage for nilearn/interfaces/fmriprep/load_confounds_strategy.py: 14%

29 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-16 12:32 +0200

1"""Predefined denoising strategies.""" 

2 

3import warnings 

4 

5from nilearn._utils.logger import find_stack_level 

6from nilearn.interfaces.fmriprep import load_confounds 

7 

8# defining a preset strategy with python dictionary: 

9# key: 

10# name for the strategy 

11# value: 

12# a dictionary containing the parameters from `load_confounds` 

13# and associated values. 

14# compulsory: 

15# strategy (as the value defines the other relevant parameters) 

16preset_strategies = { 

17 "simple": { 

18 "strategy": ("high_pass", "motion", "wm_csf"), 

19 "motion": "full", 

20 "wm_csf": "basic", 

21 "global_signal": None, 

22 "demean": True, 

23 }, 

24 "scrubbing": { 

25 "strategy": ("high_pass", "motion", "wm_csf", "scrub"), 

26 "motion": "full", 

27 "wm_csf": "full", 

28 "scrub": 5, 

29 "fd_threshold": 0.2, # updated here and doc to 0.5 in v0.13 

30 "std_dvars_threshold": 3, # updated here and doc to 1.5 in v0.13 

31 "global_signal": None, 

32 "demean": True, 

33 }, 

34 "compcor": { 

35 "strategy": ("high_pass", "motion", "compcor"), 

36 "motion": "full", 

37 "n_compcor": "all", 

38 "compcor": "anat_combined", 

39 "global_signal": None, 

40 "demean": True, 

41 }, 

42 "ica_aroma": { 

43 "strategy": ("high_pass", "wm_csf", "ica_aroma"), 

44 "wm_csf": "basic", 

45 "ica_aroma": "full", 

46 "global_signal": None, 

47 "demean": True, 

48 }, 

49} 

50 

51 

52def load_confounds_strategy(img_files, denoise_strategy="simple", **kwargs): 

53 """ 

54 Use preset strategy to load confounds from :term:`fMRIPrep`. 

55 

56 `load_confounds_strategy` provides an interface to select confounds 

57 based on past literature with limited parameters for user customization. 

58 

59 .. versionadded:: 0.9.0 

60 

61 Parameters 

62 ---------- 

63 img_files : :obj:`str` or :obj:`list` of :obj:`str`. 

64 Processed nii.gz/dtseries.nii/func.gii file reside in a 

65 :term:`fMRIPrep` generated functional derivative directory (i.e.The 

66 associated confound files should be in the same directory as the image 

67 file). As long as the image file, confound related tsv and json are in 

68 the same directory with BIDS-compliant names, 

69 :func:`nilearn.interfaces.fmriprep.load_confounds` can retrieve the 

70 relevant files correctly. 

71 

72 - `nii.gz` or `dtseries.nii`: path to files, optionally as a list. 

73 - `func.gii`: list of a pair of paths to files, optionally as a list 

74 of lists. 

75 

76 denoise_strategy : :obj:`str`, default="simple" 

77 Name of preset denoising strategies. Each strategy has a set of 

78 associated configurable parameters. For customiseable parameters, 

79 please see the table in Notes. 

80 

81 - 'simple': Load confounds for a simple denoising strategy commonly 

82 used in resting state functional connectivity, described in 

83 :footcite:t:`Fox2005`. With the global signal regression, 

84 this approach can remove confounds 

85 without compromising the temporal degrees of freedom. 

86 - 'scrubbing': Load confounds for scrubbing described in 

87 :footcite:t:`Power2012`. This approach can reliably remove the 

88 impact of high motion volumes in functional connectome, however, it 

89 might not be suitable with subjects with high motion (more than 50% 

90 timeseries flagged as high motion). One should adjust the threshold 

91 based on the characteristics of the dataset, or remove high motion 

92 subjects from the dataset. 

93 - 'compcor': Load confounds using the CompCor strategy from 

94 :footcite:t:`Behzadi2007`. CompCor estimates noise through principal 

95 component analysis on regions that are unlikely to contain signal. 

96 Thus it might not be a suitable approach for researchers who want 

97 explicit description of the source of noise. Empirically, Compcor 

98 has shown similar effect of removing physiological noise as methods 

99 that explicitly model and remove physiology signals. Compcor can 

100 suffer from loss of temporal degrees of freedom when using explained 

101 variance as the noise component estimation as the number of compcor 

102 component can be really high. Please refer to :term:`fMRIPrep` 

103 documentation for more details. 

104 

105 .. versionadded:: 0.10.3 

106 `golobal_signal` is now a tunable parameter for compcor. 

107 

108 - 'ica_aroma': Load confounds for non-aggresive ICA-AROMA strategy 

109 described in :footcite:t:`Pruim2015`. The strategy requires 

110 :term:`fMRIPrep` outputs generated with `--use-aroma` suffixed with 

111 `desc-smoothAROMAnonaggr_bold`. ICA-AROMA increases the run time of 

112 :term:`fMRIPrep`, however, the strategy performs well in various 

113 benchmarks (:footcite:t:`Ciric2017`, :footcite:t:`Parker2018`). 

114 See Notes for more details about this option. 

115 

116 .. attention:: 

117 The `--use-aroma` option is deprecated in :term:`fMRIPrep` 

118 version 23.2.3 and no longer works since version 24.0.0. 

119 See `fmripost-aroma docs <https://fmripost-aroma.readthedocs.io/latest/usage.html>`_ 

120 for the new ICA-AROMA implementation. 

121 

122 Other keyword arguments: 

123 See additional parameters associated with `denoise_strategy` in 

124 Notes and refer to the documentation of 

125 :func:`nilearn.interfaces.fmriprep.load_confounds`. 

126 

127 Returns 

128 ------- 

129 confounds : :class:`pandas.DataFrame`, or :obj:`list` of \ 

130 :class:`pandas.DataFrame` 

131 A reduced version of :term:`fMRIPrep` confounds based on selected 

132 strategy and flags. 

133 The columns contains the labels of the regressors. 

134 

135 sample_mask : None, :class:`numpy.ndarray` or, :obj:`list` of \ 

136 :class:`numpy.ndarray` or None 

137 When no volume requires removal, the value is None. 

138 Otherwise, shape: (number of scans - number of volumes removed, ) 

139 The index of the niimgs along time/fourth dimension for valid volumes 

140 for subsequent analysis. 

141 This attribute should be passed to parameter `sample_mask` of 

142 :class:`nilearn.maskers.NiftiMasker` or 

143 :func:`nilearn.signal.clean`. 

144 Volumes are removed if flagged as following: 

145 

146 - Non-steady-state volumes (if present) 

147 - Motion outliers detected by scrubbing 

148 

149 Notes 

150 ----- 

151 1. The following table details the default options of each preset 

152 strategies. Parameters with `*` denote customizable parameters. Please 

153 see :func:`nilearn.interfaces.fmriprep.load_confounds`. 

154 

155 ========= ========= ====== ====== ============= ===== ============ \ 

156 =================== ============== ========= ========= ====== 

157 strategy high_pass motion wm_csf global_signal scrub fd_threshold \ 

158 std_dvars_threshold compcor n_compcor ica_aroma demean 

159 ========= ========= ====== ====== ============= ===== ============ \ 

160 =================== ============== ========= ========= ====== 

161 simple True full* basic* None* N/A N/A \ 

162 N/A N/A N/A N/A True* 

163 scrubbing True full* full None* 5* 0.2* \ 

164 3* N/A N/A N/A True* 

165 compcor True full* N/A None* N/A N/A \ 

166 N/A anat_combined* all* N/A True* 

167 ica_aroma True N/A basic* None* N/A N/A \ 

168 N/A N/A N/A full True* 

169 ========= ========= ====== ====== ============= ===== ============ \ 

170 =================== ============== ========= ========= ====== 

171 

172 2. ICA-AROMA is implemented in two steps in :footcite:t:`Pruim2015`: 

173 

174 i. A non-aggressive denoising immediately after :term:`ICA` 

175 classification. 

176 A linear regression estimates signals with all independent 

177 components as predictors. A partial regression is then applied to 

178 remove variance associated with noise independent components. 

179 :term:`fMRIPrep` performs this step and generates files in 

180 `MNI152NLin6Asym` template, suffixed with 

181 `desc-smoothAROMAnonaggr_bold`. 

182 

183 One can produce `desc-smoothAROMAnonaggr_bold` in other spatial 

184 templates, please refer to :term:`fMRIPrep` documentation on ICA-AROMA 

185 `<https://fmriprep.org/en/23.2.3/usage.html#%5Bdeprecated%5D-options-for-running-ica_aroma>`_ 

186 

187 ii. Confound regression step (mean signals from WM and CSF). 

188 Confound regressors generated by this function with 

189 `denoise_strategy="ica_aroma"`. 

190 

191 For more discussion regarding choosing the nuisance regressors before 

192 or after denoising with ICA-AROMA has a detriment on outcome measures, 

193 please see notebook 5. 

194 `<https://github.com/nipreps/fmriprep-notebooks/>`_ 

195 

196 .. attention:: 

197 Since version 24.0.0 `fMRIPrep` does not perform ICA-AROMA anymore. 

198 This feature has been replaced by `fmripost-aroma <https://fmripost-aroma.readthedocs.io/latest/usage.html>`_ 

199 and consequently the suffixes of files produced by `fmripost-aroma` 

200 may differ from the ones produced by `fMRIPrep < 24.0.0`. 

201 

202 

203 See Also 

204 -------- 

205 :func:`nilearn.interfaces.fmriprep.load_confounds` 

206 

207 References 

208 ---------- 

209 .. footbibliography:: 

210 

211 """ 

212 default_parameters = preset_strategies.get(denoise_strategy, False) 

213 if not default_parameters: 

214 raise KeyError( 

215 f"Provided strategy '{denoise_strategy}' is not a " 

216 "preset strategy. Valid strategy: " 

217 f"{preset_strategies.keys()}" 

218 ) 

219 

220 check_parameters = list(default_parameters.keys()) 

221 check_parameters.remove("strategy") 

222 # ICA-AROMA only accept the non-aggressive strategy 

223 # ignore user passed value 

224 if "ica_aroma" in default_parameters: 

225 check_parameters.remove("ica_aroma") 

226 

227 user_parameters, not_needed = _update_user_inputs( 

228 kwargs, default_parameters, check_parameters 

229 ) 

230 

231 # raise warning about parameters not needed 

232 if not_needed: 

233 warnings.warn( 

234 "The following parameters are not needed for the " 

235 f"selected strategy '{denoise_strategy}': {not_needed}; " 

236 f"parameters accepted: {check_parameters}", 

237 stacklevel=find_stack_level(), 

238 ) 

239 return load_confounds(img_files, **user_parameters) 

240 

241 

242def _update_user_inputs(kwargs, default_parameters, check_parameters): 

243 """Update keyword parameters with user inputs if applicable. 

244 

245 Parameters 

246 ---------- 

247 kwargs : :obj:`dict` 

248 Keyword parameters passed to `load_confounds_strategy`. 

249 

250 default_parameters : :obj:`dict` 

251 Default parameters for the selected pre-set strategy. 

252 

253 check_parameters : :obj:`list` 

254 List of parameters that are applicable to the selected pre-set 

255 strategy. 

256 

257 Returns 

258 ------- 

259 parameters : :obj:`dict` 

260 Updated valid parameters for `load_confounds`. 

261 

262 not_needed : :obj:`list` 

263 List of parameters that are not applicable to the selected 

264 pre-set strategy. 

265 """ 

266 parameters = default_parameters.copy() 

267 # update the parameter with user input 

268 not_needed = [] 

269 for key in check_parameters: 

270 value = kwargs.pop(key, None) # get user input 

271 if value is not None: 

272 parameters[key] = value 

273 # global_signal parameter is not in default strategy, but 

274 # applicable to every strategy other than compcor 

275 # global signal strategy will only be added if user has passed a 

276 # recognizable value to the global_signal parameter 

277 if key == "global_signal": 

278 if isinstance(value, str): 

279 parameters["strategy"] += ("global_signal",) 

280 else: # remove global signal if not updated 

281 parameters.pop("global_signal", None) 

282 # collect remaining parameters in kwargs that are not needed 

283 not_needed = list(kwargs.keys()) 

284 return parameters, not_needed