swcgeom 0.17.1__py3-none-any.whl → 0.18.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of swcgeom might be problematic. Click here for more details.
- swcgeom/__init__.py +14 -0
- swcgeom/_version.py +2 -2
- swcgeom/analysis/__init__.py +15 -0
- swcgeom/analysis/feature_extractor.py +27 -3
- swcgeom/analysis/features.py +31 -4
- swcgeom/analysis/lmeasure.py +43 -7
- swcgeom/analysis/sholl.py +21 -24
- swcgeom/analysis/trunk.py +15 -0
- swcgeom/analysis/visualization.py +15 -0
- swcgeom/analysis/visualization3d.py +15 -0
- swcgeom/analysis/volume.py +15 -0
- swcgeom/core/__init__.py +15 -0
- swcgeom/core/branch.py +15 -0
- swcgeom/core/branch_tree.py +15 -0
- swcgeom/core/compartment.py +15 -0
- swcgeom/core/node.py +30 -1
- swcgeom/core/path.py +18 -7
- swcgeom/core/population.py +43 -3
- swcgeom/core/swc.py +15 -0
- swcgeom/core/swc_utils/__init__.py +15 -1
- swcgeom/core/swc_utils/assembler.py +15 -0
- swcgeom/core/swc_utils/base.py +15 -0
- swcgeom/core/swc_utils/checker.py +19 -12
- swcgeom/core/swc_utils/io.py +17 -1
- swcgeom/core/swc_utils/normalizer.py +16 -1
- swcgeom/core/swc_utils/subtree.py +15 -0
- swcgeom/core/tree.py +37 -9
- swcgeom/core/tree_utils.py +17 -7
- swcgeom/core/tree_utils_impl.py +15 -0
- swcgeom/images/__init__.py +15 -0
- swcgeom/images/augmentation.py +15 -0
- swcgeom/images/contrast.py +15 -0
- swcgeom/images/folder.py +17 -10
- swcgeom/images/io.py +18 -6
- swcgeom/transforms/__init__.py +16 -0
- swcgeom/transforms/base.py +17 -2
- swcgeom/transforms/branch.py +74 -8
- swcgeom/transforms/branch_tree.py +82 -0
- swcgeom/transforms/geometry.py +22 -7
- swcgeom/transforms/image_preprocess.py +15 -0
- swcgeom/transforms/image_stack.py +30 -4
- swcgeom/transforms/images.py +17 -10
- swcgeom/transforms/mst.py +15 -0
- swcgeom/transforms/neurolucida_asc.py +16 -1
- swcgeom/transforms/path.py +15 -0
- swcgeom/transforms/population.py +15 -0
- swcgeom/transforms/tree.py +76 -23
- swcgeom/transforms/tree_assembler.py +19 -4
- swcgeom/utils/__init__.py +15 -0
- swcgeom/utils/debug.py +15 -0
- swcgeom/utils/download.py +59 -21
- swcgeom/utils/dsu.py +15 -0
- swcgeom/utils/ellipse.py +15 -0
- swcgeom/utils/file.py +15 -0
- swcgeom/utils/neuromorpho.py +18 -7
- swcgeom/utils/numpy_helper.py +15 -0
- swcgeom/utils/plotter_2d.py +15 -0
- swcgeom/utils/plotter_3d.py +18 -1
- swcgeom/utils/renderer.py +15 -0
- swcgeom/utils/sdf.py +17 -5
- swcgeom/utils/solid_geometry.py +15 -0
- swcgeom/utils/transforms.py +16 -1
- swcgeom/utils/volumetric_object.py +15 -0
- {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/LICENSE +1 -1
- {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/METADATA +26 -22
- swcgeom-0.18.1.dist-info/RECORD +68 -0
- {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/WHEEL +1 -1
- swcgeom-0.17.1.dist-info/RECORD +0 -67
- {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/top_level.txt +0 -0
swcgeom/__init__.py
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
1
15
|
"""A neuron geometry library for swc format."""
|
|
2
16
|
|
|
3
17
|
from swcgeom import analysis, core, images, transforms
|
swcgeom/_version.py
CHANGED
swcgeom/analysis/__init__.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Analysis for neuron trees."""
|
|
2
17
|
|
|
3
18
|
from swcgeom.analysis.feature_extractor import *
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Easy way to compute and visualize common features for feature.
|
|
2
17
|
|
|
3
18
|
Notes
|
|
@@ -19,8 +34,8 @@ import seaborn as sns
|
|
|
19
34
|
from matplotlib.axes import Axes
|
|
20
35
|
|
|
21
36
|
from swcgeom.analysis.features import (
|
|
22
|
-
BifurcationFeatures,
|
|
23
37
|
BranchFeatures,
|
|
38
|
+
FurcationFeatures,
|
|
24
39
|
NodeFeatures,
|
|
25
40
|
PathFeatures,
|
|
26
41
|
TipFeatures,
|
|
@@ -40,6 +55,9 @@ Feature = Literal[
|
|
|
40
55
|
"node_count",
|
|
41
56
|
"node_radial_distance",
|
|
42
57
|
"node_branch_order",
|
|
58
|
+
# furcation nodes
|
|
59
|
+
"furcation_count",
|
|
60
|
+
"furcation_radial_distance",
|
|
43
61
|
# bifurcation nodes
|
|
44
62
|
"bifurcation_count",
|
|
45
63
|
"bifurcation_radial_distance",
|
|
@@ -57,7 +75,7 @@ Feature = Literal[
|
|
|
57
75
|
NDArrayf32 = npt.NDArray[np.float32]
|
|
58
76
|
FeatAndKwargs = Feature | tuple[Feature, dict[str, Any]]
|
|
59
77
|
|
|
60
|
-
Feature1D = set(["length", "volume", "node_count", "
|
|
78
|
+
Feature1D = set(["length", "volume", "node_count", "furcation_count", "tip_count"])
|
|
61
79
|
|
|
62
80
|
|
|
63
81
|
class Features:
|
|
@@ -70,7 +88,7 @@ class Features:
|
|
|
70
88
|
@cached_property
|
|
71
89
|
def node_features(self) -> NodeFeatures: return NodeFeatures(self.tree)
|
|
72
90
|
@cached_property
|
|
73
|
-
def
|
|
91
|
+
def furcation_features(self) -> FurcationFeatures: return FurcationFeatures(self.node_features)
|
|
74
92
|
@cached_property
|
|
75
93
|
def tip_features(self) -> TipFeatures: return TipFeatures(self.node_features)
|
|
76
94
|
@cached_property
|
|
@@ -214,6 +232,12 @@ class FeatureExtractor(ABC):
|
|
|
214
232
|
) -> Axes:
|
|
215
233
|
raise NotImplementedError()
|
|
216
234
|
|
|
235
|
+
def get_bifurcation_count(self, **kwargs):
|
|
236
|
+
raise DeprecationWarning("Use `furcation_count` instead.")
|
|
237
|
+
|
|
238
|
+
def get_bifurcation_radial_distance(self, **kwargs):
|
|
239
|
+
raise DeprecationWarning("Use `furcation_radial_distance` instead.")
|
|
240
|
+
|
|
217
241
|
|
|
218
242
|
class TreeFeatureExtractor(FeatureExtractor):
|
|
219
243
|
"""Extract feature from tree."""
|
swcgeom/analysis/features.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Feature anlysis of tree."""
|
|
2
17
|
|
|
3
18
|
from abc import ABC, abstractmethod
|
|
@@ -6,7 +21,7 @@ from typing import TypeVar
|
|
|
6
21
|
|
|
7
22
|
import numpy as np
|
|
8
23
|
import numpy.typing as npt
|
|
9
|
-
from typing_extensions import Self
|
|
24
|
+
from typing_extensions import Self, deprecated
|
|
10
25
|
|
|
11
26
|
from swcgeom.core import Branch, BranchTree, Tree
|
|
12
27
|
|
|
@@ -121,12 +136,24 @@ class _SubsetNodesFeatures(ABC):
|
|
|
121
136
|
return cls(NodeFeatures(tree))
|
|
122
137
|
|
|
123
138
|
|
|
124
|
-
class
|
|
125
|
-
"""Evaluate
|
|
139
|
+
class FurcationFeatures(_SubsetNodesFeatures):
|
|
140
|
+
"""Evaluate furcation node feature of tree."""
|
|
126
141
|
|
|
127
142
|
@cached_property
|
|
128
143
|
def nodes(self) -> npt.NDArray[np.bool_]:
|
|
129
|
-
return np.array([n.
|
|
144
|
+
return np.array([n.is_furcation() for n in self._features.tree])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@deprecated("Use FurcationFeatures instead")
|
|
148
|
+
class BifurcationFeatures(FurcationFeatures):
|
|
149
|
+
"""Evaluate bifurcation node feature of tree.
|
|
150
|
+
|
|
151
|
+
Notes
|
|
152
|
+
-----
|
|
153
|
+
Deprecated due to the wrong spelling of furcation. For now, it
|
|
154
|
+
is just an alias of `FurcationFeatures` and raise a warning. It
|
|
155
|
+
will be change to raise an error in the future.
|
|
156
|
+
"""
|
|
130
157
|
|
|
131
158
|
|
|
132
159
|
class TipFeatures(_SubsetNodesFeatures):
|
swcgeom/analysis/lmeasure.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""L-Measure analysis."""
|
|
2
17
|
|
|
3
18
|
import math
|
|
@@ -5,9 +20,7 @@ from typing import Literal
|
|
|
5
20
|
|
|
6
21
|
import numpy as np
|
|
7
22
|
import numpy.typing as npt
|
|
8
|
-
|
|
9
23
|
from swcgeom.core import Branch, Compartment, Node, Tree
|
|
10
|
-
from swcgeom.utils import angle
|
|
11
24
|
|
|
12
25
|
__all__ = ["LMeasure"]
|
|
13
26
|
|
|
@@ -69,7 +82,7 @@ class LMeasure:
|
|
|
69
82
|
--------
|
|
70
83
|
L-Measure: http://cng.gmu.edu:8080/Lm/help/N_bifs.htm
|
|
71
84
|
"""
|
|
72
|
-
return len(tree.
|
|
85
|
+
return len(tree.get_furcations())
|
|
73
86
|
|
|
74
87
|
def n_branch(self, tree: Tree) -> int:
|
|
75
88
|
"""Number of branches.
|
|
@@ -163,12 +176,15 @@ class LMeasure:
|
|
|
163
176
|
--------
|
|
164
177
|
L-Measure: http://cng.gmu.edu:8080/Lm/help/Partition_asymmetry.htm
|
|
165
178
|
"""
|
|
179
|
+
|
|
166
180
|
children = n.children()
|
|
167
181
|
assert (
|
|
168
182
|
len(children) == 2
|
|
169
183
|
), "Partition asymmetry is only defined for bifurcations"
|
|
170
184
|
n1 = len(children[0].subtree().get_tips())
|
|
171
185
|
n2 = len(children[1].subtree().get_tips())
|
|
186
|
+
if n1 == n2:
|
|
187
|
+
return 0
|
|
172
188
|
return abs(n1 - n2) / (n1 + n2 - 2)
|
|
173
189
|
|
|
174
190
|
def fractal_dim(self):
|
|
@@ -336,7 +352,7 @@ class LMeasure:
|
|
|
336
352
|
return (da**rall_power + db**rall_power) / dp**rall_power
|
|
337
353
|
|
|
338
354
|
def bif_ampl_local(self, bif: Tree.Node) -> float:
|
|
339
|
-
"""
|
|
355
|
+
"""Bifurcation angle.
|
|
340
356
|
|
|
341
357
|
Given a bifurcation, this function returns the angle between
|
|
342
358
|
the first two compartments (in degree).
|
|
@@ -350,7 +366,7 @@ class LMeasure:
|
|
|
350
366
|
return np.degrees(angle(v1, v2))
|
|
351
367
|
|
|
352
368
|
def bif_ampl_remote(self, bif: Tree.Node) -> float:
|
|
353
|
-
"""
|
|
369
|
+
"""Bifurcation angle.
|
|
354
370
|
|
|
355
371
|
This function returns the angle between two bifurcation points
|
|
356
372
|
or between bifurcation point and terminal point or between two
|
|
@@ -361,7 +377,7 @@ class LMeasure:
|
|
|
361
377
|
L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_ampl_remote.htm
|
|
362
378
|
"""
|
|
363
379
|
|
|
364
|
-
v1, v2 = self.
|
|
380
|
+
v1, v2 = self._bif_vector_remote(bif)
|
|
365
381
|
return np.degrees(angle(v1, v2))
|
|
366
382
|
|
|
367
383
|
def bif_tilt_local(self, bif: Tree.Node) -> float:
|
|
@@ -665,7 +681,7 @@ class LMeasure:
|
|
|
665
681
|
n = node
|
|
666
682
|
order = 0
|
|
667
683
|
while n is not None:
|
|
668
|
-
if n.
|
|
684
|
+
if n.is_furcation():
|
|
669
685
|
order += 1
|
|
670
686
|
n = n.parent()
|
|
671
687
|
return order
|
|
@@ -819,3 +835,23 @@ def pill_surface_area(ra: float, rb: float, h: float) -> float:
|
|
|
819
835
|
bottom_hemisphere_area = 2 * math.pi * rb**2
|
|
820
836
|
total_area = lateral_area + top_hemisphere_area + bottom_hemisphere_area
|
|
821
837
|
return total_area
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
# TODO: move to `utils`
|
|
841
|
+
def angle(a: npt.ArrayLike, b: npt.ArrayLike) -> float:
|
|
842
|
+
"""Get the angle of vectors.
|
|
843
|
+
|
|
844
|
+
Returns
|
|
845
|
+
-------
|
|
846
|
+
angle : float
|
|
847
|
+
Angle [0, PI) in radians.
|
|
848
|
+
"""
|
|
849
|
+
|
|
850
|
+
a, b = np.array(a), np.array(b)
|
|
851
|
+
if np.linalg.norm(a) == 0 or np.linalg.norm(b) == 0:
|
|
852
|
+
raise ValueError("Input vectors must not be zero vectors.")
|
|
853
|
+
|
|
854
|
+
costheta = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
|
|
855
|
+
costheta = np.clip(costheta, -1, 1) # avoid numerical errors
|
|
856
|
+
theta = np.arccos(costheta)
|
|
857
|
+
return theta
|
swcgeom/analysis/sholl.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Sholl analysis."""
|
|
2
17
|
|
|
3
18
|
import warnings
|
|
@@ -8,6 +23,7 @@ import numpy.typing as npt
|
|
|
8
23
|
import seaborn as sns
|
|
9
24
|
from matplotlib.axes import Axes
|
|
10
25
|
from matplotlib.figure import Figure
|
|
26
|
+
from typing_extensions import deprecated
|
|
11
27
|
|
|
12
28
|
from swcgeom.analysis.visualization import draw
|
|
13
29
|
from swcgeom.core import Tree
|
|
@@ -160,20 +176,17 @@ class Sholl:
|
|
|
160
176
|
|
|
161
177
|
return self.get_rs(self.rmax, steps)
|
|
162
178
|
|
|
179
|
+
@deprecated("Use `Sholl.get(x)` instead")
|
|
163
180
|
def get_count(self) -> npt.NDArray[np.int32]:
|
|
164
181
|
"""Get the count of intersection.
|
|
165
182
|
|
|
166
183
|
.. deprecated:: 0.5.0
|
|
167
|
-
Use :meth:`Sholl.get` instead.
|
|
184
|
+
Use :meth:`Sholl(x).get()` instead.
|
|
168
185
|
"""
|
|
169
186
|
|
|
170
|
-
warnings.warn(
|
|
171
|
-
"`Sholl.get_count` has been renamed to `get` since v0.5.0, "
|
|
172
|
-
"and will be removed in next version",
|
|
173
|
-
DeprecationWarning,
|
|
174
|
-
)
|
|
175
187
|
return self.get().astype(np.int32)
|
|
176
188
|
|
|
189
|
+
@deprecated("Use `Shool(x).get().mean()` instead")
|
|
177
190
|
def avg(self) -> float:
|
|
178
191
|
"""Get the average of the count of intersection.
|
|
179
192
|
|
|
@@ -181,14 +194,9 @@ class Sholl:
|
|
|
181
194
|
Use :meth:`Shool(x).get().mean()` instead.
|
|
182
195
|
"""
|
|
183
196
|
|
|
184
|
-
warnings.warn(
|
|
185
|
-
"`Sholl.avg` has been deprecated since v0.6.0 and will be "
|
|
186
|
-
"removed in next version, use `Shool(x).get().mean()` "
|
|
187
|
-
"instead",
|
|
188
|
-
DeprecationWarning,
|
|
189
|
-
)
|
|
190
197
|
return self.get().mean()
|
|
191
198
|
|
|
199
|
+
@deprecated("Use `Shool(x).get().std()` instead")
|
|
192
200
|
def std(self) -> float:
|
|
193
201
|
"""Get the std of the count of intersection.
|
|
194
202
|
|
|
@@ -196,14 +204,9 @@ class Sholl:
|
|
|
196
204
|
Use :meth:`Shool(x).get().std()` instead.
|
|
197
205
|
"""
|
|
198
206
|
|
|
199
|
-
warnings.warn(
|
|
200
|
-
"`Sholl.std` has been deprecate since v0.6.0 and will be "
|
|
201
|
-
"removed in next version, use `Shool(x).get().std()` "
|
|
202
|
-
"instead",
|
|
203
|
-
DeprecationWarning,
|
|
204
|
-
)
|
|
205
207
|
return self.get().std()
|
|
206
208
|
|
|
209
|
+
@deprecated("Use `Shool(x).get().sum()` instead")
|
|
207
210
|
def sum(self) -> int:
|
|
208
211
|
"""Get the sum of the count of intersection.
|
|
209
212
|
|
|
@@ -211,10 +214,4 @@ class Sholl:
|
|
|
211
214
|
Use :meth:`Shool(x).get().sum()` instead.
|
|
212
215
|
"""
|
|
213
216
|
|
|
214
|
-
warnings.warn(
|
|
215
|
-
"`Sholl.sum` has been deprecate since v0.6.0 and will be "
|
|
216
|
-
"removed in next version, use `Shool(x).get().sum()` "
|
|
217
|
-
"instead",
|
|
218
|
-
DeprecationWarning,
|
|
219
|
-
)
|
|
220
217
|
return self.get().sum()
|
swcgeom/analysis/trunk.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Plot trunk and florets."""
|
|
2
17
|
|
|
3
18
|
# pylint: disable=invalid-name
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Painter utils."""
|
|
2
17
|
|
|
3
18
|
import os
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Painter utils.
|
|
2
17
|
|
|
3
18
|
Notes
|
swcgeom/analysis/volume.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Analysis of volume of a SWC tree."""
|
|
2
17
|
|
|
3
18
|
from typing import Literal
|
swcgeom/core/__init__.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Neuron trees."""
|
|
2
17
|
|
|
3
18
|
from swcgeom.core import swc_utils
|
swcgeom/core/branch.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Branch is a set of node points."""
|
|
2
17
|
|
|
3
18
|
from collections.abc import Iterable
|
swcgeom/core/branch_tree.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Branch tree is a simplified neuron tree."""
|
|
2
17
|
|
|
3
18
|
import itertools
|
swcgeom/core/compartment.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""The segment is a branch with two nodes."""
|
|
2
17
|
|
|
3
18
|
from collections.abc import Iterable
|
swcgeom/core/node.py
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Nueron node."""
|
|
2
17
|
|
|
3
18
|
from collections.abc import Iterable
|
|
@@ -5,6 +20,7 @@ from typing import Any, Generic
|
|
|
5
20
|
|
|
6
21
|
import numpy as np
|
|
7
22
|
import numpy.typing as npt
|
|
23
|
+
from typing_extensions import deprecated
|
|
8
24
|
|
|
9
25
|
from swcgeom.core.swc import DictSWC, SWCTypeVar
|
|
10
26
|
from swcgeom.core.swc_utils import SWCNames
|
|
@@ -95,9 +111,22 @@ class Node(Generic[SWCTypeVar]):
|
|
|
95
111
|
items = [self.id, self.type, x, y, z, r, self.pid]
|
|
96
112
|
return " ".join(map(str, items))
|
|
97
113
|
|
|
98
|
-
def
|
|
114
|
+
def is_furcation(self) -> bool:
|
|
115
|
+
"""Is furcation node."""
|
|
99
116
|
return np.count_nonzero(self.attach.pid() == self.id) > 1
|
|
100
117
|
|
|
118
|
+
@deprecated("Use is_furcation instead")
|
|
119
|
+
def is_bifurcation(self) -> bool:
|
|
120
|
+
"""Is furcation node.
|
|
121
|
+
|
|
122
|
+
Notes
|
|
123
|
+
-----
|
|
124
|
+
Deprecated due to the wrong spelling of furcation. For now, it
|
|
125
|
+
is just an alias of `is_furcation` and raise a warning. It will
|
|
126
|
+
be change to raise an error in the future.
|
|
127
|
+
"""
|
|
128
|
+
return self.is_furcation()
|
|
129
|
+
|
|
101
130
|
def is_tip(self) -> bool:
|
|
102
131
|
return self.id not in self.attach.pid()
|
|
103
132
|
|
swcgeom/core/path.py
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
|
+
# Copyright 2022-2025 Zexin Yuan
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
1
16
|
"""Nueron path."""
|
|
2
17
|
|
|
3
|
-
import warnings
|
|
4
18
|
from collections.abc import Iterable, Iterator
|
|
5
19
|
from typing import Generic, overload
|
|
6
20
|
|
|
7
21
|
import numpy as np
|
|
8
22
|
import numpy.typing as npt
|
|
23
|
+
from typing_extensions import deprecated
|
|
9
24
|
|
|
10
25
|
from swcgeom.core.node import Node
|
|
11
26
|
from swcgeom.core.swc import DictSWC, SWCLike, SWCTypeVar
|
|
@@ -16,7 +31,7 @@ __all__ = ["Path"]
|
|
|
16
31
|
class Path(SWCLike, Generic[SWCTypeVar]):
|
|
17
32
|
"""Neuron path.
|
|
18
33
|
|
|
19
|
-
A path is a linear set of points without
|
|
34
|
+
A path is a linear set of points without furcations.
|
|
20
35
|
"""
|
|
21
36
|
|
|
22
37
|
attach: SWCTypeVar
|
|
@@ -75,6 +90,7 @@ class Path(SWCLike, Generic[SWCTypeVar]):
|
|
|
75
90
|
def get_ndata(self, key: str) -> npt.NDArray:
|
|
76
91
|
return self.attach.get_ndata(key)[self.idx]
|
|
77
92
|
|
|
93
|
+
@deprecated("Use `path.node` instead.")
|
|
78
94
|
def get_node(self, idx: int | np.integer) -> Node:
|
|
79
95
|
"""Get the count of intersection.
|
|
80
96
|
|
|
@@ -82,11 +98,6 @@ class Path(SWCLike, Generic[SWCTypeVar]):
|
|
|
82
98
|
Use :meth:`path.node` instead.
|
|
83
99
|
"""
|
|
84
100
|
|
|
85
|
-
warnings.warn(
|
|
86
|
-
"`Path.get_node` has been deprecated since v0.16.0 and "
|
|
87
|
-
"will be removed in future version",
|
|
88
|
-
DeprecationWarning,
|
|
89
|
-
)
|
|
90
101
|
return self.node(idx)
|
|
91
102
|
|
|
92
103
|
def node(self, idx: int | np.integer) -> Node:
|