def _node_centrality_by_synapse(tree, nodes: Dict, totalOutputs: int, totalInputs: int) -> None: """ tree: a DiGraph nodes: a dictionary of treenode ID vs Counts instance totalOutputs: the total number of output synapses of the tree totalInputs: the total number of input synapses of the tree Returns nothing, the results are an update to the Counts instance of each treenode entry in nodes, namely the nPossibleIOPaths. """ # 1. Ensure the root is an end by checking that it has only one child; otherwise reroot at the first end node found if 0 == totalOutputs: # Not computable for counts in nodes.values(): counts.synapse_centrality = -1 return if len(list(tree.successors(find_root(tree)))) > 1: # Reroot at the first end node found tree = tree.copy() endNode = next(nodeID for nodeID in nodes.keys() if not list(tree.successors(nodeID))) reroot(tree, endNode) # 2. Partition into sequences, sorted from small to large sequences = sorted(partition(tree), key=len) # 3. Traverse all partitions counting synapses seen for seq in sequences: # Each seq runs from an end node towards the root or a branch node seenI = 0 seenO = 0 for nodeID in seq: counts = nodes[nodeID] seenI += counts.inputs + counts.seenInputs seenO += counts.outputs + counts.seenOutputs counts.seenInputs = seenI counts.seenOutputs = seenO counts.nPossibleIOPaths = counts.seenInputs * ( totalOutputs - counts.seenOutputs) + counts.seenOutputs * ( totalInputs - counts.seenInputs) counts.synapse_centrality = counts.nPossibleIOPaths / float( totalOutputs)
def _node_centrality_by_synapse(tree, nodes, totalOutputs, totalInputs): """ tree: a DiGraph nodes: a dictionary of treenode ID vs Counts instance totalOutputs: the total number of output synapses of the tree totalInputs: the total number of input synapses of the tree Returns nothing, the results are an update to the Counts instance of each treenode entry in nodes, namely the nPossibleIOPaths. """ # 1. Ensure the root is an end by checking that it has only one child; otherwise reroot at the first end node found if 0 == totalOutputs: # Not computable for counts in nodes.values(): counts.synapse_centrality = -1 return if len(tree.successors(find_root(tree))) > 1: # Reroot at the first end node found tree = tree.copy() endNode = next(nodeID for nodeID in nodes.keys() if not tree.successors(nodeID)) reroot(tree, endNode) # 2. Partition into sequences, sorted from small to large sequences = sorted(partition(tree), key=len) # 3. Traverse all partitions counting synapses seen for seq in sequences: # Each seq runs from an end node towards the root or a branch node seenI = 0 seenO = 0 for nodeID in seq: counts = nodes[nodeID] seenI += counts.inputs + counts.seenInputs seenO += counts.outputs + counts.seenOutputs counts.seenInputs = seenI counts.seenOutputs = seenO counts.nPossibleIOPaths = counts.seenInputs * (totalOutputs - counts.seenOutputs) + counts.seenOutputs * (totalInputs - counts.seenInputs) counts.synapse_centrality = counts.nPossibleIOPaths / float(totalOutputs)
def last_openleaf(request, project_id=None, skeleton_id=None): """ Return the ID of the nearest node (or itself), and its location string; or two nulls if none found. """ tnid = int(request.POST['tnid']) cursor = connection.cursor() cursor.execute("SELECT id FROM relation WHERE project_id=%s AND relation_name='labeled_as'" % int(project_id)) labeled_as = cursor.fetchone()[0] # Select all nodes and their tags cursor.execute(''' SELECT t.id, t.parent_id, t.location_x, t.location_y, t.location_z, ci.name FROM treenode t LEFT OUTER JOIN (treenode_class_instance tci INNER JOIN class_instance ci ON tci.class_instance_id = ci.id AND tci.relation_id = %s) ON t.id = tci.treenode_id WHERE t.skeleton_id = %s ''' % (labeled_as, int(skeleton_id))) # Some entries repeated, when a node has more than one tag # Create a graph with edges from parent to child, and accumulate parents tree = nx.DiGraph() for row in cursor.fetchall(): nodeID = row[0] if row[1]: # It is ok to add edges that already exist: DiGraph doesn't keep duplicates tree.add_edge(row[1], nodeID) else: tree.add_node(nodeID) tree.node[nodeID]['loc'] = (row[2], row[3], row[4]) if row[5]: props = tree.node[nodeID] tags = props.get('tags') if tags: tags.append(row[5]) else: props['tags'] = [row[5]] if tnid not in tree: raise Exception("Could not find %s in skeleton %s" % (tnid, int(skeleton_id))) reroot(tree, tnid) distances = edge_count_to_root(tree, root_node=tnid) # Iterate end nodes, find closest nearest = None distance = tree.number_of_nodes() + 1 loc = None other_tags = set(('uncertain continuation', 'not a branch', 'soma')) for nodeID, out_degree in tree.out_degree_iter(): if 0 == out_degree: # Found an end node props = tree.node[nodeID] # Check if not tagged with a tag containing 'end' if not 'tags' in props and not [s for s in props if 'end' in s or s in other_tags]: # Found an open end d = distances[nodeID] if d < distance: nearest = nodeID distance = d loc = props['loc'] return HttpResponse(json.dumps((nearest, loc)))