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.

Files changed (69) hide show
  1. swcgeom/__init__.py +14 -0
  2. swcgeom/_version.py +2 -2
  3. swcgeom/analysis/__init__.py +15 -0
  4. swcgeom/analysis/feature_extractor.py +27 -3
  5. swcgeom/analysis/features.py +31 -4
  6. swcgeom/analysis/lmeasure.py +43 -7
  7. swcgeom/analysis/sholl.py +21 -24
  8. swcgeom/analysis/trunk.py +15 -0
  9. swcgeom/analysis/visualization.py +15 -0
  10. swcgeom/analysis/visualization3d.py +15 -0
  11. swcgeom/analysis/volume.py +15 -0
  12. swcgeom/core/__init__.py +15 -0
  13. swcgeom/core/branch.py +15 -0
  14. swcgeom/core/branch_tree.py +15 -0
  15. swcgeom/core/compartment.py +15 -0
  16. swcgeom/core/node.py +30 -1
  17. swcgeom/core/path.py +18 -7
  18. swcgeom/core/population.py +43 -3
  19. swcgeom/core/swc.py +15 -0
  20. swcgeom/core/swc_utils/__init__.py +15 -1
  21. swcgeom/core/swc_utils/assembler.py +15 -0
  22. swcgeom/core/swc_utils/base.py +15 -0
  23. swcgeom/core/swc_utils/checker.py +19 -12
  24. swcgeom/core/swc_utils/io.py +17 -1
  25. swcgeom/core/swc_utils/normalizer.py +16 -1
  26. swcgeom/core/swc_utils/subtree.py +15 -0
  27. swcgeom/core/tree.py +37 -9
  28. swcgeom/core/tree_utils.py +17 -7
  29. swcgeom/core/tree_utils_impl.py +15 -0
  30. swcgeom/images/__init__.py +15 -0
  31. swcgeom/images/augmentation.py +15 -0
  32. swcgeom/images/contrast.py +15 -0
  33. swcgeom/images/folder.py +17 -10
  34. swcgeom/images/io.py +18 -6
  35. swcgeom/transforms/__init__.py +16 -0
  36. swcgeom/transforms/base.py +17 -2
  37. swcgeom/transforms/branch.py +74 -8
  38. swcgeom/transforms/branch_tree.py +82 -0
  39. swcgeom/transforms/geometry.py +22 -7
  40. swcgeom/transforms/image_preprocess.py +15 -0
  41. swcgeom/transforms/image_stack.py +30 -4
  42. swcgeom/transforms/images.py +17 -10
  43. swcgeom/transforms/mst.py +15 -0
  44. swcgeom/transforms/neurolucida_asc.py +16 -1
  45. swcgeom/transforms/path.py +15 -0
  46. swcgeom/transforms/population.py +15 -0
  47. swcgeom/transforms/tree.py +76 -23
  48. swcgeom/transforms/tree_assembler.py +19 -4
  49. swcgeom/utils/__init__.py +15 -0
  50. swcgeom/utils/debug.py +15 -0
  51. swcgeom/utils/download.py +59 -21
  52. swcgeom/utils/dsu.py +15 -0
  53. swcgeom/utils/ellipse.py +15 -0
  54. swcgeom/utils/file.py +15 -0
  55. swcgeom/utils/neuromorpho.py +18 -7
  56. swcgeom/utils/numpy_helper.py +15 -0
  57. swcgeom/utils/plotter_2d.py +15 -0
  58. swcgeom/utils/plotter_3d.py +18 -1
  59. swcgeom/utils/renderer.py +15 -0
  60. swcgeom/utils/sdf.py +17 -5
  61. swcgeom/utils/solid_geometry.py +15 -0
  62. swcgeom/utils/transforms.py +16 -1
  63. swcgeom/utils/volumetric_object.py +15 -0
  64. {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/LICENSE +1 -1
  65. {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/METADATA +26 -22
  66. swcgeom-0.18.1.dist-info/RECORD +68 -0
  67. {swcgeom-0.17.1.dist-info → swcgeom-0.18.1.dist-info}/WHEEL +1 -1
  68. swcgeom-0.17.1.dist-info/RECORD +0 -67
  69. {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
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.17.1'
16
- __version_tuple__ = version_tuple = (0, 17, 1)
15
+ __version__ = version = '0.18.1'
16
+ __version_tuple__ = version_tuple = (0, 18, 1)
@@ -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", "bifurcation_count", "tip_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 bifurcation_features(self) -> BifurcationFeatures: return BifurcationFeatures(self.node_features)
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."""
@@ -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 BifurcationFeatures(_SubsetNodesFeatures):
125
- """Evaluate bifurcation node feature of tree."""
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.is_bifurcation() for n in self._features.tree])
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):
@@ -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.get_bifurcations())
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
- """Bifuraction angle.
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
- """Bifuraction angle.
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._bif_vector_local(bif)
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.is_bifurcation():
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
@@ -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
@@ -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
@@ -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 is_bifurcation(self) -> bool:
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 bifurcations.
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: