Browse Source

added Surface.find_label_border_polygonal_chains()

Fabian Peter Hammerle 5 years ago
parent
commit
2e61c61186
2 changed files with 36 additions and 0 deletions
  1. 22 0
      freesurfer_surface/__init__.py
  2. 14 0
      tests/test_surface.py

+ 22 - 0
freesurfer_surface/__init__.py

@@ -355,3 +355,25 @@ class Surface:
             ))
             if len(border_vertex_indices) == 2:
                 yield _LineSegment(border_vertex_indices)
+
+    def find_label_border_polygonal_chains(self, label: Label) -> typing.Iterator[PolygonalChain]:
+        segments = set(self._find_label_border_segments(label))
+        available_chains = collections.deque(PolygonalChain(segment.vertex_indices)
+                                             for segment in segments)
+        # irrespective of its poor performance,
+        # we keep this approach since it's easy to read and fast enough
+        while available_chains:
+            chain = available_chains.pop()
+            last_chains_len = None
+            while last_chains_len != len(available_chains):
+                last_chains_len = len(available_chains)
+                checked_chains = collections.deque()
+                while available_chains:
+                    potential_neighbour = available_chains.pop()
+                    try:
+                        chain.connect(potential_neighbour)
+                    except PolygonalChainsNotOverlapingError:
+                        checked_chains.append(potential_neighbour)
+                available_chains = checked_chains
+            assert all((segment in segments) for segment in chain.segments())
+            yield chain

+ 14 - 0
tests/test_surface.py

@@ -149,3 +149,17 @@ def test__find_label_border_segments():
         for other_vertex_index in [32064, 33449, 33455, 33449, 33455]:
             assert _LineSegment((other_vertex_index, border_vertex_index)) not in border_segments
             assert _LineSegment((border_vertex_index, other_vertex_index)) not in border_segments
+
+
+def test_find_label_border_polygonal_chains():
+    surface = Surface.read_triangular(SURFACE_FILE_PATH)
+    surface.load_annotation_file(ANNOTATION_FILE_PATH)
+    precentral_label, = filter(lambda l: l.name == 'precentral',
+                               surface.annotation.labels.values())
+    border_chain, = surface.find_label_border_polygonal_chains(precentral_label)
+    vertex_indices = list(border_chain.vertex_indices)
+    assert len(vertex_indices) == 418
+    min_index = vertex_indices.index(min(vertex_indices))
+    vertex_indices_normalized = vertex_indices[min_index:] + vertex_indices[:min_index]
+    assert vertex_indices_normalized[:4] == [32065, 32072, 32073, 32080]
+    assert vertex_indices_normalized[-4:] == [36281, 34870, 33454, 33450]