Coverage for nilearn/plotting/surface/tests/test_html_surface.py: 0%

119 statements  

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

1"""Test nilearn.plotting.surface.html_surface functions.""" 

2 

3import json 

4 

5import numpy as np 

6import pytest 

7 

8from nilearn import datasets, image 

9from nilearn._utils.exceptions import DimensionError 

10from nilearn.datasets import fetch_surf_fsaverage 

11from nilearn.image import get_data 

12from nilearn.plotting.js_plotting_utils import decode 

13from nilearn.plotting.surface.html_surface import ( 

14 _fill_html_template, 

15 _full_brain_info, 

16 _one_mesh_info, 

17 full_brain_info, 

18 one_mesh_info, 

19 view_img_on_surf, 

20 view_surf, 

21) 

22from nilearn.plotting.tests.test_js_plotting_utils import ( 

23 check_colors, 

24 check_html, 

25) 

26from nilearn.surface.surface import ( 

27 check_mesh_is_fsaverage, 

28 load_surf_data, 

29 load_surf_mesh, 

30) 

31 

32 

33@pytest.fixture(scope="session") 

34def mni152_template_res_2(): 

35 return datasets.load_mni152_template(resolution=2) 

36 

37 

38def test_check_mesh(): 

39 mesh = check_mesh_is_fsaverage("fsaverage5") 

40 assert mesh is check_mesh_is_fsaverage(mesh) 

41 with pytest.raises(ValueError): 

42 check_mesh_is_fsaverage("fsaverage2") 

43 mesh.pop("pial_left") 

44 with pytest.raises(ValueError): 

45 check_mesh_is_fsaverage(mesh) 

46 with pytest.raises(TypeError): 

47 check_mesh_is_fsaverage(load_surf_mesh(mesh["pial_right"])) 

48 mesh = datasets.fetch_surf_fsaverage() 

49 assert mesh is check_mesh_is_fsaverage(mesh) 

50 

51 

52def test_one_mesh_info(): 

53 fsaverage = datasets.fetch_surf_fsaverage() 

54 mesh = fsaverage["pial_left"] 

55 surf_map = load_surf_data(fsaverage["sulc_left"]) 

56 mesh = load_surf_mesh(mesh) 

57 info = _one_mesh_info( 

58 surf_map, mesh, "90%", black_bg=True, bg_map=surf_map 

59 ) 

60 assert {"_x", "_y", "_z", "_i", "_j", "_k"}.issubset( 

61 info["inflated_both"].keys() 

62 ) 

63 assert len(decode(info["inflated_both"]["_x"], "<f4")) == len(surf_map) 

64 assert len(info["vertexcolor_both"]) == len(surf_map) 

65 cmax = np.max(np.abs(surf_map)) 

66 assert (info["cmin"], info["cmax"]) == (-cmax, cmax) 

67 assert isinstance(info["cmax"], float) 

68 json.dumps(info) 

69 assert info["black_bg"] 

70 assert not info["full_brain_mesh"] 

71 check_colors(info["colorscale"]) 

72 

73 with pytest.warns( 

74 DeprecationWarning, 

75 match="one_mesh_info is a private function and is renamed " 

76 "to _one_mesh_info. Using the deprecated name will " 

77 "raise an error in release 0.13", 

78 ): 

79 one_mesh_info(surf_map, mesh) 

80 

81 

82def test_full_brain_info(mni152_template_res_2): 

83 surfaces = datasets.fetch_surf_fsaverage() 

84 

85 info = _full_brain_info(mni152_template_res_2, surfaces) 

86 check_colors(info["colorscale"]) 

87 assert { 

88 "pial_left", 

89 "pial_right", 

90 "inflated_left", 

91 "inflated_right", 

92 "vertexcolor_left", 

93 "vertexcolor_right", 

94 }.issubset(info.keys()) 

95 assert info["cmin"] == -info["cmax"] 

96 assert info["full_brain_mesh"] 

97 assert not info["black_bg"] 

98 assert isinstance(info["cmax"], float) 

99 json.dumps(info) 

100 for hemi in ["left", "right"]: 

101 mesh = load_surf_mesh(surfaces[f"pial_{hemi}"]) 

102 assert len(info[f"vertexcolor_{hemi}"]) == len(mesh.coordinates) 

103 assert len(decode(info[f"inflated_{hemi}"]["_z"], "<f4")) == len( 

104 mesh.coordinates 

105 ) 

106 assert len(decode(info[f"pial_{hemi}"]["_j"], "<i4")) == len( 

107 mesh.faces 

108 ) 

109 

110 with pytest.warns( 

111 DeprecationWarning, 

112 match="full_brain_info is a private function and is renamed to " 

113 "_full_brain_info. Using the deprecated name will raise an error " 

114 "in release 0.13", 

115 ): 

