def test_plot_surf_stat_map(): mesh = generate_surf() rng = np.random.RandomState(0) bg = rng.randn(mesh[0].shape[0], ) data = 10 * rng.randn(mesh[0].shape[0], ) # Plot mesh with stat map plot_surf_stat_map(mesh, stat_map=data) plot_surf_stat_map(mesh, stat_map=data, colorbar=True) plot_surf_stat_map(mesh, stat_map=data, alpha=1) # Plot mesh with background and stat map plot_surf_stat_map(mesh, stat_map=data, bg_map=bg) plot_surf_stat_map(mesh, stat_map=data, bg_map=bg, bg_on_data=True, darkness=0.5) plot_surf_stat_map(mesh, stat_map=data, bg_map=bg, colorbar=True, bg_on_data=True, darkness=0.5) # Apply threshold plot_surf_stat_map(mesh, stat_map=data, bg_map=bg, bg_on_data=True, darkness=0.5, threshold=0.3) plot_surf_stat_map(mesh, stat_map=data, bg_map=bg, colorbar=True, bg_on_data=True, darkness=0.5, threshold=0.3) # Change vmax plot_surf_stat_map(mesh, stat_map=data, vmax=5) plot_surf_stat_map(mesh, stat_map=data, vmax=5, colorbar=True) # Change colormap plot_surf_stat_map(mesh, stat_map=data, cmap='cubehelix') plot_surf_stat_map(mesh, stat_map=data, cmap='cubehelix', colorbar=True) # Plot to axes axes = plt.subplots(ncols=2, subplot_kw={'projection': '3d'})[1] for ax in axes.flatten(): plot_surf_stat_map(mesh, stat_map=data, ax=ax) axes = plt.subplots(ncols=2, subplot_kw={'projection': '3d'})[1] for ax in axes.flatten(): plot_surf_stat_map(mesh, stat_map=data, ax=ax, colorbar=True) fig = plot_surf_stat_map(mesh, stat_map=data, colorbar=False) assert len(fig.axes) == 1 # symmetric_cbar fig = plot_surf_stat_map( mesh, stat_map=data, colorbar=True, symmetric_cbar=True) assert len(fig.axes) == 2 yticklabels = fig.axes[1].get_yticklabels() first, last = yticklabels[0].get_text(), yticklabels[-1].get_text() assert float(first) == - float(last) # no symmetric_cbar fig = plot_surf_stat_map( mesh, stat_map=data, colorbar=True, symmetric_cbar=False) assert len(fig.axes) == 2 yticklabels = fig.axes[1].get_yticklabels() first, last = yticklabels[0].get_text(), yticklabels[-1].get_text() assert float(first) != - float(last) # Save execution time and memory plt.close()
def test_plot_surf_roi(): mesh = generate_surf() rng = np.random.RandomState(0) roi_idx = rng.randint(0, mesh[0].shape[0], size=10) roi_map = np.zeros(mesh[0].shape[0]) roi_map[roi_idx] = 1 parcellation = rng.rand(mesh[0].shape[0]) # plot roi plot_surf_roi(mesh, roi_map=roi_map) plot_surf_roi(mesh, roi_map=roi_map, colorbar=True) # plot parcellation plot_surf_roi(mesh, roi_map=parcellation) plot_surf_roi(mesh, roi_map=parcellation, colorbar=True) # plot to axes plot_surf_roi(mesh, roi_map=roi_map, ax=None, figure=plt.gcf()) # plot to axes with tempfile.NamedTemporaryFile() as tmp_file: plot_surf_roi(mesh, roi_map=roi_map, ax=plt.gca(), figure=None, output_file=tmp_file.name) with tempfile.NamedTemporaryFile() as tmp_file: plot_surf_roi(mesh, roi_map=roi_map, ax=plt.gca(), figure=None, output_file=tmp_file.name, colorbar=True) # Save execution time and memory plt.close()
def test_plot_surf_error(engine): if not PLOTLY_INSTALLED and engine == "plotly": pytest.skip('Plotly is not installed; required for this test.') mesh = generate_surf() rng = np.random.RandomState(42) # Wrong inputs for view or hemi with pytest.raises(ValueError, match='view must be one of'): plot_surf(mesh, view='middle', engine=engine) with pytest.raises(ValueError, match='hemi must be one of'): plot_surf(mesh, hemi='lft', engine=engine) # Wrong size of background image with pytest.raises( ValueError, match='bg_map does not have the same number of vertices'): plot_surf(mesh, bg_map=rng.standard_normal(size=mesh[0].shape[0] - 1), engine=engine) # Wrong size of surface data with pytest.raises( ValueError, match="surf_map does not have the same number of vertices"): plot_surf(mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0] + 1), engine=engine) with pytest.raises(ValueError, match="'surf_map' can only have one dimension"): plot_surf(mesh, surf_map=rng.standard_normal(size=(mesh[0].shape[0], 2)), engine=engine)
def test_plot_surf_contours(): mesh = generate_surf() # we need a valid parcellation for testing parcellation = np.zeros((mesh[0].shape[0], )) parcellation[mesh[1][3]] = 1 parcellation[mesh[1][5]] = 2 plot_surf_contours(mesh, parcellation) plot_surf_contours(mesh, parcellation, levels=[1, 2]) plot_surf_contours(mesh, parcellation, levels=[1, 2], cmap='gist_ncar') plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=['r', 'g']) plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=['r', 'g'], labels=['1', '2']) fig = plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=['r', 'g'], labels=['1', '2'], legend=True) assert fig.legends is not None plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=[[0, 0, 0, 1], [1, 1, 1, 1]]) fig, axes = plt.subplots(1, 1, subplot_kw={'projection': '3d'}) plot_surf_contours(mesh, parcellation, axes=axes) plot_surf_contours(mesh, parcellation, figure=fig) fig = plot_surf(mesh) plot_surf_contours(mesh, parcellation, figure=fig) plot_surf_contours(mesh, parcellation, title='title') with tempfile.NamedTemporaryFile() as tmp_file: plot_surf_contours(mesh, parcellation, output_file=tmp_file.name) plt.close()
def test_plot_surf_stat_map_error(): mesh = generate_surf() rng = np.random.RandomState(0) data = 10 * rng.randn(mesh[0].shape[0], ) # Try to input vmin assert_raises_regex(ValueError, 'this function does not accept a "vmin" argument', plot_surf_stat_map, mesh, stat_map=data, vmin=0) # Wrong size of stat map data assert_raises_regex(ValueError, 'surf_map does not have the same number of vertices', plot_surf_stat_map, mesh, stat_map=np.hstack((data, data))) assert_raises_regex(ValueError, 'surf_map can only have one dimension', plot_surf_stat_map, mesh, stat_map=np.vstack((data, data)).T)
def test_plot_surf_error(): mesh = generate_surf() rng = np.random.RandomState(0) # Wrong inputs for view or hemi with pytest.raises(ValueError, match='view must be one of'): plot_surf(mesh, view='middle') with pytest.raises(ValueError, match='hemi must be one of'): plot_surf(mesh, hemi='lft') # Wrong size of background image with pytest.raises( ValueError, match='bg_map does not have the same number of vertices'): plot_surf(mesh, bg_map=rng.randn(mesh[0].shape[0] - 1, )) # Wrong size of surface data with pytest.raises( ValueError, match='surf_map does not have the same number of vertices'): plot_surf(mesh, surf_map=rng.randn(mesh[0].shape[0] + 1, )) with pytest.raises(ValueError, match='surf_map can only have one dimension'): plot_surf(mesh, surf_map=rng.randn(mesh[0].shape[0], 2))
def test_plot_surf_contours_error(): mesh = generate_surf() # we need an invalid parcellation for testing rng = np.random.RandomState(0) invalid_parcellation = rng.rand(mesh[0].shape[0]) parcellation = np.zeros((mesh[0].shape[0], )) parcellation[mesh[1][3]] = 1 parcellation[mesh[1][5]] = 2 with pytest.raises(ValueError, match='Vertices in parcellation do not form region.'): plot_surf_contours(mesh, invalid_parcellation) fig, axes = plt.subplots(1, 1) with pytest.raises(ValueError, match='Axes must be 3D.'): plot_surf_contours(mesh, parcellation, axes=axes) with pytest.raises( ValueError, match= 'All elements of colors need to be either a matplotlib color string or RGBA values.' ): plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=[[1, 2], 3]) with pytest.raises( ValueError, match= 'Levels, labels, and colors argument need to be either the same length or None.' ): plot_surf_contours(mesh, parcellation, levels=[1, 2], colors=['r'], labels=['1', '2'])
def test_plot_surf(): mesh = generate_surf() rng = np.random.RandomState(42) bg = rng.standard_normal(size=mesh[0].shape[0]) # Plot mesh only plot_surf(mesh) # Plot mesh with background plot_surf(mesh, bg_map=bg) plot_surf(mesh, bg_map=bg, darkness=0.5) plot_surf(mesh, bg_map=bg, alpha=0.5) # Plot different views plot_surf(mesh, bg_map=bg, hemi='right') plot_surf(mesh, bg_map=bg, view='medial') plot_surf(mesh, bg_map=bg, hemi='right', view='medial') # Plot with colorbar plot_surf(mesh, bg_map=bg, colorbar=True) plot_surf(mesh, bg_map=bg, colorbar=True, cbar_vmin=0, cbar_vmax=150, cbar_tick_format="%i") # Save execution time and memory plt.close()
def test_plot_surf_error(): mesh = generate_surf() rng = np.random.RandomState(0) # Wrong inputs for view or hemi assert_raises_regex(ValueError, 'view must be one of', plot_surf, mesh, view='middle') assert_raises_regex(ValueError, 'hemi must be one of', plot_surf, mesh, hemi='lft') # Wrong size of background image assert_raises_regex(ValueError, 'bg_map does not have the same number of vertices', plot_surf, mesh, bg_map=rng.randn(mesh[0].shape[0] - 1, )) # Wrong size of surface data assert_raises_regex(ValueError, 'surf_map does not have the same number of vertices', plot_surf, mesh, surf_map=rng.randn(mesh[0].shape[0] + 1, )) assert_raises_regex(ValueError, 'surf_map can only have one dimension', plot_surf, mesh, surf_map=rng.randn(mesh[0].shape[0], 2))
def test_load_surface(): coords, faces = generate_surf() mesh = Mesh(coords, faces) data = mesh[0][:,0] surf = Surface(mesh, data) surf_like_obj = SurfaceLikeObject(mesh, data) # Load the surface from: # - Surface-like objects having the right attributes # - a list of length 2 (mesh, data) for loadings in [surf, surf_like_obj, [mesh, data]]: s = surface.load_surface(loadings) assert_array_equal(s.data, data) assert_array_equal(s.data, surf.data) assert_array_equal(s.mesh.coordinates, coords) assert_array_equal(s.mesh.coordinates, surf.mesh.coordinates) assert_array_equal(s.mesh.faces, surf.mesh.faces) # Giving an iterable of length other than 2 will raise an error # Length 3 with pytest.raises(ValueError, match="`load_surface` accepts iterables of length 2"): s = surface.load_surface([coords, faces, data]) # Length 1 with pytest.raises(ValueError, match="`load_surface` accepts iterables of length 2"): s = surface.load_surface([coords]) # Giving other objects will raise an error with pytest.raises(ValueError, match="Wrong parameter `surface` in `load_surface`"): s = surface.load_surface("foo")
def test_plot_surf_error(): mesh = generate_surf() rng = np.random.RandomState(0) # Wrong inputs for view or hemi assert_raises_regex(ValueError, 'view must be one of', plot_surf, mesh, view='middle') assert_raises_regex(ValueError, 'hemi must be one of', plot_surf, mesh, hemi='lft') # Wrong size of background image assert_raises_regex(ValueError, 'bg_map does not have the same number of vertices', plot_surf, mesh, bg_map=rng.randn(mesh[0].shape[0] - 1, )) # Wrong size of surface data assert_raises_regex(ValueError, 'surf_map does not have the same number of vertices', plot_surf, mesh, surf_map=rng.randn(mesh[0].shape[0] + 1, )) assert_raises_regex(ValueError, 'surf_map can only have one dimension', plot_surf, mesh, surf_map=rng.randn(mesh[0].shape[0], 2))
def test_check_surface(): coords, faces = generate_surf() mesh = Mesh(coords, faces) data = mesh[0][:,0] surf = Surface(mesh, data) s = surface.check_surface(surf) assert_array_equal(s.data, data) assert_array_equal(s.data, surf.data) assert_array_equal(s.mesh.coordinates, coords) assert_array_equal(s.mesh.coordinates, mesh.coordinates) assert_array_equal(s.mesh.faces, faces) assert_array_equal(s.mesh.faces, mesh.faces) # Generate faces such that max index is larger than # the length of coordinates array. rng = np.random.RandomState(42) wrong_faces = rng.randint(coords.shape[0] + 1, size=(30, 3)) wrong_mesh = Mesh(coords, wrong_faces) wrong_surface = Surface(wrong_mesh, data) # Check that check_mesh_and_data raises an error with the resulting wrong mesh with pytest.raises(ValueError, match="Mismatch between the indices of faces and the number of nodes."): surface.check_surface(wrong_surface) # Alter the data and check that an error is raised wrong_data = mesh[0][::2, 0] wrong_surface = Surface(mesh, wrong_data) with pytest.raises(ValueError, match="Mismatch between number of nodes in mesh"): surface.check_surface(wrong_surface)
def test_plot_surf_roi_error(): mesh = generate_surf() rng = np.random.RandomState(0) roi_idx = rng.randint(0, mesh[0].shape[0], size=5) with pytest.raises( ValueError, match='roi_map does not have the same number of vertices'): plot_surf_roi(mesh, roi_map=roi_idx)
def test_vol_to_surf(): # test 3d niimg to cortical surface projection and invariance to a change # of affine mni = datasets.load_mni152_template() mesh = generate_surf() _check_vol_to_surf_results(mni, mesh) fsaverage = datasets.fetch_surf_fsaverage().pial_left _check_vol_to_surf_results(mni, fsaverage)
def _generate_data_test_surf_roi(): mesh = generate_surf() rng = np.random.RandomState(42) roi_idx = rng.randint(0, mesh[0].shape[0], size=10) roi_map = np.zeros(mesh[0].shape[0]) roi_map[roi_idx] = 1 parcellation = rng.uniform(size=mesh[0].shape[0]) return mesh, roi_map, parcellation
def test_vol_to_surf(): # test 3d niimg to cortical surface projection and invariance to a change # of affine mni = datasets.load_mni152_template() mesh = generate_surf() _check_vol_to_surf_results(mni, mesh) fsaverage = datasets.fetch_surf_fsaverage().pial_left _check_vol_to_surf_results(mni, fsaverage)
def test_check_mesh_and_data(): mesh = generate_surf() data = mesh[0][:, 0] m, d = surface.check_mesh_and_data(mesh, data) assert (m[0] == mesh[0]).all() assert (m[1] == mesh[1]).all() assert (d == data).all() data = mesh[0][::2, 0] assert_raises(ValueError, surface.check_mesh_and_data, mesh, data)
def test_load_surf_mesh_file_freesurfer(): mesh = generate_surf() for suff in ['.pial', '.inflated', '.white', '.orig', 'sphere']: filename_fs_mesh = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_fs_mesh, mesh[0], mesh[1]) assert len(load_surf_mesh(filename_fs_mesh)) == 2 assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[0], mesh[0]) assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[1], mesh[1]) os.remove(filename_fs_mesh)
def test_check_mesh_and_data(): mesh = generate_surf() data = mesh[0][:, 0] m, d = surface.check_mesh_and_data(mesh, data) assert (m[0] == mesh[0]).all() assert (m[1] == mesh[1]).all() assert (d == data).all() data = mesh[0][::2, 0] assert_raises(ValueError, surface.check_mesh_and_data, mesh, data)
def test_plot_surf_roi_error(engine): if not PLOTLY_INSTALLED and engine == "plotly": pytest.skip('Plotly is not installed; required for this test.') mesh = generate_surf() rng = np.random.RandomState(42) roi_idx = rng.randint(0, mesh[0].shape[0], size=5) with pytest.raises( ValueError, match='roi_map does not have the same number of vertices'): plot_surf_roi(mesh, roi_map=roi_idx, engine=engine)
def test_plot_surf_roi_error(): mesh = generate_surf() rng = np.random.RandomState(0) roi_idx = rng.randint(0, mesh[0].shape[0], size=5) # Wrong input assert_raises_regex(ValueError, 'roi_map does not have the same number of vertices', plot_surf_roi, mesh, roi_map=roi_idx)
def test_load_surf_mesh_file_error(): # test if files with unexpected suffixes raise errors mesh = generate_surf() wrong_suff = ['.vtk', '.obj', '.mnc', '.txt'] for suff in wrong_suff: filename_wrong = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_wrong, mesh[0], mesh[1]) with pytest.raises(ValueError, match='input type is not recognized'): load_surf_mesh(filename_wrong) os.remove(filename_wrong)
def test_plot_surf_roi_error(): mesh = generate_surf() rng = np.random.RandomState(0) roi_idx = rng.randint(0, mesh[0].shape[0], size=5) # Wrong input assert_raises_regex(ValueError, 'roi_map does not have the same number of vertices', plot_surf_roi, mesh, roi_map=roi_idx)
def test_gifti_img_to_mesh(): mesh = generate_surf() coord_array = gifti.GiftiDataArray(data=mesh[0]) coord_array.intent = nb.nifti1.intent_codes['NIFTI_INTENT_POINTSET'] face_array = gifti.GiftiDataArray(data=mesh[1]) face_array.intent = nb.nifti1.intent_codes['NIFTI_INTENT_TRIANGLE'] gii = gifti.GiftiImage(darrays=[coord_array, face_array]) coords, faces = _gifti_img_to_mesh(gii) assert_array_equal(coords, mesh[0]) assert_array_equal(faces, mesh[1])
def test_gifti_img_to_mesh(): mesh = generate_surf() coord_array = gifti.GiftiDataArray(data=mesh[0]) coord_array.intent = nb.nifti1.intent_codes['NIFTI_INTENT_POINTSET'] face_array = gifti.GiftiDataArray(data=mesh[1]) face_array.intent = nb.nifti1.intent_codes['NIFTI_INTENT_TRIANGLE'] gii = gifti.GiftiImage(darrays=[coord_array, face_array]) coords, faces = _gifti_img_to_mesh(gii) assert_array_equal(coords, mesh[0]) assert_array_equal(faces, mesh[1])
def test_load_surf_mesh_file_error(): if LooseVersion(nb.__version__) <= LooseVersion('1.2.0'): raise SkipTest # test if files with unexpected suffixes raise errors mesh = generate_surf() wrong_suff = ['.vtk', '.obj', '.mnc', '.txt'] for suff in wrong_suff: filename_wrong = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_wrong, mesh[0], mesh[1]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, filename_wrong) os.remove(filename_wrong)
def test_load_surf_mesh_file_error(): if LooseVersion(nb.__version__) <= LooseVersion('1.2.0'): raise SkipTest # test if files with unexpected suffixes raise errors mesh = generate_surf() wrong_suff = ['.vtk', '.obj', '.mnc', '.txt'] for suff in wrong_suff: filename_wrong = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_wrong, mesh[0], mesh[1]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, filename_wrong) os.remove(filename_wrong)
def test_plot_surf_stat_map_matplotlib_specific(): mesh = generate_surf() rng = np.random.RandomState(42) data = 10 * rng.standard_normal(size=mesh[0].shape[0]) # Plot to axes axes = plt.subplots(ncols=2, subplot_kw={'projection': '3d'})[1] for ax in axes.flatten(): plot_surf_stat_map(mesh, stat_map=data, ax=ax) axes = plt.subplots(ncols=2, subplot_kw={'projection': '3d'})[1] for ax in axes.flatten(): plot_surf_stat_map(mesh, stat_map=data, ax=ax, colorbar=True) fig = plot_surf_stat_map(mesh, stat_map=data, colorbar=False) assert len(fig.axes) == 1 # symmetric_cbar fig = plot_surf_stat_map(mesh, stat_map=data, colorbar=True, symmetric_cbar=True) fig.canvas.draw() assert len(fig.axes) == 2 yticklabels = fig.axes[1].get_yticklabels() first, last = yticklabels[0].get_text(), yticklabels[-1].get_text() assert float(first) == -float(last) # no symmetric_cbar fig = plot_surf_stat_map(mesh, stat_map=data, colorbar=True, symmetric_cbar=False) fig.canvas.draw() assert len(fig.axes) == 2 yticklabels = fig.axes[1].get_yticklabels() first, last = yticklabels[0].get_text(), yticklabels[-1].get_text() assert float(first) != -float(last) # Test handling of nan values in texture data # Add nan values in the texture data[2] = np.nan # Plot the surface stat map fig = plot_surf_stat_map(mesh, stat_map=data) # Check that the resulting plot facecolors contain no transparent faces # (last column equals zero) even though the texture contains nan values assert (mesh[1].shape[0] == ( (fig._axstack.as_list()[0].collections[0]._facecolors[:, 3]) != 0).sum()) # noqa # Save execution time and memory plt.close()
def test_load_surf_mesh_file_freesurfer(): # Older nibabel versions does not support 'write_geometry' if LooseVersion(nb.__version__) <= LooseVersion('1.2.0'): raise SkipTest mesh = generate_surf() for suff in ['.pial', '.inflated', '.white', '.orig', 'sphere']: filename_fs_mesh = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_fs_mesh, mesh[0], mesh[1]) assert_equal(len(load_surf_mesh(filename_fs_mesh)), 2) assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[0], mesh[0]) assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[1], mesh[1]) os.remove(filename_fs_mesh)
def test_load_surf_mesh_file_freesurfer(): # Older nibabel versions does not support 'write_geometry' if LooseVersion(nb.__version__) <= LooseVersion('1.2.0'): raise SkipTest mesh = generate_surf() for suff in ['.pial', '.inflated', '.white', '.orig', 'sphere']: filename_fs_mesh = tempfile.mktemp(suffix=suff) nb.freesurfer.write_geometry(filename_fs_mesh, mesh[0], mesh[1]) assert_equal(len(load_surf_mesh(filename_fs_mesh)), 2) assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[0], mesh[0]) assert_array_almost_equal(load_surf_mesh(filename_fs_mesh)[1], mesh[1]) os.remove(filename_fs_mesh)
def test_plot_surf_roi(): mesh = generate_surf() rng = np.random.RandomState(0) roi_idx = rng.randint(0, mesh[0].shape[0], size=10) roi_map = np.zeros(mesh[0].shape[0]) roi_map[roi_idx] = 1 parcellation = rng.rand(mesh[0].shape[0]) # plot roi plot_surf_roi(mesh, roi_map=roi_map) plot_surf_roi(mesh, roi_map=roi_map, colorbar=True) # change vmin, vmax img = plot_surf_roi(mesh, roi_map=roi_map, vmin=1.2, vmax=8.9, colorbar=True) img.canvas.draw() cbar = img.axes[-1] cbar_vmin = float(cbar.get_yticklabels()[0].get_text()) cbar_vmax = float(cbar.get_yticklabels()[-1].get_text()) assert cbar_vmin == 1.2 assert cbar_vmax == 8.9 # plot parcellation plot_surf_roi(mesh, roi_map=parcellation) plot_surf_roi(mesh, roi_map=parcellation, colorbar=True) # plot to axes plot_surf_roi(mesh, roi_map=roi_map, ax=None, figure=plt.gcf()) # plot to axes with tempfile.NamedTemporaryFile() as tmp_file: plot_surf_roi(mesh, roi_map=roi_map, ax=plt.gca(), figure=None, output_file=tmp_file.name) with tempfile.NamedTemporaryFile() as tmp_file: plot_surf_roi(mesh, roi_map=roi_map, ax=plt.gca(), figure=None, output_file=tmp_file.name, colorbar=True) # Save execution time and memory plt.close()
def test_load_surf_mesh_file_gii(tmp_path): # Test the loader `load_surf_mesh` # If nibabel is of older version we skip tests as nibabel does not # support intent argument and intent codes are not handled properly with # older versions if not LooseVersion(nb.__version__) >= LooseVersion('2.1.0'): raise pytest.skip('Nibabel version too old to handle intent codes') mesh = generate_surf() # test if correct gii is loaded into correct list fd_mesh, filename_gii_mesh = tempfile.mkstemp(suffix='.gii', dir=str(tmp_path)) os.close(fd_mesh) coord_array = gifti.GiftiDataArray(data=mesh[0], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_POINTSET']) face_array = gifti.GiftiDataArray(data=mesh[1], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_TRIANGLE']) gii = gifti.GiftiImage(darrays=[coord_array, face_array]) gifti.write(gii, filename_gii_mesh) assert_array_equal(load_surf_mesh(filename_gii_mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(filename_gii_mesh)[1], mesh[1]) os.remove(filename_gii_mesh) # test if incorrect gii raises error fd_no, filename_gii_mesh_no_point = tempfile.mkstemp(suffix='.gii', dir=str(tmp_path)) os.close(fd_no) gifti.write(gifti.GiftiImage(darrays=[face_array, face_array]), filename_gii_mesh_no_point) with pytest.raises(ValueError, match='NIFTI_INTENT_POINTSET'): load_surf_mesh(filename_gii_mesh_no_point) os.remove(filename_gii_mesh_no_point) fd_face, filename_gii_mesh_no_face = tempfile.mkstemp(suffix='.gii', dir=str(tmp_path)) os.close(fd_face) gifti.write(gifti.GiftiImage(darrays=[coord_array, coord_array]), filename_gii_mesh_no_face) with pytest.raises(ValueError, match='NIFTI_INTENT_TRIANGLE'): load_surf_mesh(filename_gii_mesh_no_face) os.remove(filename_gii_mesh_no_face)
def test_plot_surf_avg_method_errors(): mesh = generate_surf() rng = np.random.RandomState(42) with pytest.raises(ValueError, match=("Array computed with the custom " "function from avg_method does " "not have the correct shape")): def custom_avg_function(vertices): return [vertices[0] * vertices[1], vertices[2]] plot_surf(mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0]), avg_method=custom_avg_function, engine='matplotlib') with pytest.raises(ValueError, match=re.escape("avg_method should be either " "['mean', 'median', 'max', 'min'] " "or a custom function")): custom_avg_function = dict() plot_surf(mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0]), avg_method=custom_avg_function, engine='matplotlib') plot_surf(mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0]), avg_method="foo", engine='matplotlib') with pytest.raises(ValueError, match=re.escape( "Array computed with the custom function " "from avg_method should be an array of " "numbers (int or float)")): def custom_avg_function(vertices): return "string" plot_surf(mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0]), avg_method=custom_avg_function, engine='matplotlib')
def test_load_surf_mesh_list(): # test if correct list is returned mesh = generate_surf() assert len(load_surf_mesh(mesh)) == 2 assert_array_equal(load_surf_mesh(mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(mesh)[1], mesh[1]) # test if incorrect list, array or dict raises error with pytest.raises(ValueError, match='it must have two elements'): load_surf_mesh([]) with pytest.raises(ValueError, match='it must have two elements'): load_surf_mesh([mesh[0]]) with pytest.raises(ValueError, match='it must have two elements'): load_surf_mesh([mesh[0], mesh[1], mesh[1]]) with pytest.raises(ValueError, match='input type is not recognized'): load_surf_mesh(mesh[0]) with pytest.raises(ValueError, match='input type is not recognized'): load_surf_mesh(dict()) del mesh
def test_load_surf_mesh_file_glob(): mesh = generate_surf() fname1 = tempfile.mktemp(suffix='.pial') nb.freesurfer.write_geometry(fname1, mesh[0], mesh[1]) fname2 = tempfile.mktemp(suffix='.pial') nb.freesurfer.write_geometry(fname2, mesh[0], mesh[1]) with pytest.raises(ValueError, match='More than one file matching path'): load_surf_mesh(os.path.join(os.path.dirname(fname1), "*.pial")) with pytest.raises(ValueError, match='No files matching path'): load_surf_mesh( os.path.join(os.path.dirname(fname1), "*.unlikelysuffix")) assert len(load_surf_mesh(fname1)) == 2 assert_array_almost_equal(load_surf_mesh(fname1)[0], mesh[0]) assert_array_almost_equal(load_surf_mesh(fname1)[1], mesh[1]) os.remove(fname1) os.remove(fname2)
def test_load_surf_mesh_list(): # test if correct list is returned mesh = generate_surf() assert_equal(len(load_surf_mesh(mesh)), 2) assert_array_equal(load_surf_mesh(mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(mesh)[1], mesh[1]) # test if incorrect list, array or dict raises error assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, []) assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, [mesh[0]]) assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, [mesh[0], mesh[1], mesh[1]]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, mesh[0]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, dict()) del mesh
def test_load_surf_mesh_list(): # test if correct list is returned mesh = generate_surf() assert_equal(len(load_surf_mesh(mesh)), 2) assert_array_equal(load_surf_mesh(mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(mesh)[1], mesh[1]) # test if incorrect list, array or dict raises error assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, []) assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, [mesh[0]]) assert_raises_regex(ValueError, 'it must have two elements', load_surf_mesh, [mesh[0], mesh[1], mesh[1]]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, mesh[0]) assert_raises_regex(ValueError, 'input type is not recognized', load_surf_mesh, dict()) del mesh
def test_load_surf_mesh_file_gii(): # Test the loader `load_surf_mesh` # If nibabel is of older version we skip tests as nibabel does not # support intent argument and intent codes are not handled properly with # older versions if not LooseVersion(nb.__version__) >= LooseVersion('2.1.0'): raise SkipTest mesh = generate_surf() # test if correct gii is loaded into correct list filename_gii_mesh = tempfile.mktemp(suffix='.gii') coord_array = gifti.GiftiDataArray(data=mesh[0], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_POINTSET']) face_array = gifti.GiftiDataArray(data=mesh[1], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_TRIANGLE']) gii = gifti.GiftiImage(darrays=[coord_array, face_array]) gifti.write(gii, filename_gii_mesh) assert_array_equal(load_surf_mesh(filename_gii_mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(filename_gii_mesh)[1], mesh[1]) os.remove(filename_gii_mesh) # test if incorrect gii raises error filename_gii_mesh_no_point = tempfile.mktemp(suffix='.gii') gifti.write(gifti.GiftiImage(darrays=[face_array, face_array]), filename_gii_mesh_no_point) assert_raises_regex(ValueError, 'NIFTI_INTENT_POINTSET', load_surf_mesh, filename_gii_mesh_no_point) os.remove(filename_gii_mesh_no_point) filename_gii_mesh_no_face = tempfile.mktemp(suffix='.gii') gifti.write(gifti.GiftiImage(darrays=[coord_array, coord_array]), filename_gii_mesh_no_face) assert_raises_regex(ValueError, 'NIFTI_INTENT_TRIANGLE', load_surf_mesh, filename_gii_mesh_no_face) os.remove(filename_gii_mesh_no_face)
def test_plot_surf_avg_method(): mesh = generate_surf() rng = np.random.RandomState(42) # Plot with avg_method ## Test all built-in methods and check mapp = rng.standard_normal(size=mesh[0].shape[0]) mesh_ = load_surf_mesh(mesh) coords, faces = mesh_[0], mesh_[1] for method in ['mean', 'median', 'min', 'max']: display = plot_surf(mesh, surf_map=mapp, avg_method=method, engine='matplotlib') if method == 'mean': agg_faces = np.mean(mapp[faces], axis=1) elif method == 'median': agg_faces = np.median(mapp[faces], axis=1) elif method == 'min': agg_faces = np.min(mapp[faces], axis=1) elif method == 'max': agg_faces = np.max(mapp[faces], axis=1) vmin = np.min(agg_faces) vmax = np.max(agg_faces) agg_faces -= vmin agg_faces /= (vmax - vmin) cmap = plt.cm.get_cmap(plt.rcParamsDefault['image.cmap']) assert_array_equal( cmap(agg_faces), display._axstack.as_list()[0].collections[0]._facecolors) ## Try custom avg_method def custom_avg_function(vertices): return vertices[0] * vertices[1] * vertices[2] plot_surf( mesh, surf_map=rng.standard_normal(size=mesh[0].shape[0]), avg_method=custom_avg_function, engine='matplotlib', ) # Save execution time and memory plt.close()
def test_load_surf_mesh_file_gii(): # Test the loader `load_surf_mesh` # If nibabel is of older version we skip tests as nibabel does not # support intent argument and intent codes are not handled properly with # older versions if not LooseVersion(nb.__version__) >= LooseVersion('2.1.0'): raise SkipTest mesh = generate_surf() # test if correct gii is loaded into correct list filename_gii_mesh = tempfile.mktemp(suffix='.gii') coord_array = gifti.GiftiDataArray(data=mesh[0], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_POINTSET']) face_array = gifti.GiftiDataArray(data=mesh[1], intent=nb.nifti1.intent_codes[ 'NIFTI_INTENT_TRIANGLE']) gii = gifti.GiftiImage(darrays=[coord_array, face_array]) gifti.write(gii, filename_gii_mesh) assert_array_equal(load_surf_mesh(filename_gii_mesh)[0], mesh[0]) assert_array_equal(load_surf_mesh(filename_gii_mesh)[1], mesh[1]) os.remove(filename_gii_mesh) # test if incorrect gii raises error filename_gii_mesh_no_point = tempfile.mktemp(suffix='.gii') gifti.write(gifti.GiftiImage(darrays=[face_array, face_array]), filename_gii_mesh_no_point) assert_raises_regex(ValueError, 'NIFTI_INTENT_POINTSET', load_surf_mesh, filename_gii_mesh_no_point) os.remove(filename_gii_mesh_no_point) filename_gii_mesh_no_face = tempfile.mktemp(suffix='.gii') gifti.write(gifti.GiftiImage(darrays=[coord_array, coord_array]), filename_gii_mesh_no_face) assert_raises_regex(ValueError, 'NIFTI_INTENT_TRIANGLE', load_surf_mesh, filename_gii_mesh_no_face) os.remove(filename_gii_mesh_no_face)
def test_plot_surf(engine, tmp_path): if not PLOTLY_INSTALLED and engine == "plotly": pytest.skip('Plotly is not installed; required for this test.') mesh = generate_surf() rng = np.random.RandomState(42) bg = rng.standard_normal(size=mesh[0].shape[0]) # Plot mesh only plot_surf(mesh, engine=engine) # Plot mesh with background plot_surf(mesh, bg_map=bg, engine=engine) plot_surf(mesh, bg_map=bg, darkness=0.5, engine=engine) plot_surf(mesh, bg_map=bg, alpha=0.5, output_file=tmp_path / 'tmp.png', engine=engine) # Plot different views plot_surf(mesh, bg_map=bg, hemi='right', engine=engine) plot_surf(mesh, bg_map=bg, view='medial', engine=engine) plot_surf(mesh, bg_map=bg, hemi='right', view='medial', engine=engine) # Plot with colorbar plot_surf(mesh, bg_map=bg, colorbar=True, engine=engine) plot_surf(mesh, bg_map=bg, colorbar=True, cbar_vmin=0, cbar_vmax=150, cbar_tick_format="%i", engine=engine) # Save execution time and memory plt.close() # Plot with title display = plot_surf(mesh, bg_map=bg, title='Test title', engine=engine) if engine == 'matplotlib': assert display._suptitle._text == 'Test title' assert display._suptitle._x == .5 assert display._suptitle._y == .95
def test_plot_surf_stat_map_error(): mesh = generate_surf() rng = np.random.RandomState(0) data = 10 * rng.randn(mesh[0].shape[0], ) # Try to input vmin assert_raises_regex(ValueError, 'this function does not accept a "vmin" argument', plot_surf_stat_map, mesh, stat_map=data, vmin=0) # Wrong size of stat map data assert_raises_regex(ValueError, 'surf_map does not have the same number of vertices', plot_surf_stat_map, mesh, stat_map=np.hstack((data, data))) assert_raises_regex(ValueError, 'surf_map can only have one dimension', plot_surf_stat_map, mesh, stat_map=np.vstack((data, data)).T)
def test_load_surf_mesh_file_glob(): mesh = generate_surf() fname1 = tempfile.mktemp(suffix='.pial') nb.freesurfer.write_geometry(fname1, mesh[0], mesh[1]) fname2 = tempfile.mktemp(suffix='.pial') nb.freesurfer.write_geometry(fname2, mesh[0], mesh[1]) assert_raises_regex(ValueError, 'More than one file matching path', load_surf_mesh, os.path.join(os.path.dirname(fname1), "*.pial")) assert_raises_regex(ValueError, 'No files matching path', load_surf_mesh, os.path.join(os.path.dirname(fname1), "*.unlikelysuffix")) assert_equal(len(load_surf_mesh(fname1)), 2) assert_array_almost_equal(load_surf_mesh(fname1)[0], mesh[0]) assert_array_almost_equal(load_surf_mesh(fname1)[1], mesh[1]) os.remove(fname1) os.remove(fname2)
def test_plot_surf(): mesh = generate_surf() rng = np.random.RandomState(0) bg = rng.randn(mesh[0].shape[0], ) # Plot mesh only plot_surf(mesh) # Plot mesh with background plot_surf(mesh, bg_map=bg) plot_surf(mesh, bg_map=bg, darkness=0.5) plot_surf(mesh, bg_map=bg, alpha=0.5) # Plot different views plot_surf(mesh, bg_map=bg, hemi='right') plot_surf(mesh, bg_map=bg, view='medial') plot_surf(mesh, bg_map=bg, hemi='right', view='medial') # Plot with colorbar plot_surf(mesh, bg_map=bg, colorbar=True) # Save execution time and memory plt.close()