Coverage for nilearn/plotting/surface/tests/test_utils.py: 0%
86 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._utils functions."""
3from pathlib import Path
5import numpy as np
6import pytest
7from numpy.testing import assert_array_equal
9from nilearn._utils.helpers import (
10 is_matplotlib_installed,
11 is_plotly_installed,
12)
13from nilearn.plotting.surface._utils import (
14 _check_hemisphere_is_valid,
15 _check_view_is_valid,
16 check_surface_plotting_inputs,
17 get_faces_on_edge,
18 get_surface_backend,
19)
20from nilearn.surface import InMemoryMesh, load_surf_mesh
21from nilearn.surface.utils import assert_surface_mesh_equal
24@pytest.mark.parametrize(
25 "view,is_valid",
26 [
27 ("lateral", True),
28 ("medial", True),
29 ("latreal", False),
30 ((100, 100), True),
31 ([100.0, 100.0], True),
32 ((100, 100, 1), False),
33 (("lateral", "medial"), False),
34 ([100, "bar"], False),
35 ],
36)
37def test_check_view_is_valid(view, is_valid):
38 assert _check_view_is_valid(view) is is_valid
41@pytest.mark.parametrize(
42 "hemi,is_valid",
43 [
44 ("left", True),
45 ("right", True),
46 ("both", True),
47 ("lft", False),
48 ],
49)
50def test_check_hemisphere_is_valid(hemi, is_valid):
51 assert _check_hemisphere_is_valid(hemi) is is_valid
54@pytest.mark.parametrize("bg_map", ["some_path", Path("some_path"), None])
55@pytest.mark.parametrize("surf_map", ["some_path", Path("some_path")])
56@pytest.mark.parametrize("surf_mesh", ["some_path", Path("some_path")])
57def test_check_surface_plotting_inputs_no_change(surf_map, surf_mesh, bg_map):
58 """Cover use cases where the inputs are not changed."""
59 hemi = "left"
60 out_surf_map, out_surf_mesh, out_bg_map = check_surface_plotting_inputs(
61 surf_map, surf_mesh, hemi, bg_map
62 )
63 assert surf_map == out_surf_map
64 assert surf_mesh == out_surf_mesh
65 assert bg_map == out_bg_map
68@pytest.mark.parametrize("bg_map", ["some_path", Path("some_path"), None])
69@pytest.mark.parametrize("mesh", [None])
70def test_check_surface_plotting_inputs_extract_mesh_and_data(
71 surf_img_1d, mesh, bg_map
72):
73 """Extract mesh and data when a SurfaceImage is passed."""
74 hemi = "left"
75 out_surf_map, out_surf_mesh, out_bg_map = check_surface_plotting_inputs(
76 surf_map=surf_img_1d,
77 surf_mesh=mesh,
78 hemi=hemi,
79 bg_map=bg_map,
80 )
82 assert_array_equal(out_surf_map, surf_img_1d.data.parts[hemi].T)
83 assert_surface_mesh_equal(out_surf_mesh, surf_img_1d.mesh.parts[hemi])
85 assert bg_map == out_bg_map
88def test_check_surface_plotting_inputs_many_time_points(
89 surf_img_1d, surf_img_2d
90):
91 """Extract mesh and data when a SurfaceImage is passed."""
92 with pytest.raises(
93 TypeError, match="Input data has incompatible dimensionality"
94 ):
95 check_surface_plotting_inputs(
96 surf_map=surf_img_2d(10),
97 surf_mesh=None,
98 hemi="left",
99 bg_map=None,
100 )
102 with pytest.raises(
103 TypeError, match="Input data has incompatible dimensionality"
104 ):
105 check_surface_plotting_inputs(
106 surf_map=surf_img_1d,
107 surf_mesh=None,
108 hemi="left",
109 bg_map=surf_img_2d(10),
110 )
113@pytest.mark.parametrize("bg_map", ["some_path", Path("some_path"), None])
114def test_check_surface_plotting_inputs_extract_mesh_from_polymesh(
115 surf_img_1d, surf_mesh, bg_map
116):
117 """Extract mesh from Polymesh and data from SurfaceImage."""
118 hemi = "left"
119 out_surf_map, out_surf_mesh, out_bg_map = check_surface_plotting_inputs(
120 surf_map=surf_img_1d,
121 surf_mesh=surf_mesh,
122 hemi=hemi,
123 bg_map=bg_map,
124 )
125 assert_array_equal(out_surf_map, surf_img_1d.data.parts[hemi].T)
126 assert_surface_mesh_equal(out_surf_mesh, surf_mesh.parts[hemi])
127 assert bg_map == out_bg_map
130def test_check_surface_plotting_inputs_extract_bg_map_data(
131 surf_img_1d, surf_mesh
132):
133 """Extract background map data."""
134 hemi = "left"
135 _, _, out_bg_map = check_surface_plotting_inputs(
136 surf_map=surf_img_1d,
137 surf_mesh=surf_mesh,
138 hemi=hemi,
139 bg_map=surf_img_1d,
140 )
141 assert_array_equal(out_bg_map, surf_img_1d.data.parts[hemi])
144def test_check_surface_plotting_inputs_error_mash_and_data_none():
145 """Fail if no mesh or data is passed."""
146 with pytest.raises(TypeError, match="cannot both be None"):
147 check_surface_plotting_inputs(None, None)
150def test_check_surface_plotting_inputs_errors(surf_img_1d):
151 """Fail if mesh is none and data is not not SurfaceImage."""
152 with pytest.raises(TypeError, match="must be a SurfaceImage instance"):
153 check_surface_plotting_inputs(surf_map=1, surf_mesh=None)
154 with pytest.raises(
155 TypeError, match="'surf_mesh' cannot be a SurfaceImage instance."
156 ):
157 check_surface_plotting_inputs(
158 surf_map=surf_img_1d, surf_mesh=surf_img_1d
159 )
162def test_check_surface_plotting_hemi_both_all_inputs(surf_img_1d, surf_mesh):
163 """Test that hemi="both" works as expected when all inputs are provided."""
164 hemi = "both"
165 combined_map, combined_mesh, combined_bg = check_surface_plotting_inputs(
166 surf_map=surf_img_1d,
167 surf_mesh=surf_mesh,
168 hemi=hemi,
169 bg_map=surf_img_1d,
170 )
171 # check that the data is concatenated
172 for data in [combined_map, combined_bg]:
173 assert_array_equal(
174 data,
175 np.concatenate(
176 (
177 surf_img_1d.data.parts["left"],
178 surf_img_1d.data.parts["right"],
179 )
180 ),
181 )
182 assert isinstance(data, np.ndarray)
183 # check that the mesh is concatenated
184 assert combined_mesh.n_vertices == surf_mesh.n_vertices
185 assert isinstance(combined_mesh, InMemoryMesh)
188def test_check_surface_plotting_hemi_both_mesh_none(surf_img_1d):
189 """Test that hemi="both" works as expected when mesh is not provided."""
190 hemi = "both"
191 combined_map, combined_mesh, combined_bg = check_surface_plotting_inputs(
192 surf_map=surf_img_1d,
193 surf_mesh=None,
194 hemi=hemi,
195 )
196 # check that the mesh is taken from surf_map
197 assert combined_mesh.n_vertices == surf_img_1d.mesh.n_vertices
198 assert isinstance(combined_mesh, InMemoryMesh)
201def test_check_surface_plotting_hemi_error(surf_img_1d, surf_mesh):
202 """Test that an error is raised when hemi is not valid."""
203 with pytest.raises(
204 ValueError, match="hemi must be one of 'left', 'right' or 'both'"
205 ):
206 check_surface_plotting_inputs(
207 surf_map=surf_img_1d, surf_mesh=surf_mesh, hemi="foo"
208 )
211def test_get_faces_on_edge_matplotlib(in_memory_mesh):
212 _, faces = load_surf_mesh(in_memory_mesh)
213 with pytest.raises(
214 ValueError, match=("Vertices in parcellation do not form region.")
215 ):
216 get_faces_on_edge(faces, [91])
219@pytest.mark.skipif(
220 is_matplotlib_installed(),
221 reason="This test is run only if matplotlib is not installed.",
222)
223def test_get_surface_backend_matplotlib_not_installed():
224 """Tests to see if get_surface_backend raises error when matplotlib is not
225 installed.
226 """
227 with pytest.raises(ImportError, match="Using engine"):
228 get_surface_backend("matplotlib")
231@pytest.mark.skipif(
232 is_plotly_installed(),
233 reason="This test is run only if plotly is not installed.",
234)
235def test_get_surface_backend_plotly_not_installed():
236 """Tests to see if get_surface_backend raises error when plotly is not
237 installed.
238 """
239 with pytest.raises(ImportError, match="Using engine"):
240 get_surface_backend("plotly")
243def test_get_surface_backend_unknown_error():
244 """Tests to see if get_surface_backend raises error when the specified
245 backend is not implemented.
246 """
247 with pytest.raises(ValueError, match="Unknown plotting engine"):
248 get_surface_backend("unknown")