Skip to content

Commit

Permalink
Add back_tracking_segments() which is then called by is_back_tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-berchet committed Apr 12, 2024
1 parent 7e41691 commit b47db65
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
31 changes: 25 additions & 6 deletions neurom/check/morphtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def is_flat(neurite, tol, method='tolerance'):
return any(ext < float(tol))


def is_back_tracking(neurite):
def back_tracking_segments(neurite):
"""Check if a neurite process backtracks to a previous node.
Back-tracking takes place
Expand All @@ -95,10 +95,11 @@ def is_back_tracking(neurite):
neurite(Neurite): neurite to operate on
Returns:
True Under the following scenaria:
1. A segment endpoint falls back and overlaps with a previous segment's point
2. The geometry of a segment overlaps with a previous one in the section
A generator of tuples containing the section ID and the two segment indices in this section
for which a back tracking is detected (so the first point of these segments can be
retrieved with ``morph.section(section_id).points[segment_id]``.
"""
# pylint: disable=too-many-locals
def pair(segs):
"""Pairs the input list into triplets."""
return zip(segs, segs[1:])
Expand Down Expand Up @@ -179,9 +180,27 @@ def is_inside_cylinder(seg1, seg2):
for i, seg1 in enumerate(segment_pairs[1:]):
# check if the end point of the segment lies within the previous
# ones in the current section
for seg2 in segment_pairs[0: i + 1]:
for j, seg2 in enumerate(segment_pairs[0: i + 1]):
if is_inside_cylinder(seg1, seg2):
return True
yield (sec.id, i, j)


def is_back_tracking(neurite):
"""Check if a neurite process backtracks to a previous node.
See back_tracking_segments() for more details.
Args:
neurite(Neurite): neurite to operate on
Returns:
True Under the following scenaria:
1. A segment endpoint falls back and overlaps with a previous segment's point
2. The geometry of a segment overlaps with a previous one in the section
"""
for _i in back_tracking_segments(neurite):
# If one segment is found then the neurite is back tracking
return True
return False


Expand Down
24 changes: 24 additions & 0 deletions tests/check/test_morphtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,30 @@ def test_is_flat():
assert not mt.is_flat(m.neurites[0], 0.1, method='ratio')


def test_back_tracking_segments():
# case 1: a back-track falls directly on a previous node
t1 = _generate_back_track_tree(1, (0.0, 0.0, 0.0))
assert list(mt.back_tracking_segments(t1.neurites[0])) == [(2, 1, 0), (2, 1, 1)]

# case 2: a zigzag is close to another segment
t2 = _generate_back_track_tree(1, (0.1, -0.1, 0.02))
assert list(mt.back_tracking_segments(t2.neurites[0])) == [(2, 1, 0), (2, 1, 1)]

# case 3: a zigzag is close to another segment 2
t3 = _generate_back_track_tree(1, (-0.2, 0.04, 0.144))
assert list(mt.back_tracking_segments(t3.neurites[0])) == [(2, 1, 0)]

# case 4: a zigzag far from civilization
t4 = _generate_back_track_tree(1, (10.0, -10.0, 10.0))
assert list(mt.back_tracking_segments(t4.neurites[0])) == []

# case 5: a zigzag on another section
# currently zigzag is defined on the same section
# thus this test should not be true
t5 = _generate_back_track_tree(0, (-0.2, 0.04, 0.144))
assert list(mt.back_tracking_segments(t5.neurites[0])) == []


def test_is_back_tracking():
# case 1: a back-track falls directly on a previous node
t = _generate_back_track_tree(1, (0., 0., 0.))
Expand Down

0 comments on commit b47db65

Please sign in to comment.