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

1"""Helper function for load_compcor.""" 

2 

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} 

15 

16 

17def find_compcor(confounds_json, compcor, n_compcor): 

18 """Build list for the number of compcor components. 

19 

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. 

30 

31 Returns 

32 ------- 

33 collector : :obj:`list` 

34 List of compcor components to retain. 

35 """ 

36 prefix_set, anat_mask = _check_compcor_method(compcor) 

37 

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 

57 

58 

59def _select_compcor(compcor_cols, n_compcor): 

60 """Retain a specified number of compcor components. 

61 

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. 

70 

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 

81 

82 

83def _check_compcor_method(compcor): 

84 """Load compcor options and check if method is acceptable. 

85 

86 Parameters 

87 ---------- 

88 compcor : :obj: `str` 

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

90 "anat", or "combined". 

91 

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 

106 

107 

108def _acompcor_mask(confounds_json, anat_mask, compcor_cols_filt, n_compcor): 

109 """Filter according to acompcor mask(s) and select top components. 

110 

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. 

123 

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 

135 

136 

137def _json_mask(compcor_cols_filt, confounds_json, mask): 

138 """Extract anat compcor components with a given mask. 

139 

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. 

149 

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 ] 

161 

162 

163def _prefix_confound_filter(prefix, all_compcor_name): 

164 """Get confound columns by prefix and acompcor mask. 

165 

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. 

172 

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