Skip to content

Commit 2e8296f

Browse files
committed
Test and fix SWC DFS sorting
1 parent e169670 commit 2e8296f

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

navis/io/swc_io.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ def write_swc(x: 'core.NeuronObject',
450450
451451
export_connectors : bool, optional
452452
If True, will label nodes with pre- ("7") and
453-
postsynapse ("8"). Because only one label can be given
453+
postsynapse ("8"), or both ("9"). Because only one label can be given
454454
this might drop synapses (i.e. in case of multiple
455455
pre- and/or postsynapses on a single node)! ``labels``
456456
must be ``True`` for this to have any effect.
@@ -613,7 +613,7 @@ def _sort_swc_dfs(df: pd.DataFrame, roots, sort_children=True, inplace=False):
613613
while to_visit:
614614
node_id = to_visit.pop()
615615
order[node_id_to_orig_idx[node_id]] = count
616-
cs = children.pop(order[-1], [])
616+
cs = children.pop(node_id, [])
617617
if sort_children:
618618
to_visit.extend(sorted(cs, reverse=True))
619619
else:
@@ -627,7 +627,7 @@ def _sort_swc_dfs(df: pd.DataFrame, roots, sort_children=True, inplace=False):
627627

628628
df["_order"] = order
629629
df.sort_values("_order", inplace=True)
630-
df.drop(columns=["_order"])
630+
df.drop(columns=["_order"], inplace=True)
631631
return df
632632

633633

@@ -680,6 +680,7 @@ def make_swc_table(x: 'core.TreeNeuron',
680680
x = x.to_skeleton()
681681

682682
# Work on a copy sorted in depth-first order
683+
# swc = _sort_swc_parent(x.nodes, inplace=False)
683684
swc = _sort_swc_dfs(x.nodes, x.root, inplace=False)
684685

685686
# Add labels

tests/test_io.py

+43
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pytest
33
import tempfile
44
import numpy as np
5+
import pandas as pd
56

67
from pathlib import Path
78

@@ -29,6 +30,48 @@ def test_swc_io(filename):
2930
assert len(n) == len(n2)
3031

3132

33+
@pytest.fixture
34+
def simple_neuron():
35+
"""Neuron with 1 branch and no connectors.
36+
37+
[3]
38+
|
39+
2 -- 4
40+
|
41+
1
42+
"""
43+
nrn = navis.TreeNeuron(None)
44+
dtypes = {
45+
"node_id": np.uint64,
46+
"parent_id": np.int64,
47+
"x": float,
48+
"y": float,
49+
"z": float,
50+
}
51+
df = pd.DataFrame([
52+
[1, 2, 0, 2, 0],
53+
[2, 3, 0, 1, 0],
54+
[3, -1, 0, 0, 0], # root
55+
[4, 2, 1, 1, 0]
56+
], columns=list(dtypes)).astype(dtypes)
57+
nrn.nodes = df
58+
return nrn
59+
60+
61+
def assert_parent_defined(df: pd.DataFrame):
62+
defined = set()
63+
for node, _structure, _x, _y, _z, _r, parent in df.itertuples(index=False):
64+
defined.add(node)
65+
if parent == -1:
66+
continue
67+
assert parent in defined, f"Child {node} has undefined parent {parent}"
68+
69+
70+
def test_swc_io_order(simple_neuron):
71+
df = navis.io.swc_io.make_swc_table(simple_neuron, True)
72+
assert_parent_defined(df)
73+
74+
3275
@pytest.mark.parametrize("filename", ['',
3376
'neurons.zip',
3477
'{neuron.id}@neurons.zip'])

0 commit comments

Comments
 (0)