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
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-16 12:32 +0200
1"""Test nilearn.plotting.surface.html_surface functions."""
3import json
5import numpy as np
6import pytest
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)
33@pytest.fixture(scope="session")
34def mni152_template_res_2():
35 return datasets.load_mni152_template(resolution=2)
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)
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"])
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)
82def test_full_brain_info(mni152_template_res_2):
83 surfaces = datasets.fetch_surf_fsaverage()
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 )
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)
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
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 )
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)
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)
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)
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)
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
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)
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)
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))
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])