Exemple #1
0
class MeshKLazy(SymMatrixApprox):
    def __init__(self, func=None, m=1.0):
        """
        m : float, default 1.0
            Time step for the geodesic heat approximation. Should be 1.0 normally,
            but if there's numerical instability, set it higher (e.g. 100.0)
        """
        if func is not None:
            self._func = func
        else:
            self._func = lambda x: x

        self._m = m

    def fit(self, pts, polys):
        self._n = len(pts)
        self._surface = Surface(pts, polys)

    def get_row(self, i):
        return self._func(self._surface.geodesic_distance([i], m=self._m))

    def get_rows(self, rows):
        return np.vstack([
            self._func(self._surface.geodesic_distance([i], m=self._m))
            for i in rows
        ])

    def get_size(self):
        return self._n

    def get_memory(self):
        return (
            self._surface.pts.shape[0] * self._surface.pts.shape[1] +
            self._surface.polys.shape[0] * self._surface.polys.shape[1]) * 8

    def get_name(self):
        return 'MeshKLazy'

    @property
    def shape(self):
        return self._n, self._n
Exemple #2
0
def perpendicular_scalar_func(sfunc, surf, origin, antipode, mask):
    sfunc_grad = surf.surface_gradient(sfunc, at_verts=False)
    normals = surf.face_normals
    grad_perps = np.cross(sfunc_grad, normals)
    #norm_grad_perps = grad_perps / np.sqrt((grad_perps ** 2).sum(1))
    norm_grad_perps = np.nan_to_num(grad_perps.T / np.sqrt(
        (grad_perps**2).sum(1))).T

    # compute integrated divergence
    X = norm_grad_perps
    c32, c13, c21 = surf._cot_edge
    x1 = 0.5 * (c32 * X).sum(1)
    x2 = 0.5 * (c13 * X).sum(1)
    x3 = 0.5 * (c21 * X).sum(1)

    conn1, conn2, conn3 = surf._polyconn
    divx = conn1.dot(x1) + conn2.dot(x2) + conn3.dot(x3)

    # create a surface with a cut
    print("about to cut path")
    cut_path = np.array(surf.geodesic_path(origin, antipode, m=5))
    cut_path = np.union1d(cut_path, mask)
    #noncut_polys = np.array([p for p in surf.polys if ])
    good_polys = ~np.any(
        np.in1d(surf.polys, cut_path).reshape(surf.polys.shape), 1)

    cut_surf = Surface(surf.pts, surf.polys[good_polys])
    # run the geodesic distance code to generate laplace solver (lol)
    cut_surf.geodesic_distance([0])
    print('2')
    cconn1, cconn2, cconn3 = cut_surf._polyconn
    divx_cut = cconn1.dot(x1[good_polys]) + cconn2.dot(
        x2[good_polys]) + cconn3.dot(x3[good_polys])

    # integrate to find fxn whose gradient is norm_grad_perps
    print('3')
    part_perp_func = cut_surf._nLC_solvers[1.0](divx_cut[cut_surf._goodrows])
    perp_func = np.zeros_like(sfunc)
    perp_func[cut_surf._goodrows] = part_perp_func

    return perp_func
Exemple #3
0
class MeshK(SymMatrixApprox):
    CACHE_DIR = "/tmp"

    def __init__(self, func=None, m=1.0):
        self._m = m
        if func is not None:
            self._func = func
        else:
            self._func = lambda x: x

    def fit(self, pts, polys, recache=False):
        self._n = len(pts)
        self._surface = Surface(pts, polys)

        # check to see if the full K is cached
        dataset_hash = str(hash(pts.tostring())) + str(hash(
            polys.tostring())) + str(hash(self._m))
        cache_path = os.path.join(self.CACHE_DIR,
                                  dataset_hash + '_geodesic_K_cache.npz')
        if not os.path.exists(cache_path) or recache:
            print('Cache not found, computing K..')
            K = np.vstack([
                self._surface.geodesic_distance([i], m=self._m)
                for i in counter(range(self._n))
            ])
            self._K = (K + K.T) / 2.0
            np.savez(cache_path, geodesic_K=self._K)
        else:
            print('Loading K from cache..')
            self._K = np.load(cache_path)['geodesic_K']

    def get_row(self, i):
        return self._K[i, :]

    def get_rows(self, rows):
        return self._K[rows, :]

    def get_size(self):
        return self._n

    def get_memory(self):
        return self._K.shape[0] * self._K.shape[1] * 8

    def get_name(self):
        return 'MeshK'

    @property
    def shape(self):
        return self._n, self._n
import numpy as np
import os
from cortex.polyutils import Surface
from perpendicular_path import perpendicular_scalar_func
import io_mesh as io
from neighbours import get_neighbours

surf_io = io.load_mesh_geometry('icbm_avg_mid_sym_mc_left_hires.obj')
surf = Surface(surf_io['coords'], surf_io['faces'])

atlas = np.loadtxt('icbm_avg_mid_sym_mc_atlas_left.txt')
lobule = np.loadtxt('lobule.txt')
medial = (atlas == 0).astype(int)
medial[lobule == 1] = 1
mask = np.where(medial == 1)[0]
dists = surf.geodesic_distance(mask, m=5)

max_start = np.argmax(dists)
#np.savetxt('dists.txt',dists)

inv_dists = surf.geodesic_distance(max_start, m=5)
filtered = inv_dists.copy()
filtered[medial == 0] = 500
#np.savetxt('invdists.txt',inv_dists)
#filtered=filtered*0
#filtered[max_start]=1
#np.savetxt('start.txt',filtered)

start_vert = np.argmax(dists)
end_vert = np.argmin(filtered)
#print end_vert