def load_surface(lh, rh, with_normals=True, join=False): """ Loads surfaces. Parameters ---------- with_normals : bool, optional Whether to compute surface normals. Default is True. join : bool, optional. If False, return one surface for left and right hemispheres. Otherwise, return a single surface as a combination of both left and right. surfaces. Default is False. Returns ------- surf : tuple of BSPolyData or BSPolyData. Surfaces for left and right hemispheres. If ``join == True``, one surface with both hemispheres. """ surfs = [None] * 2 for i, side in enumerate([lh, rh]): surfs[i] = read_surface(side) if with_normals: nf = wrap_vtk(vtkPolyDataNormals, splitting=False, featureAngle=0.1) surfs[i] = serial_connect(surfs[i], nf) if join: return combine_surfaces(*surfs) return surfs[0], surfs[1]
def test_cell_types(): ss = vtk.vtkSphereSource() ss.Update() st = wrap_vtk(ss.GetOutput()) sl = mc.to_lines(st) sv = mc.to_vertex(st) assert checks.get_cell_types(st) == np.array([VTK_TRIANGLE]) assert checks.get_cell_types(st.VTKObject) == np.array([VTK_TRIANGLE]) assert checks.get_cell_types(sl) == np.array([VTK_LINE]) assert checks.get_cell_types(sv) == np.array([VTK_VERTEX]) assert checks.get_number_of_cell_types(st) == 1 assert checks.get_number_of_cell_types(st.VTKObject) == 1 assert checks.get_number_of_cell_types(sl) == 1 assert checks.get_number_of_cell_types(sv) == 1 assert checks.has_unique_cell_type(st) assert checks.has_unique_cell_type(st.VTKObject) assert checks.has_unique_cell_type(sl) assert checks.has_unique_cell_type(sv) assert checks.has_only_triangle(st) assert checks.has_only_triangle(st.VTKObject) assert checks.has_only_line(sl) assert checks.has_only_vertex(sv) ss2 = vtk.vtkSphereSource() ss2.SetRadius(3) ss2.Update() s2 = ss2.GetOutput() app = vtk.vtkAppendPolyData() app.AddInputData(sl.VTKObject) app.AddInputData(s2) app.Update() spl = wrap_vtk(app.GetOutput()) cell_types = np.sort([VTK_TRIANGLE, VTK_LINE]) assert np.all(checks.get_cell_types(spl) == cell_types) assert checks.get_number_of_cell_types(spl) == cell_types.size assert checks.has_unique_cell_type(spl) is False assert checks.has_only_triangle(spl) is False assert checks.has_only_line(spl) is False assert checks.has_only_vertex(spl) is False
def test_moran(): # Sphere with points as locations to build spatial matrix sphere = wrap_vtk(vtk.vtkSphereSource, radius=20, thetaResolution=10, phiResolution=5) sphere = to_data(sphere) n_pts = sphere.n_points # Features to randomize rs = np.random.RandomState(0) feats = rs.randn(n_pts, 2) # build spatial weight matrix a = me.get_immediate_distance(sphere) a.data **= -1 # test default v, w = compute_mem(a, tol=1e-7) assert w.shape[0] <= (n_pts - 1) assert v.shape == (n_pts, w.shape[0]) r1 = moran_randomization(feats[:, 0], v, n_rep=10, random_state=0) assert r1.shape == (10, n_pts) r2 = moran_randomization(feats, v, n_rep=10, random_state=0) assert r2.shape == (10, n_pts, 2) # test default dense mem, ev = compute_mem(a.toarray(), tol=1e-7) assert np.allclose(w, ev) assert np.allclose(v, mem) r1 = moran_randomization(feats[:, 0], mem, n_rep=10, random_state=0) assert r1.shape == (10, n_pts) r2 = moran_randomization(feats, mem, n_rep=10, random_state=0) assert r2.shape == (10, n_pts, 2) # test object api msr = MoranRandomization(n_rep=10, random_state=0, tol=1e-7) msr.fit(a) assert np.allclose(msr.mev_, ev) assert np.allclose(msr.mem_, mem) assert np.allclose(r1, msr.randomize(feats[:, 0])) assert np.allclose(r2, msr.randomize(feats)) # test object api with PolyData msr = MoranRandomization(n_rep=10, random_state=0, tol=1e-7) msr.fit(sphere) assert np.allclose(msr.mev_, ev) assert np.allclose(msr.mem_, mem) assert np.allclose(r1, msr.randomize(feats[:, 0])) assert np.allclose(r2, msr.randomize(feats))
def _generate_sphere(): """Generates a vtk sphere of 50 vertices. Returns ------- BSPolyData Mesh of a sphere. """ s = vtk.vtkSphereSource() s.Update() return wrap_vtk(s.GetOutput())
def test_pipeline(): # check defaults s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f) assert isinstance(out, BSPolyData) assert out.n_points > 0 # check update filter s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, as_data=False) assert isinstance(out, BSAlgorithm) assert out.GetOutput().GetNumberOfPoints() > 0 # check filter no update s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, as_data=False, update=False) assert isinstance(out, BSAlgorithm) assert out.GetOutput().GetNumberOfPoints() == 0 # check non-existing port s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, port=1) assert out is None # check get all possible ports s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, port=-1) assert isinstance(out, list) assert len(out) == f.GetNumberOfOutputPorts() assert isinstance(out[0], BSPolyData) assert out[0].n_points > 0 # check accept wrappers s = wrap_vtk(vtk.vtkSphereSource) f = wrap_vtk(vtk.vtkSmoothPolyDataFilter) assert isinstance(serial_connect(s, f), BSPolyData)
def test_variogram_sampled(): # Sampled class # Sphere with points as locations to build distance matrix sphere = wrap_vtk(vtk.vtkSphereSource, radius=20, thetaResolution=50, phiResolution=25) sphere = to_data(sphere) points = sphere.GetPoints() npoints = sphere.n_points distmat = squareform(pdist(points)) # pairwise distance matrix rs = np.random.RandomState(0) brainmap = rs.randn(npoints, 1).flatten() brainmap[0] = np.nan # Create a mask file mask = np.zeros(npoints, dtype=int) mask[[3, 4, 5]] = 1 # Save distmat and mask file temp = gettempdir() dist_file = join(temp, 'distmat.txt') mask_file = join(temp, 'mask.txt') np.savetxt(dist_file, distmat) np.savetxt(mask_file, mask) assert exists(dist_file) and exists(mask_file) # Convert to memmap files = txt2memmap(dist_file=dist_file, output_dir=temp, maskfile=mask_file) assert exists(files['index']) assert exists(files['distmat']) masked_map = brainmap[np.where(mask == 0)] # Generate surrogates gen = Sampled(masked_map, files['distmat'], files['index'], knn=100, ns=100) surrs = gen(n=5) assert gen.D.shape == (npoints - 3, 100) assert surrs.shape == (5, npoints - 3) assert np.allclose(gen.x.data[1:], masked_map[1:]) assert np.isnan(gen.x.data[0]) assert not np.isnan(surrs).any()
def test_variogram_base(): # Base class # Sphere with points as locations to build distance matrix sphere = wrap_vtk(vtk.vtkSphereSource, radius=20, thetaResolution=20, phiResolution=10) sphere = to_data(sphere) points = sphere.GetPoints() npoints = sphere.n_points distmat = squareform(pdist(points)) # pairwise distance matrix rs = np.random.RandomState(0) brainmap = rs.randn(npoints, 1).flatten() brainmap[0] = np.nan # Generate surrogates gen = Base(brainmap, distmat) surrs = gen(n=10) assert surrs.shape == (10, npoints) assert np.allclose(gen.D, distmat) assert np.allclose(gen.x.data[1:], brainmap[1:]) assert np.isnan(gen.x.data[0]) assert not np.isnan(surrs).any()
def test_array_operations(): s = _generate_sphere() # Cell area area = aop.compute_cell_area(s) assert isinstance(area, np.ndarray) assert area.shape == (s.n_cells, ) s2 = aop.compute_cell_area(s, append=True, key='CellArea') assert s is s2 assert np.allclose(s2.CellData['CellArea'], area) # Cell centers centers = aop.compute_cell_center(s) assert isinstance(centers, np.ndarray) assert centers.shape == (s.n_cells, 3) s2 = aop.compute_cell_center(s, append=True, key='CellCenter') assert s is s2 assert np.allclose(s2.CellData['CellCenter'], centers) # Adjacent cells n_adj = aop.get_n_adjacent_cells(s) assert isinstance(n_adj, np.ndarray) assert n_adj.shape == (s.n_points, ) s2 = aop.get_n_adjacent_cells(s, append=True, key='NAdjCells') assert s is s2 assert np.all(s2.PointData['NAdjCells'] == n_adj) # map cell data to point data area2 = aop.map_celldata_to_pointdata(s, area) area3 = aop.map_celldata_to_pointdata(s, 'CellArea', red_func='mean') assert area.dtype == area2.dtype assert area.dtype == area3.dtype assert np.allclose(area2, area3) area4 = aop.map_celldata_to_pointdata(s, 'CellArea', red_func='mean', dtype=np.float32) assert area4.dtype == np.float32 for op in ['sum', 'mean', 'mode', 'one_third', 'min', 'max']: ap = aop.map_celldata_to_pointdata(s, 'CellArea', red_func=op) assert ap.shape == (s.n_points, ) name = 'CellArea_{}'.format(op) s2 = aop.map_celldata_to_pointdata(s, 'CellArea', red_func=op, append=True, key=name) assert np.allclose(s2.PointData[name], ap) # map point data to cell data fc = aop.map_pointdata_to_celldata(s, n_adj) fc2 = aop.map_pointdata_to_celldata(s, 'NAdjCells', red_func='mean') assert fc.dtype == fc2.dtype assert fc.dtype == fc2.dtype assert np.allclose(fc, fc2) fc3 = aop.map_pointdata_to_celldata(s, 'NAdjCells', red_func='mean', dtype=np.float32) assert fc3.dtype == np.float32 for op in ['sum', 'mean', 'mode', 'one_third', 'min', 'max']: ac = aop.map_pointdata_to_celldata(s, 'NAdjCells', red_func=op) assert ac.shape == (s.n_cells, ) name = 'NAdjCells_{}'.format(op) s2 = aop.map_pointdata_to_celldata(s, 'NAdjCells', red_func=op, append=True, key=name) assert np.allclose(s2.CellData[name], ac) # Point area area = aop.compute_point_area(s) assert isinstance(area, np.ndarray) assert area.shape == (s.n_points, ) s2 = aop.compute_point_area(s, append=True, key='PointArea') assert s is s2 assert np.allclose(s2.PointData['PointArea'], area) s2 = aop.compute_point_area(s, cell_area='CellArea', append=True, key='PointArea2') assert s is s2 assert np.allclose(s2.PointData['PointArea2'], area) # Connected components cc = mop.get_connected_components(s) assert cc.shape == (s.n_points, ) assert np.unique(cc).size == 1 s2 = mop.get_connected_components(s, append=True, key='components') assert s is s2 assert np.all(cc == s2.PointData['components']) # labeling border labeling = (s.Points[:, 0] > s.Points[:, 0].mean()).astype(int) s.append_array(labeling, name='parc', at='p') border = aop.get_labeling_border(s, labeling) assert border.shape == (s.n_points, ) assert np.unique(border).size == 2 border2 = aop.get_labeling_border(s, 'parc') assert np.all(border == border2) # parcellation centroids cent = aop.get_parcellation_centroids(s, labeling, non_centroid=2) assert cent.shape == (s.n_points, ) assert np.unique(cent).size == 3 assert np.count_nonzero(cent == 0) == 1 assert np.count_nonzero(cent == 1) == 1 assert np.count_nonzero(cent == 2) == s.n_points - 2 cent2 = aop.get_parcellation_centroids(s, 'parc', non_centroid=2) assert np.all(cent == cent2) # propagate labeling labeling2 = labeling.astype(np.float32) labeling2[:10] = np.nan s.append_array(labeling2, name='parc2', at='p') pl1 = aop.propagate_labeling(s, labeling2) assert pl1.shape == (s.n_points, ) assert np.count_nonzero(np.isnan(pl1)) == 0 assert np.all(np.unique(pl1) == np.array([0, 1])) pl2 = aop.propagate_labeling(s, 'parc2') assert np.all(pl1 == pl2) # smooth array for k in ['uniform', 'gaussian', 'inverse_distance']: sa = aop.smooth_array(s, n_adj, kernel=k) assert sa.shape == (s.n_points, ) sa2 = aop.smooth_array(s, 'NAdjCells', kernel=k) assert np.all(sa == sa2) # resample pointdata s2 = wrap_vtk(vtk.vtkSphereSource, phiResolution=20) s2.Update() s2 = wrap_vtk(s2.output) rd = aop.resample_pointdata(s, s2, 'NAdjCells') assert rd.shape == (s2.n_points, ) rd2 = aop.resample_pointdata(s, s2, 'NAdjCells', red_func='mean') assert np.all(rd == rd2)
def _generate_sphere(): s = vtk.vtkSphereSource() s.Update() return wrap_vtk(s.GetOutput())
def test_mesh_elements(): s = _generate_sphere() ee = vtk.vtkExtractEdges() ee.SetInputData(s.VTKObject) ee.Update() ee = wrap_vtk(ee.GetOutput()) n_edges = ee.n_cells assert np.all(me.get_points(s) == s.Points) assert np.all(me.get_cells(s) == s.GetCells2D()) assert me.get_extent(s).shape == (3, ) pc = me.get_point2cell_connectivity(s) assert pc.shape == (s.n_points, s.n_cells) assert pc.dtype == np.uint8 assert np.all(pc.sum(axis=0) == 3) cp = me.get_cell2point_connectivity(s) assert pc.dtype == np.uint8 assert (pc - cp.T).nnz == 0 adj = me.get_immediate_adjacency(s) assert adj.shape == (s.n_points, s.n_points) assert adj.dtype == np.uint8 assert adj.nnz == (2 * n_edges + s.n_points) adj2 = me.get_immediate_adjacency(s, include_self=False) assert adj2.shape == (s.n_points, s.n_points) assert adj2.dtype == np.uint8 assert adj2.nnz == (2 * n_edges) radj = me.get_ring_adjacency(s) assert radj.dtype == np.uint8 assert (adj - radj).nnz == 0 radj2 = me.get_ring_adjacency(s, include_self=False) assert radj2.dtype == np.uint8 assert (adj2 - radj2).nnz == 0 radj3 = me.get_ring_adjacency(s, n_ring=2, include_self=False) assert radj3.dtype == np.uint8 assert (radj3 - adj2).nnz > 0 d = me.get_immediate_distance(s) assert d.shape == (s.n_points, s.n_points) assert d.dtype == np.float assert d.nnz == adj2.nnz d2 = me.get_immediate_distance(s, metric='sqeuclidean') d_sq = d.copy() d_sq.data **= 2 assert np.allclose(d_sq.A, d2.A) rd = me.get_ring_distance(s) assert rd.dtype == np.float assert np.allclose(d.A, rd.A) rd2 = me.get_ring_distance(s, n_ring=2) assert (rd2 - d).nnz > 0 assert me.get_cell_neighbors(s).shape == (s.n_cells, s.n_cells) assert me.get_edges(s).shape == (n_edges, 2) assert me.get_edge_length(s).shape == (n_edges, ) assert me.get_boundary_points(s).size == 0 assert me.get_boundary_edges(s).size == 0 assert me.get_boundary_cells(s).size == 0
from vtk import vtkPolyDataNormals from brainspace.mesh.mesh_io import read_surface from brainspace.mesh.mesh_operations import combine_surfaces from brainspace.utils.parcellation import reduce_by_labels from brainspace.vtk_interface import wrap_vtk, serial_connect template_path = "Z:/hschoi/backup/hschoi/template/MMP" template_L = "S900.L.midthickness_MSMAll.10k_fs_LR.surf.gii" # S900.L.midthickness_MSMAll.10k_fs_LR.surf.gii # L.very_inflated_MSMAll.10k_fs_LR.surf.gii template_R = "S900.R.midthickness_MSMAll.10k_fs_LR.surf.gii" # S900.R.midthickness_MSMAll.10k_fs_LR.surf.gii # R.very_inflated_MSMAll.10k_fs_LR.surf.gii surfs = [None] * 2 surfs[0] = read_surface(join(template_path, template_L)) nf = wrap_vtk(vtkPolyDataNormals, splitting=False, featureAngle=0.1) surf_lh = serial_connect(surfs[0], nf) surfs[1] = read_surface(join(template_path, template_R)) nf = wrap_vtk(vtkPolyDataNormals, splitting=False, featureAngle=0.1) surf_rh = serial_connect(surfs[1], nf) # Visualization from brainspace.datasets import load_group_fc, load_parcellation, load_conte69 from brainspace.gradient import GradientMaps from brainspace.plotting import plot_hemispheres from brainspace.utils.parcellation import map_to_labels atlas = np.load("Z:\\hschoi\\backup\\hschoi\\template\\MMP\\MMP.10k_fs_LR.npy")
def test_basic_wrapping(): assert is_vtk(vtk.vtkPolyData) is False assert is_vtk(vtk.vtkPolyData()) is True assert is_vtk(None) is False ws = wrap_vtk(vtk.vtkPolyData()) assert is_wrapper(ws.VTKObject) is False assert is_wrapper(ws) is True assert is_wrapper(None) is False assert wrap_vtk(None) is None assert wrap_vtk(ws) is ws # test source s = wrap_vtk(vtk.vtkSphereSource, radius=3) assert isinstance(s, BSAlgorithm) assert s.is_source assert s.VTKObject.GetRadius() == 3 s.setVTK(radius=4.5) assert s.VTKObject.GetRadius() == 4.5 s.radius = 2.5 assert s.VTKObject.GetRadius() == 2.5 with pytest.raises(Exception): s.radius2 = 0 # test filter (no source no sink) s = wrap_vtk(vtk.vtkSmoothPolyDataFilter, numberOfIterations=2) assert isinstance(s, BSAlgorithm) assert s.is_filter assert s.VTKObject.GetNumberOfIterations() == 2 # test sink s = wrap_vtk(vtk.vtkXMLPolyDataWriter, filename='some/path') assert isinstance(s, BSAlgorithm) assert s.is_sink assert s.VTKObject.GetFileName() == 'some/path' # test vtkPolyDataMapper s = wrap_vtk(vtk.vtkPolyDataMapper, arrayName='array_name', scalarMode='UseCellData') assert isinstance(s, BSAlgorithm) assert isinstance(s, BSPolyDataMapper) assert s.is_sink assert s.VTKObject.GetScalarModeAsString() == 'UseCellData' assert s.VTKObject.GetArrayName() == 'array_name' assert s.VTKObject.GetArrayAccessMode() == 1 # test change in access mode s.arrayid = 3 assert s.VTKObject.GetArrayId() == 3 assert s.VTKObject.GetArrayAccessMode() == 0 # test actor access to property s = wrap_vtk(vtk.vtkActor, opacity=0.5, interpolation='phong') assert isinstance(s, BSActor) assert s.VTKObject.GetProperty().GetOpacity() == 0.5 assert s.property.opacity == 0.5 assert s.opacity == 0.5 # test implemented wrapper s = wrap_vtk(vtk.vtkPolyData) assert isinstance(s, BSPolyData) # test not implemented --> default to superclass s = wrap_vtk(vtk.vtkImageData) assert isinstance(s, BSDataSet) # test wrappers to create objects with pytest.raises(TypeError): w = BSVTKObjectWrapper() with pytest.raises(AttributeError): w = BSVTKObjectWrapper(None) pd = BSPolyData() assert isinstance(pd.VTKObject, vtk.vtkPolyData) a = BSActor() assert isinstance(a.VTKObject, vtk.vtkActor) m = BSPolyDataMapper() assert isinstance(m.VTKObject, vtk.vtkPolyDataMapper)
def test_spin(): # Create dummy spheres or left and right hemispheres sphere_lh = wrap_vtk(vtk.vtkSphereSource, radius=20, thetaResolution=10, phiResolution=5) sphere_lh = to_data(sphere_lh) pts_lh = sphere_lh.Points n_pts_lh = sphere_lh.n_points # Right with more points sphere_rh = wrap_vtk(vtk.vtkSphereSource, radius=20, thetaResolution=10, phiResolution=6) sphere_rh = to_data(sphere_rh) pts_rh = sphere_rh.Points n_pts_rh = sphere_rh.n_points # Features to randomize rs = np.random.RandomState(0) feats_lh = rs.randn(n_pts_lh, 2) feats_rh = rs.randn(n_pts_rh, 2) # generate spin indices ridx1 = _generate_spins(pts_lh, n_rep=10, random_state=0) assert ridx1['lh'].shape == (10, n_pts_lh) assert 'rh' not in ridx1 ridx2 = _generate_spins(pts_lh, points_rh=pts_rh, n_rep=10, random_state=0) assert ridx2['lh'].shape == (10, n_pts_lh) assert ridx2['rh'].shape == (10, n_pts_rh) # test api lh sp = SpinPermutations(n_rep=10, random_state=0) sp.fit(pts_lh) assert np.all(sp.spin_lh_ == ridx1['lh']) assert sp.spin_rh_ is None assert sp.randomize(feats_lh[:, 0]).shape == (10, n_pts_lh) assert sp.randomize(feats_lh).shape == (10, n_pts_lh, 2) # test api lh and rh sp = SpinPermutations(n_rep=10, random_state=0) sp.fit(pts_lh, points_rh=pts_rh) assert np.all(sp.spin_lh_ == ridx2['lh']) assert np.all(sp.spin_rh_ == ridx2['rh']) r1 = sp.randomize(feats_lh[:, 0]) assert r1[0].shape == (10, n_pts_lh) assert r1[1] is None r1bis = spin_permutations(pts_lh, feats_lh[:, 0], n_rep=10, random_state=0) assert np.all(r1[0] == r1bis) r2 = sp.randomize(feats_lh) assert r2[0].shape == (10, n_pts_lh, 2) assert r2[1] is None r2bis = spin_permutations(pts_lh, feats_lh, n_rep=10, random_state=0) assert np.all(r2[0] == r2bis) r1 = sp.randomize(feats_lh[:, 0], x_rh=feats_rh[:, 0]) assert r1[0].shape == (10, n_pts_lh) assert r1[1].shape == (10, n_pts_rh) r1bis = spin_permutations({ 'lh': pts_lh, 'rh': pts_rh }, { 'lh': feats_lh[:, 0], 'rh': feats_rh[:, 0] }, n_rep=10, random_state=0) assert np.all(r1[0] == r1bis[0]) assert np.all(r1[1] == r1bis[1]) r2 = sp.randomize(feats_lh, x_rh=feats_rh) assert r2[0].shape == (10, n_pts_lh, 2) assert r2[1].shape == (10, n_pts_rh, 2) r2bis = spin_permutations({ 'lh': pts_lh, 'rh': pts_rh }, { 'lh': feats_lh, 'rh': feats_rh }, n_rep=10, random_state=0) assert np.all(r2[0] == r2bis[0]) assert np.all(r2[1] == r2bis[1])