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
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
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
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
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