def calc_arc_choord(anno, nxg=None):
"""
Calculates the arc choord length of an annotation object as a measure of
the tortuosity of an annotation. The return value is 1 for a completely
straight skeleton. It uses the two most distant end nodes in an
annotation and divides it by the graph path length between them.
:param anno:
:param nxg:
:return: float
"""
if not nxg:
nxg = su.annoToNXGraph(anno)
# find end nodes
e_nodes = list({k for k, v in nxg.degree().iteritems() if v == 1})
# get euclidian distance between end nodes max away
# this can be done more efficiently by computing a convex hull first,
# but the naive implementation should be fast enough for now
dists = []
for pair in itertools.permutations(e_nodes, 2):
dists.append((pair, pair[0].distance_scaled(pair[1])))
dists = sorted(dists, key=lambda x: x[1])
try:
path_len = nx.shortest_path_length(nxg, source=dists[-1][0][0],
target=dists[-1][0][1],
weight='weight')
except:
# print('No path between nodes for tortuosity calculation for neuron %s' %
# anno.filename)
return 0
return dists[-1][1] / path_len
评论列表
文章目录