def calc_graph(dat):
    """
    Creates a graph from the input skeleton data.
    
    The skeleton is segmented to the regions depending on the
    neighborhood of each points: the nodes have more than 3 neighbors
    and the branches have 1 or 2 neighbors. The isolated points are
    not treated. The nodes are converted to the nodes of a networkx 
    graph with the attribute 'neigh', which is the array of the adjoint
    branches. Binary dilation is used then to establish the connections
    between the nodes and the branches and add the edges to the graph, 
    creating necessary end nodes. All branches have the attribute 'length'
    that is equal the the number of elements (points) in the branch.
    
    Parameters
    ---------
    dat : 3D binary array
    
    Returns
    -------
    G : a graph
    """
    dat_n = lb.numb(dat)
    dat_nodes = lb.label_nodes(dat_n)
    dat_br = lb.label_br(dat_n)
    
    dat_G = lb.neigh_br(dat_nodes, dat_br)
    G = lb.create_con(dat_G, dat_br)
    return G
def isolated_points(graph, dat):
    """
    Treats the isolated points and adds them to a graph as
    the nodes.
    
    Parameters
    ---------
    graph : a graph
    dat : 3D skeleton binary array
    
    Returns
    -------
    G : a copy of input graph with isolated nodes
    """
    G = graph.copy()
    dat_n = lb.numb(dat)
    dat_is = lb.label_iso(dat, dat_n)
    G = lb.add_isol_points(G, dat_is)
    return G
    fileName = 'path/skeletons_largedom/' + i[
        19:-3] + '.h5'  #indices in i differs depending on the length
    #of path; name can be arbitrary
    shape = seg.shape
    atom_s = tb.UInt8Atom()
    atom_d = tb.UInt16Atom()
    filters = tb.Filters(complevel=5, complib='zlib')

    d = tb.open_file(fileName, 'w')
    ca_s = d.create_carray(d.root, 'skel', atom_s, shape, filters=filters)
    ca_dist = d.create_carray(d.root, 'dist', atom_d, shape, filters=filters)

    ca_s[:, :, :] = skel[:, :, :]
    ca_dist[:, :, :] = dist[:, :, :]

    n = lm.numb(skel)
    br = lm.label_br(n)
    br1 = lm.rem_bound(
        br)  #exclude boundary effects by removing boundary branches

    #create a list of mean thicknesses of the branches
    find_br = ndimage.find_objects(br1)
    un = np.unique(br1)[1:]
    t = []
    for k in un:
        mask = br1[find_br[k - 1]] == k
        v = np.unique(mask * dist[find_br[k - 1]])
        n1 = float(np.count_nonzero(v.ravel()))
        t = np.append(t, (np.sum(v.ravel()) / n1))

    atom = tb.UInt16Atom()