Пример #1
0
    def test_average_node_edge_length(self):
        for side in xrange(1, 5):
            s_flat = surf.generate_plane((0, 0, 0), (0, 0, 1), (0, 1, 0), 6, 6)
            rnd_xyz = 0 * np.random.normal(size=s_flat.vertices.shape)
            s = surf.Surface(s_flat.vertices + rnd_xyz, s_flat.faces)

            nvertices = s.nvertices

            sd = np.zeros((nvertices,))
            c = np.zeros((nvertices,))

            def d(src, trg, vertices=s.vertices):
                s = vertices[src, :]
                t = vertices[trg, :]

                delta = s - t
                # print s, t, delta
                return np.sum(delta ** 2) ** .5

            for i_face in s.faces:
                for i in xrange(3):
                    src = i_face[i]
                    trg = i_face[(i + 1) % 3]

                    sd[src] += d(src, trg)
                    sd[trg] += d(src, trg)
                    c[src] += 1
                    c[trg] += 1

                    # print i, src, trg, d(src, trg)

            assert_array_almost_equal(sd / c, s.average_node_edge_length)
Пример #2
0
def read(fn):
    '''
    Reads a AFNI SUMA ASCII surface

    Parameters
    ----------
    fn : str
        Filename of ASCII surface file

    Returns
    -------
    s : Surface
        a surf.Surface as defined in 'fn'
    '''

    if not os.path.exists(fn):
        raise Exception("File not found: %s" % fn)

    with open(fn) as f:
        r = f.read().split("\n")

    row = 0
    nv = nf = None  # number of vertices and faces
    while True:
        line = r[row]
        row += 1

        if line.startswith("#"):
            continue

        try:
            nvnf = line.split(" ")
            nv = int(nvnf[0])
            nf = int(nvnf[1])
            break

        except:
            continue

    if not nf:
        raise Exception("Not found in %s: number of nodes and faces" % fn)

    # helper function to get a numpy Cx3 ndarray
    def getrows(c, s):  # c: number of rows, s is string with data
        vs = np.fromstring(s, count=4 * c, sep=" ")
        vx = np.reshape(vs, (c, 4))
        return vx[:, :3]

    # coordinates should start at pos...
    v = getrows(nv, "\n".join(r[row:(row + nv)]))

    # and the faces just after those
    ffloat = getrows(nf, "\n".join(r[(row + nv):(row + nv + nf)]))
    f = ffloat.astype(int)

    return surf.Surface(v=v, f=f)
Пример #3
0
    def test_surf_border_nonconnected_nodes(self):
        s = surf.generate_cube()

        # add empty node
        v = np.vstack((s.vertices, [2, 2, 2]))

        # remove two faces
        s2 = surf.Surface(v, s.faces[:-2])

        is_on_border = [
            False, False, False, False, True, True, True, True, False
        ]
        assert_array_equal(s2.nodes_on_border(), np.asarray(is_on_border))
Пример #4
0
def read(fn, topology_fn=None):
    '''Reads Caret .coord file and also (if it exists) the topology file
    
    Parameters
    ----------
    fn: str
        filename of .coord file
    topology_fn: str or None
        filename of .topo file. If None then it is attempted to deduce
        this filename from the header in fn.
    
    Returns
    -------
    s: surf.Surface
        Surface with the nodes as in fn, and the topology form topology_fn
    '''
    with open(fn) as f:
        s = f.read()

    end_header_pos = _end_header_position(s)

    header = s[:end_header_pos]
    body = s[end_header_pos:]

    # read body
    vertices = np.fromstring(body[4:], dtype='>f4').reshape((-1, 3))

    # see if we can find the topology
    faces = None
    if topology_fn is None:
        lines = header.split('\n')

        for line in lines:
            if line.startswith('topo_file'):
                topo_file = line[10:]

                topo_fn = pathjoin(os.path.split(fn)[0], topo_file)
                if os.path.exists(topo_fn):
                    faces = read_topology(topo_fn)
                    break
    else:
        faces = read_topology(topology_fn)

    if faces is None:
        # XXX print a warning?
        # For now no warning as the Surface.__init__ should print something
        faces = np.zeros((0, 3), dtype=np.int32)

    return surf.Surface(vertices, faces)
Пример #5
0
    def test_surfing_nodes_on_border_paths_surface_with_hole(self):
        s = surf.generate_plane((0, 0, 0), (0, 0, 1), (0, 1, 0), 6, 6)
        faces_to_remove = [1, 3, 7, 8, 3, 12, 13, 14, 22]
        faces_to_keep = np.setdiff1d(np.arange(s.nfaces), faces_to_remove)
        faces_to_add = [(0, 3, 10), (0, 4, 7), (0, 6, 4)]
        faces_hole = np.vstack((s.faces[faces_to_keep], faces_to_add))
        s_hole = surf.Surface(s.vertices, faces_hole)

        pths = s_hole.nodes_on_border_paths()

        expected_pths = [[1, 6, 4, 7, 0],
                         [3, 4, 9, 8, 2],
                         [11, 17, 23, 29, 35,
                          34, 33, 32, 31, 30,
                          24, 18, 12, 6, 7,
                          13, 19, 14, 9, 10,
                          5]]

        def as_sorted_sets(xs):
            return sorted(map(set, xs), key=min)

        assert_equal(as_sorted_sets(pths),
                     as_sorted_sets(expected_pths), )
Пример #6
0
def read(fn):
    '''Reads a GIFTI surface file

    Parameters
    ----------
    fn: str
        Filename

    Returns
    -------
    surf_: surf.Surface
        Surface

    Notes
    -----
    Any meta-information stored in the GIFTI file is not present in surf_.
    '''

    g = giftiio.read(fn)

    vertices = _get_single_array(g, 'NIFTI_INTENT_POINTSET').data
    faces = _get_single_array(g, 'NIFTI_INTENT_TRIANGLE').data

    return surf.Surface(vertices, faces)