116 full_brain_info(mni152_template_res_2) 

117 

118 

119def test_fill_html_template(tmp_path, mni152_template_res_2): 

120 fsaverage = fetch_surf_fsaverage() 

121 mesh = load_surf_mesh(fsaverage["pial_right"]) 

122 surf_map = mesh.coordinates[:, 0] 

123 info = _one_mesh_info( 

124 surf_map, 

125 fsaverage["pial_right"], 

126 "90%", 

127 black_bg=True, 

128 bg_map=fsaverage["sulc_right"], 

129 ) 

130 info["title"] = None 

131 html = _fill_html_template(info, embed_js=False) 

132 check_html(tmp_path, html) 

133 assert "jquery.min.js" in html.html 

134 info = _full_brain_info(mni152_template_res_2) 

135 info["title"] = None 

136 html = _fill_html_template(info) 

137 check_html(tmp_path, html) 

138 assert "* plotly.js (gl3d - minified) v1." in html.html 

139 

140 

141def test_view_surf(tmp_path, rng): 

142 fsaverage = fetch_surf_fsaverage() 

143 mesh = load_surf_mesh(fsaverage["pial_right"]) 

144 surf_map = mesh.coordinates[:, 0] 

145 html = view_surf( 

146 fsaverage["pial_right"], surf_map, fsaverage["sulc_right"], "90%" 

147 ) 

148 check_html(tmp_path, html, title="Surface plot") 

149 html = view_surf( 

150 fsaverage["pial_right"], 

151 surf_map, 

152 fsaverage["sulc_right"], 

153 0.3, 

154 title="SOME_TITLE", 

155 ) 

156 check_html(tmp_path, html, title="SOME_TITLE") 

157 assert "SOME_TITLE" in html.html 

158 html = view_surf(fsaverage["pial_right"]) 

159 check_html(tmp_path, html) 

160 atlas = rng.integers(0, 10, size=len(mesh.coordinates)) 

161 html = view_surf(fsaverage["pial_left"], atlas, symmetric_cmap=False) 

162 check_html(tmp_path, html) 

163 html = view_surf( 

164 fsaverage["pial_right"], 

165 fsaverage["sulc_right"], 

166 threshold=None, 

167 cmap="Greys", 

168 ) 

169 check_html(tmp_path, html) 

170 with pytest.raises(ValueError): 

171 view_surf(mesh, mesh.coordinates[::2, 0]) 

172 with pytest.raises(ValueError): 

173 view_surf( 

174 mesh, mesh.coordinates[:, 0], bg_map=mesh.coordinates[::2, 0] 

175 ) 

176 

177 

178def test_view_img_on_surf(tmp_path, mni152_template_res_2): 

179 html = view_img_on_surf(mni152_template_res_2, threshold="92.3%") 

180 check_html(tmp_path, html) 

181 

182 surfaces = datasets.fetch_surf_fsaverage() 

183 html = view_img_on_surf( 

184 mni152_template_res_2, threshold=0, surf_mesh=surfaces 

185 ) 

186 check_html(tmp_path, html) 

187 

188 html = view_img_on_surf( 

189 mni152_template_res_2, threshold=0.4, title="SOME_TITLE" 

190 ) 

191 assert "SOME_TITLE" in html.html 

192 check_html(tmp_path, html) 

193 

194 html = view_img_on_surf( 

195 mni152_template_res_2, threshold=0.4, cmap="hot", black_bg=True 

196 ) 

197 check_html(tmp_path, html) 

198 

199 img_4d = image.new_img_like( 

200 mni152_template_res_2, 

201 get_data(mni152_template_res_2)[:, :, :, np.newaxis], 

202 ) 

203 assert len(img_4d.shape) == 4 

204 

205 np.clip( 

206 get_data(mni152_template_res_2), 

207 0, 

208 None, 

209 out=get_data(mni152_template_res_2), 

210 ) 

211 html = view_img_on_surf(mni152_template_res_2, symmetric_cmap=False) 

212 check_html(tmp_path, html) 

213 

214 html = view_img_on_surf( 

215 mni152_template_res_2, 

216 symmetric_cmap=False, 

217 vol_to_surf_kwargs={ 

218 "n_samples": 1, 

219 "radius": 0.0, 

220 "interpolation": "nearest", 

221 }, 

222 ) 

223 check_html(tmp_path, html) 

224 

225 

226def test_view_img_on_surf_input_as_file(img_3d_mni_as_file): 

227 view_img_on_surf(img_3d_mni_as_file) 

228 view_img_on_surf(str(img_3d_mni_as_file)) 

229 

230 

231def test_view_img_on_surf_errors(img_3d_mni): 

232 with pytest.raises(DimensionError): 

233 view_img_on_surf([img_3d_mni, img_3d_mni])