Coverage for nilearn/interfaces/fmriprep/tests/_testing.py: 11%

66 statements  

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

1"""Utility functions for testing load_confounds.""" 

2 

3import json 

4from pathlib import Path 

5 

6import pandas as pd 

7 

8from nilearn.interfaces.bids.utils import bids_entities, create_bids_filename 

9from nilearn.interfaces.fmriprep import load_confounds_utils 

10 

11img_file_patterns = { 

12 "ica_aroma": { 

13 "entities": { 

14 "space": "MNI152NLin2009cAsym", 

15 "desc": "smoothAROMAnonaggr", 

16 } 

17 }, 

18 "regular": { 

19 "entities": {"space": "MNI152NLin2009cAsym", "desc": "preproc"} 

20 }, 

21 "res": { 

22 "entities": { 

23 "space": "MNI152NLin2009cAsym", 

24 "res": "2", 

25 "desc": "preproc", 

26 } 

27 }, 

28 "native": {"entities": {"desc": "preproc"}}, 

29 "cifti": { 

30 "entities": {"desc": "preproc", "space": "fsLR", "den": "91k"}, 

31 "extension": "dtseries.nii", 

32 }, 

33 "den": {"entities": {"space": "fsLR", "den": "32k", "desc": "preproc"}}, 

34 "part": { 

35 "entities": { 

36 "part": "mag", 

37 "space": "MNI152NLin2009cAsym", 

38 "desc": "preproc", 

39 } 

40 }, 

41 "gifti": ( 

42 { 

43 "entities": {"hemi": "L", "space": "fsaverage5"}, 

44 "extension": "func.gii", 

45 }, 

46 { 

47 "entities": {"hemi": "R", "space": "fsaverage5"}, 

48 "extension": "func.gii", 

49 }, 

50 ), 

51} 

52 

53 

54def get_testdata_path(non_steady_state=True, fmriprep_version="1.4.x"): 

55 """Get file path for the confound regressors.""" 

56 derivative = "regressors" if fmriprep_version != "21.x.x" else "timeseries" 

57 path_data = Path(load_confounds_utils.__file__).parent / "data" 

58 suffix = "test-v21" if fmriprep_version == "21.x.x" else "test" 

59 if non_steady_state: 

60 return [ 

61 path_data / filename 

62 for filename in [ 

63 f"{suffix}_desc-confounds_{derivative}.tsv", 

64 f"{suffix}_desc-confounds_{derivative}.json", 

65 ] 

66 ] 

67 else: 

68 return [ 

69 path_data / filename 

70 for filename in [ 

71 f"no_nonsteady_desc-confounds_{derivative}.tsv", 

72 f"test_desc-confounds_{derivative}.json", 

73 ] 

74 ] 

75 

76 

77def create_tmp_filepath( 

78 base_path, 

79 image_type="regular", 

80 bids_fields=None, 

81 copy_confounds=False, 

82 copy_json=False, 

83 fmriprep_version="1.4.x", 

84): 

85 entities_to_include = [ 

86 *bids_entities()["raw"], 

87 *bids_entities()["derivatives"], 

88 ] 

89 if bids_fields is None: 

90 bids_fields = { 

91 "entities": { 

92 "sub": fmriprep_version.replace(".", ""), 

93 "task": "test", 

94 } 

95 } 

96 

97 # create test files in temporary directory 

98 derivative = "regressors" if fmriprep_version == "1.2.x" else "timeseries" 

99 

100 # confound files 

101 bids_fields["entities"]["desc"] = "confounds" 

102 bids_fields["suffix"] = derivative 

103 bids_fields["extension"] = "tsv" 

104 confounds_filename = create_bids_filename( 

105 fields=bids_fields, entities_to_include=entities_to_include 

106 ) 

107 tmp_conf = base_path / confounds_filename 

108 

109 if copy_confounds: 

110 conf, meta = get_legal_confound(fmriprep_version=fmriprep_version) 

111 conf.to_csv(tmp_conf, sep="\t", index=False) 

112 else: 

113 tmp_conf.touch() 

114 

115 if copy_json: 

116 bids_fields["extension"] = "json" 

117 confounds_sidecar = create_bids_filename( 

118 fields=bids_fields, entities_to_include=entities_to_include 

119 ) 

120 tmp_meta = base_path / confounds_sidecar 

121 conf, meta = get_legal_confound(fmriprep_version=fmriprep_version) 

122 with tmp_meta.open("w") as file: 

123 json.dump(meta, file, indent=2) 

124 

125 # image data 

126 # convert path object to string as nibabel do strings 

127 img_file_patterns_type = img_file_patterns[image_type] 

128 if type(img_file_patterns_type) is dict: 

129 bids_fields = update_bids_fields(bids_fields, img_file_patterns_type) 

130 tmp_img = create_bids_filename( 

131 fields=bids_fields, entities_to_include=entities_to_include 

132 ) 

133 tmp_img = base_path / tmp_img 

134 tmp_img.touch() 

135 tmp_img = str(tmp_img) 

136 else: 

137 tmp_img = [] 

138 for root in img_file_patterns_type: 

139 bids_fields = update_bids_fields(bids_fields, root) 

140 tmp_gii = create_bids_filename( 

141 fields=bids_fields, entities_to_include=entities_to_include 

142 ) 

143 tmp_gii = base_path / tmp_gii 

144 tmp_gii.touch() 

145 tmp_img.append(str(tmp_gii)) 

146 return tmp_img, tmp_conf 

147 

148 

149def get_legal_confound(non_steady_state=True, fmriprep_version="1.4.x"): 

150 """Load the valid confound files for manipulation.""" 

151 conf, meta = get_testdata_path( 

152 non_steady_state=non_steady_state, fmriprep_version=fmriprep_version 

153 ) 

154 conf = pd.read_csv(conf, delimiter="\t", encoding="utf-8") 

155 with meta.open() as file: 

156 meta = json.load(file) 

157 return conf, meta 

158 

159 

160def update_bids_fields(bids_fields, img_file_patterns_type): 

161 """Update the bids_fields dictionary with the img_file_patterns_type.""" 

162 if "extension" not in img_file_patterns_type: 

163 bids_fields["extension"] = "nii.gz" 

164 if "suffix" not in img_file_patterns_type: 

165 bids_fields["suffix"] = "bold" 

166 for key in img_file_patterns_type: 

167 if key == "entities": 

168 for entity in img_file_patterns_type["entities"]: 

169 bids_fields["entities"][entity] = img_file_patterns_type[ 

170 "entities" 

171 ][entity] 

172 else: 

173 bids_fields[key] = img_file_patterns_type[key] 

174 return bids_fields