Example #1
0
def split_by_confidence_and_add_edges(confidence_threshold, digraphs, rows):
    """ dipgrahs is a dictionary of skeleton IDs as keys and DiGraph instances as values,
    where the DiGraph does not have any edges yet.
    WARNING: side effect on contents of digraph: will add the edges
    """
    arbors = {}
    # Define edges, which may result in multiple subgraphs for each skeleton
    # when splitting at low-confidence edges:
    if 0 == confidence_threshold:
        # Do not split skeletons
        for row in rows:
            if row[1]:
                digraphs[row[3]].add_edge(row[1], row[0])
        for skid, digraph in digraphs.iteritems():
            arbors[skid] = [digraph]
    else:
        # The DiGraph representing the skeleton may be disconnected at a low-confidence edge
        to_split = set()
        for row in rows:
            if row[2] < confidence_threshold:
                to_split.add(row[3])
            elif row[1]:
                digraphs[row[3]].add_edge(row[1], row[0])
        for skid, digraph in digraphs.iteritems():
            if skid in to_split:
                arbors[skid] = weakly_connected_component_subgraphs(digraph)
            else:
                arbors[skid] = [digraph]

    return arbors
Example #2
0
def split_by_confidence_and_add_edges(confidence_threshold, digraphs, rows):
    """ dipgrahs is a dictionary of skeleton IDs as keys and DiGraph instances as values,
    where the DiGraph does not have any edges yet.
    WARNING: side effect on contents of digraph: will add the edges
    """
    arbors = {}
    # Define edges, which may result in multiple subgraphs for each skeleton
    # when splitting at low-confidence edges:
    if 0 == confidence_threshold:
        # Do not split skeletons
        for row in rows:
            if row[1]:
                digraphs[row[3]].add_edge(row[1], row[0])
        for skid, digraph in digraphs.iteritems():
            arbors[skid] = [digraph]
    else:
        # The DiGraph representing the skeleton may be disconnected at a low-confidence edge
        to_split = set()
        for row in rows:
            if row[2] < confidence_threshold:
                to_split.add(row[3])
            elif row[1]:
                digraphs[row[3]].add_edge(row[1], row[0])
        for skid, digraph in digraphs.iteritems():
            if skid in to_split:
                arbors[skid] = weakly_connected_component_subgraphs(digraph)
            else:
                arbors[skid] = [digraph]

    return arbors
Example #3
0
def subgraphs(digraph, skeleton_id):
    chunks = list(weakly_connected_component_subgraphs(digraph))
    if 1 == len(chunks):
        chunkIDs = (str(skeleton_id),)
    else:
        chunkIDs = tuple('%s_%s' % (skeleton_id, (i+1)) for i in range(len(chunks)))
    return chunks, chunkIDs
Example #4
0
def subgraphs(digraph, skeleton_id):
    chunks = weakly_connected_component_subgraphs(digraph)
    if 1 == len(chunks):
        chunkIDs = (str(skeleton_id),)
    else:
        chunkIDs = tuple('%s_%s' % (skeleton_id, (i+1)) for i in range(len(chunks)))
    return chunks, chunkIDs
Example #5
0
def subgraphs(digraph, skeleton_id) -> Tuple[List, Tuple]:
    chunks = list(weakly_connected_component_subgraphs(digraph))
    if 1 == len(chunks):
        chunkIDs = (str(skeleton_id),) # type: Tuple
                                       # Note: Here we're loosening the implicit type
    else:
        chunkIDs = tuple('%s_%s' % (skeleton_id, (i+1)) for i in range(len(chunks)))
    return chunks, chunkIDs
Example #6
0
def _skeleton_graph(project_id, skeleton_ids, confidence_threshold):
    """ Assumes all skeleton_ids belong to project_id. """
    skeletons_string = ",".join(str(int(x)) for x in skeleton_ids)
    cursor = connection.cursor()

    # Fetch all treenodes of all skeletons
    cursor.execute('''
    SELECT id, parent_id, confidence, skeleton_id
    FROM treenode
    WHERE skeleton_id IN (%s)
    ''' % skeletons_string)
    rows = tuple(cursor.fetchall())
    # Each skeleton is represented with a DiGraph
    arbors = defaultdict(nx.DiGraph)

    # Create a DiGraph for every skeleton
    for row in rows:
        arbors[row[3]].add_node(row[0])
    # Define edges, which may result in multiple subgraphs for each skeleton
    # when splitting at low-confidence edges:
    if 0 == confidence_threshold:
        # Do not split skeletons
        for row in rows:
            arbors[row[3]].add_edge(row[1], row[0])
        for skid, digraph in arbors.iteritems():
            arbors[skid] = [digraph]
    else:
        # The DiGraph representing the skeleton may be disconnected at a low-confidence edge
        to_split = set()
        for row in rows:
            if row[2] < confidence_threshold:
                to_split.add(row[3])
            else:
                arbors[row[3]].add_edge(row[1], row[0])
        for skid, digraph in arbors.iteritems():
            if skid in to_split:
                arbors[skid] = weakly_connected_component_subgraphs(digraph)
            else:
                arbors[skid] = [digraph]

    # Fetch all synapses
    relations = {'presynaptic_to': -1, 'postsynaptic_to': -1}
    for r in Relation.objects.filter(relation_name__in=('presynaptic_to', 'postsynaptic_to'), project_id=project_id).values_list('relation_name', 'id'):
        relations[r[0]] = r[1]
    cursor.execute('''
    SELECT connector_id, relation_id, treenode_id, skeleton_id
    FROM treenode_connector
    WHERE skeleton_id IN (%s)
    ''' % skeletons_string)
    def container():
        return defaultdict(list)
    connectors = defaultdict(container)
    for row in cursor.fetchall():
        connectors[row[0]][row[1]].append((row[2], row[3]))

    # Obtain neuron names
    cursor.execute('''
    SELECT cici.class_instance_a, ci.name
    FROM class_instance ci,
         class_instance_class_instance cici,
         relation r
    WHERE cici.class_instance_a IN (%s)
      AND cici.class_instance_b = ci.id
      AND cici.relation_id = r.id
      AND r.relation_name = 'model_of'
    ''' % skeletons_string)
    names = {row[0]: row[1] for row in cursor.fetchall()}

    # A DiGraph representing the connections between the arbors (every node is an arbor)
    circuit = nx.DiGraph()
    for skid, digraphs in arbors.iteritems():
        for i, g in enumerate(sorted(digraphs, key=len, reverse=True)):
            circuit.add_node(g, {'id': "%s_%s" % (skid, i+1),
                                 'label': "%s [%s]" % (names[skid], i+1),
                                 'skeleton_id': skid,
                                 'node_count': len(g)})
    # Define edges between arbors, with number of synapses as an edge property
    for c in connectors.values():
        for pre_treenode, pre_skeleton in c[relations['presynaptic_to']]:
            for pre_arbor in arbors.get(pre_skeleton, ()):
                if pre_treenode in pre_arbor:
                    # Found the DiGraph representing an arbor derived from the skeleton to which the presynaptic treenode belongs.
                    for post_treenode, post_skeleton in c[relations['postsynaptic_to']]:
                        for post_arbor in arbors.get(post_skeleton, ()):
                            if post_treenode in post_arbor:
                                # Found the DiGraph representing an arbor derived from the skeleton to which the postsynaptic treenode belongs.
                                edge_props = circuit.get_edge_data(pre_arbor, post_arbor)
                                if edge_props:
                                    edge_props['c'] += 1
                                else:
                                    circuit.add_edge(pre_arbor, post_arbor, {'c': 1})
                                break
                    break
    return circuit