Coverage for nilearn/_utils/glm.py: 15%

40 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-20 10:58 +0200

1from collections.abc import Iterable 

2from pathlib import Path 

3 

4import numpy as np 

5import pandas as pd 

6 

7from nilearn._utils import stringify_path 

8 

9 

10def check_and_load_tables(tables_to_check, var_name): 

11 """Load tables. 

12 

13 Tables will be 'loaded' 

14 if they are pandas.DataFrame, \ 

15 or a CSV or TSV file that can be loaded to a pandas.DataFrame. 

16 

17 Numpy arrays will also be appended as is. 

18 

19 tables_to_check : str or pathlib.Path to a TSV or CSV \ 

20 or pandas.DataFrame or numpy.ndarray or, \ 

21 a list of str or pathlib.Path to a TSV or CSV \ 

22 or pandas.DataFrame or numpy.ndarray 

23 In the case of CSV file, 

24 the first column is considered to be index column. 

25 numpy.ndarray will not be appended to the output. 

26 

27 var_name : str 

28 name of the `tables_to_check` passed, 

29 to print in the error message 

30 

31 Returns 

32 ------- 

33 list of pandas.DataFrame or numpy.arrays 

34 

35 Raises 

36 ------ 

37 TypeError 

38 If any of the elements in `tables_to_check` does not have a correct type. 

39 ValueError 

40 If a specified path in `tables_to_check` 

41 cannot be loaded to a pandas.DataFrame. 

42 

43 """ 

44 if not isinstance(tables_to_check, list): 

45 tables_to_check = [tables_to_check] 

46 

47 tables = [] 

48 for table_idx, table in enumerate(tables_to_check): 

49 table = stringify_path(table) 

50 

51 if not isinstance(table, (str, pd.DataFrame, np.ndarray)): 

52 raise TypeError( 

53 f"{var_name} can only be a pandas DataFrame, " 

54 "a Path object or a string, or a numpy array. " 

55 f"A {type(table)} was provided at idx {table_idx}" 

56 ) 

57 

58 if isinstance(table, str): 

59 loaded = _read_events_table(table) 

60 tables.append(loaded) 

61 elif isinstance(table, (pd.DataFrame, np.ndarray)): 

62 tables.append(table) 

63 

64 return tables 

65 

66 

67def _read_events_table(table_path): 

68 """Load the contents of the event file specified by `table_path`\ 

69 to a pandas.DataFrame. 

70 

71 

72 Parameters 

73 ---------- 

74 table_path : :obj:`str`, :obj:`pathlib.Path` 

75 Path to a TSV or CSV file. In the case of CSV file, 

76 the first column is considered to be index column. 

77 

78 Returns 

79 ------- 

80 pandas.Dataframe 

81 Pandas Dataframe with events data loaded from file. 

82 

83 Raises 

84 ------ 

85 ValueError 

86 If file loading fails. 

87 """ 

88 table_path = Path(table_path) 

89 if table_path.suffix == ".tsv": 

90 loaded = pd.read_csv(table_path, sep="\t") 

91 elif table_path.suffix == ".csv": 

92 loaded = pd.read_csv(table_path) 

93 else: 

94 raise ValueError( 

95 f"Tables to load can only be TSV or CSV.\nGot {table_path}" 

96 ) 

97 return loaded 

98 

99 

100def coerce_to_dict(input_arg): 

101 """Construct a dict from the provided arg. 

102 

103 If input_arg is: 

104 dict or None then returns it unchanged. 

105 

106 string or collection of Strings or Sequence[int], 

107 returns a dict {str(value): value, ...} 

108 

109 Parameters 

110 ---------- 

111 input_arg : String or Collection[str or Int or Sequence[Int]] 

112 or Dict[str, str or np.array] or None 

113 Can be of the form: 

114 'string' 

115 ['string_1', 'string_2', ...] 

116 list/array 

117 [list/array_1, list/array_2, ...] 

118 {'string_1': list/array1, ...} 

119 

120 Returns 

121 ------- 

122 input_args: Dict[str, np.array or str] or None 

123 

124 """ 

125 if input_arg is None: 

126 return None 

127 if not isinstance(input_arg, dict): 

128 if ( 

129 isinstance(input_arg, Iterable) 

130 and not isinstance(input_arg[0], Iterable) 

131 ) or isinstance(input_arg, str): 

132 input_arg = [input_arg] 

133 input_arg = {str(contrast_): contrast_ for contrast_ in input_arg} 

134 return input_arg 

135 

136 

137def make_stat_maps( 

138 model, contrasts, output_type="z_score", first_level_contrast=None 

139): 

140 """Given a model and contrasts, return the corresponding z-maps. 

141 

142 Parameters 

143 ---------- 

144 model : FirstLevelModel or SecondLevelModel object 

145 Must have a fitted design matrix(ces). 

146 

147 contrasts : Dict[str, ndarray or str] 

148 Dict of contrasts for a first or second level model. 

149 Corresponds to the contrast_def for the FirstLevelModel 

150 (nilearn.glm.first_level.FirstLevelModel.compute_contrast) 

151 & second_level_contrast for a SecondLevelModel 

152 (nilearn.glm.second_level.SecondLevelModel.compute_contrast) 

153 

154 output_type : :obj:`str`, default='z_score' 

155 The type of statistical map to retain from the contrast. 

156 

157 .. versionadded:: 0.9.2 

158 

159 %(first_level_contrast)s 

160 

161 .. versionadded:: 0.11.2dev 

162 

163 Returns 

164 ------- 

165 statistical_maps : Dict[str, niimg] or Dict[str, Dict[str, niimg]] 

166 Dict of statistical z-maps keyed to contrast names/titles. 

167 

168 See Also 

169 -------- 

170 nilearn.glm.first_level.FirstLevelModel.compute_contrast 

171 nilearn.glm.second_level.SecondLevelModel.compute_contrast 

172 

173 """ 

174 from nilearn.glm.second_level import SecondLevelModel 

175 

176 if isinstance(model, SecondLevelModel): 

177 return { 

178 contrast_name: model.compute_contrast( 

179 contrast_data, 

180 output_type=output_type, 

181 first_level_contrast=first_level_contrast, 

182 ) 

183 for contrast_name, contrast_data in contrasts.items() 

184 } 

185 

186 return { 

187 contrast_name: model.compute_contrast( 

188 contrast_data, 

189 output_type=output_type, 

190 ) 

191 for contrast_name, contrast_data in contrasts.items() 

192 }