swcgeom 0.14.0__py3-none-any.whl → 0.16.0__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 (45) hide show
  1. swcgeom/_version.py +2 -2
  2. swcgeom/analysis/lmeasure.py +821 -0
  3. swcgeom/analysis/sholl.py +31 -2
  4. swcgeom/core/__init__.py +4 -0
  5. swcgeom/core/branch.py +9 -4
  6. swcgeom/core/branch_tree.py +2 -3
  7. swcgeom/core/{segment.py → compartment.py} +14 -9
  8. swcgeom/core/node.py +0 -8
  9. swcgeom/core/path.py +21 -6
  10. swcgeom/core/population.py +42 -3
  11. swcgeom/core/swc_utils/assembler.py +20 -138
  12. swcgeom/core/swc_utils/base.py +12 -5
  13. swcgeom/core/swc_utils/checker.py +12 -2
  14. swcgeom/core/swc_utils/subtree.py +2 -2
  15. swcgeom/core/tree.py +53 -49
  16. swcgeom/core/tree_utils.py +27 -5
  17. swcgeom/core/tree_utils_impl.py +22 -6
  18. swcgeom/images/augmentation.py +6 -1
  19. swcgeom/images/contrast.py +107 -0
  20. swcgeom/images/folder.py +111 -29
  21. swcgeom/images/io.py +79 -40
  22. swcgeom/transforms/__init__.py +2 -0
  23. swcgeom/transforms/base.py +41 -21
  24. swcgeom/transforms/branch.py +5 -5
  25. swcgeom/transforms/geometry.py +42 -18
  26. swcgeom/transforms/image_preprocess.py +100 -0
  27. swcgeom/transforms/image_stack.py +46 -28
  28. swcgeom/transforms/images.py +76 -6
  29. swcgeom/transforms/mst.py +10 -18
  30. swcgeom/transforms/neurolucida_asc.py +495 -0
  31. swcgeom/transforms/population.py +2 -2
  32. swcgeom/transforms/tree.py +12 -14
  33. swcgeom/transforms/tree_assembler.py +85 -19
  34. swcgeom/utils/__init__.py +1 -0
  35. swcgeom/utils/neuromorpho.py +425 -300
  36. swcgeom/utils/numpy_helper.py +14 -4
  37. swcgeom/utils/plotter_2d.py +130 -0
  38. swcgeom/utils/renderer.py +28 -139
  39. swcgeom/utils/sdf.py +5 -1
  40. {swcgeom-0.14.0.dist-info → swcgeom-0.16.0.dist-info}/METADATA +3 -3
  41. swcgeom-0.16.0.dist-info/RECORD +67 -0
  42. {swcgeom-0.14.0.dist-info → swcgeom-0.16.0.dist-info}/WHEEL +1 -1
  43. swcgeom-0.14.0.dist-info/RECORD +0 -62
  44. {swcgeom-0.14.0.dist-info → swcgeom-0.16.0.dist-info}/LICENSE +0 -0
  45. {swcgeom-0.14.0.dist-info → swcgeom-0.16.0.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ __all__ = ["padding1d", "numpy_err"]
11
11
 
12
12
  def padding1d(
13
13
  n: int,
14
- v: npt.NDArray | None,
14
+ v: npt.ArrayLike | None,
15
15
  padding_value: Any = 0,
16
16
  dtype: npt.DTypeLike | None = None,
17
17
  ) -> npt.NDArray:
@@ -31,9 +31,19 @@ def padding1d(
31
31
  x will used, otherwise defaults to `~numpy.float32`.
32
32
  """
33
33
 
34
- dtype = dtype or (v is not None and v.dtype) or np.float32
35
- v = np.zeros(n, dtype=dtype) if v is None else v
36
- v = v.astype(dtype) if v.dtype != dtype else v
34
+ if not isinstance(v, np.ndarray):
35
+ dtype = dtype or np.float32
36
+ if v is not None:
37
+ v = np.array(v, dtype=dtype)
38
+ else:
39
+ v = np.zeros(n, dtype=dtype)
40
+
41
+ if dtype is None:
42
+ dtype = v.dtype
43
+
44
+ if v.dtype != dtype:
45
+ v = v.astype(dtype)
46
+
37
47
  assert v.ndim == 1
38
48
 
39
49
  if v.shape[0] >= n:
@@ -0,0 +1,130 @@
1
+ """Rendering related utils."""
2
+
3
+ from typing import Optional, Tuple
4
+
5
+ import matplotlib.pyplot as plt
6
+ import numpy as np
7
+ import numpy.typing as npt
8
+ from matplotlib import cm
9
+ from matplotlib.axes import Axes
10
+ from matplotlib.collections import LineCollection, PatchCollection
11
+ from matplotlib.colors import Colormap, Normalize
12
+ from matplotlib.figure import Figure
13
+ from matplotlib.patches import Circle
14
+
15
+ from swcgeom.utils.renderer import Camera
16
+ from swcgeom.utils.transforms import to_homogeneous, translate3d
17
+
18
+ __all__ = ["draw_lines", "draw_direction_indicator", "draw_circles", "get_fig_ax"]
19
+
20
+
21
+ def draw_lines(
22
+ ax: Axes, lines: npt.NDArray[np.floating], camera: Camera, **kwargs
23
+ ) -> LineCollection:
24
+ """Draw lines.
25
+
26
+ Parameters
27
+ ----------
28
+ ax : ~matplotlib.axes.Axes
29
+ lines : A collection of coords of lines
30
+ Excepting a ndarray of shape (N, 2, 3), the axis-2 holds two points,
31
+ and the axis-3 holds the coordinates (x, y, z).
32
+ camera : Camera
33
+ Camera position.
34
+ **kwargs : dict[str, Unknown]
35
+ Forwarded to `~matplotlib.collections.LineCollection`.
36
+ """
37
+
38
+ T = camera.MVP
39
+ T = translate3d(*camera.position).dot(T) # keep origin
40
+
41
+ starts, ends = lines[:, 0], lines[:, 1]
42
+ starts, ends = to_homogeneous(starts, 1), to_homogeneous(ends, 1)
43
+ starts, ends = np.dot(T, starts.T).T[:, 0:2], np.dot(T, ends.T).T[:, 0:2]
44
+
45
+ edges = np.stack([starts, ends], axis=1)
46
+ return ax.add_collection(LineCollection(edges, **kwargs)) # type: ignore
47
+
48
+
49
+ def draw_direction_indicator(
50
+ ax: Axes, camera: Camera, loc: Tuple[float, float]
51
+ ) -> None:
52
+ x, y = loc
53
+ direction = camera.MV.dot(
54
+ [
55
+ [1, 0, 0, 1],
56
+ [0, 1, 0, 1],
57
+ [0, 0, 1, 1],
58
+ [0, 0, 0, 1],
59
+ ]
60
+ )
61
+
62
+ arrow_length, text_offset = 0.05, 0.05 # TODO: may still overlap
63
+ text_colors = [["x", "red"], ["y", "green"], ["z", "blue"]]
64
+ for (dx, dy, dz, _), (text, color) in zip(direction, text_colors):
65
+ if 1 - abs(dz) < 1e-5:
66
+ continue
67
+
68
+ ax.arrow(
69
+ x,
70
+ y,
71
+ arrow_length * dx,
72
+ arrow_length * dy,
73
+ head_length=0.02,
74
+ head_width=0.01,
75
+ color=color,
76
+ transform=ax.transAxes,
77
+ )
78
+
79
+ ax.text(
80
+ x + (arrow_length + text_offset) * dx,
81
+ y + (arrow_length + text_offset) * dy,
82
+ text,
83
+ color=color,
84
+ transform=ax.transAxes,
85
+ horizontalalignment="center",
86
+ verticalalignment="center",
87
+ )
88
+
89
+
90
+ def draw_circles(
91
+ ax: Axes,
92
+ x: npt.NDArray,
93
+ y: npt.NDArray,
94
+ *,
95
+ y_min: Optional[float] = None,
96
+ y_max: Optional[float] = None,
97
+ cmap: str | Colormap = "viridis",
98
+ ) -> PatchCollection:
99
+ """Draw a sequential of circles."""
100
+
101
+ y_min = y.min() if y_min is None else y_min
102
+ y_max = y.max() if y_max is None else y_max
103
+ norm = Normalize(y_min, y_max)
104
+
105
+ color_map = cmap if isinstance(cmap, Colormap) else cm.get_cmap(name=cmap)
106
+ colors = color_map(norm(y))
107
+
108
+ circles = [
109
+ Circle((0, 0), xi, color=color) for xi, color in reversed(list(zip(x, colors)))
110
+ ]
111
+ patches = PatchCollection(circles, match_original=True)
112
+ patches.set_cmap(color_map)
113
+ patches.set_norm(norm)
114
+ patches: PatchCollection = ax.add_collection(patches) # type: ignore
115
+
116
+ ax.set_aspect(1)
117
+ ax.autoscale()
118
+ return patches
119
+
120
+
121
+ def get_fig_ax(
122
+ fig: Optional[Figure] = None, ax: Optional[Axes] = None
123
+ ) -> Tuple[Figure, Axes]:
124
+ if fig is None and ax is not None:
125
+ fig = ax.get_figure()
126
+ assert fig is not None, "expecting a figure from the axes"
127
+
128
+ fig = fig or plt.gcf()
129
+ ax = ax or plt.gca()
130
+ return fig, ax
swcgeom/utils/renderer.py CHANGED
@@ -1,36 +1,19 @@
1
1
  """Rendering related utils."""
2
2
 
3
3
  from functools import cached_property
4
- from typing import Dict, Literal, Optional, Tuple, cast
4
+ from typing import Dict, Literal, Tuple, cast
5
5
 
6
- import matplotlib.pyplot as plt
7
6
  import numpy as np
8
7
  import numpy.typing as npt
9
- from matplotlib import cm
10
- from matplotlib.axes import Axes
11
- from matplotlib.collections import LineCollection, PatchCollection
12
- from matplotlib.colors import Colormap, Normalize
13
- from matplotlib.figure import Figure
14
- from matplotlib.patches import Circle
15
8
  from typing_extensions import Self
16
9
 
17
10
  from swcgeom.utils.transforms import (
18
11
  Vec3f,
19
12
  model_view_transformation,
20
13
  orthographic_projection_simple,
21
- to_homogeneous,
22
- translate3d,
23
14
  )
24
15
 
25
- __all__ = [
26
- "CameraOptions",
27
- "SimpleCamera",
28
- "palette",
29
- "draw_lines",
30
- "draw_direction_indicator",
31
- "draw_circles",
32
- "get_fig_ax",
33
- ]
16
+ __all__ = ["CameraOptions", "Camera", "SimpleCamera", "palette"]
34
17
 
35
18
  CameraOption = Vec3f | Tuple[Vec3f, Vec3f] | Tuple[Vec3f, Vec3f, Vec3f]
36
19
  CameraPreset = Literal["xy", "yz", "zx", "yx", "zy", "xz"]
@@ -45,13 +28,35 @@ CameraPresets: Dict[CameraPreset, Tuple[Vec3f, Vec3f, Vec3f]] = {
45
28
  CameraOptions = CameraOption | CameraPreset
46
29
 
47
30
 
48
- class SimpleCamera:
31
+ class Camera:
32
+ _position: Vec3f
33
+ _look_at: Vec3f
34
+ _up: Vec3f
35
+
36
+ # fmt: off
37
+ @property
38
+ def position(self) -> Vec3f: return self._position
39
+ @property
40
+ def look_at(self) -> Vec3f: return self._look_at
41
+ @property
42
+ def up(self) -> Vec3f: return self._up
43
+
44
+ @property
45
+ def MV(self) -> npt.NDArray[np.float32]: raise NotImplementedError()
46
+ @property
47
+ def P(self) -> npt.NDArray[np.float32]: raise NotImplementedError()
48
+ @property
49
+ def MVP(self) -> npt.NDArray[np.float32]: return self.P.dot(self.MV)
50
+ # fmt: on
51
+
52
+
53
+ class SimpleCamera(Camera):
49
54
  """Simplest camera."""
50
55
 
51
56
  def __init__(self, position: Vec3f, look_at: Vec3f, up: Vec3f):
52
- self.position = position
53
- self.look_at = look_at
54
- self.up = up
57
+ self._position = position
58
+ self._look_at = look_at
59
+ self._up = up
55
60
 
56
61
  @cached_property
57
62
  def MV(self) -> npt.NDArray[np.float32]: # pylint: disable=invalid-name
@@ -61,10 +66,6 @@ class SimpleCamera:
61
66
  def P(self) -> npt.NDArray[np.float32]: # pylint: disable=invalid-name
62
67
  return orthographic_projection_simple()
63
68
 
64
- @cached_property
65
- def MVP(self) -> npt.NDArray[np.float32]: # pylint: disable=invalid-name
66
- return self.P.dot(self.MV)
67
-
68
69
  @classmethod
69
70
  def from_options(cls, camera: CameraOptions) -> Self:
70
71
  if isinstance(camera, str):
@@ -130,115 +131,3 @@ class Palette:
130
131
 
131
132
 
132
133
  palette = Palette()
133
-
134
-
135
- def draw_lines(
136
- ax: Axes, lines: npt.NDArray[np.floating], camera: SimpleCamera, **kwargs
137
- ) -> LineCollection:
138
- """Draw lines.
139
-
140
- Parameters
141
- ----------
142
- ax : ~matplotlib.axes.Axes
143
- lines : A collection of coords of lines
144
- Excepting a ndarray of shape (N, 2, 3), the axis-2 holds two points,
145
- and the axis-3 holds the coordinates (x, y, z).
146
- camera : Camera
147
- Camera position.
148
- **kwargs : dict[str, Unknown]
149
- Forwarded to `~matplotlib.collections.LineCollection`.
150
- """
151
-
152
- T = camera.MVP
153
- T = translate3d(*camera.position).dot(T) # keep origin
154
-
155
- starts, ends = lines[:, 0], lines[:, 1]
156
- starts, ends = to_homogeneous(starts, 1), to_homogeneous(ends, 1)
157
- starts, ends = np.dot(T, starts.T).T[:, 0:2], np.dot(T, ends.T).T[:, 0:2]
158
-
159
- edges = np.stack([starts, ends], axis=1)
160
- return ax.add_collection(LineCollection(edges, **kwargs)) # type: ignore
161
-
162
-
163
- def draw_direction_indicator(
164
- ax: Axes, camera: SimpleCamera, loc: Tuple[float, float]
165
- ) -> None:
166
- x, y = loc
167
- direction = camera.MV.dot(
168
- [
169
- [1, 0, 0, 1],
170
- [0, 1, 0, 1],
171
- [0, 0, 1, 1],
172
- [0, 0, 0, 1],
173
- ]
174
- )
175
-
176
- arrow_length, text_offset = 0.05, 0.05 # TODO: may still overlap
177
- text_colors = [["x", "red"], ["y", "green"], ["z", "blue"]]
178
- for (dx, dy, dz, _), (text, color) in zip(direction, text_colors):
179
- if 1 - abs(dz) < 1e-5:
180
- continue
181
-
182
- ax.arrow(
183
- x,
184
- y,
185
- arrow_length * dx,
186
- arrow_length * dy,
187
- head_length=0.02,
188
- head_width=0.01,
189
- color=color,
190
- transform=ax.transAxes,
191
- )
192
-
193
- ax.text(
194
- x + (arrow_length + text_offset) * dx,
195
- y + (arrow_length + text_offset) * dy,
196
- text,
197
- color=color,
198
- transform=ax.transAxes,
199
- horizontalalignment="center",
200
- verticalalignment="center",
201
- )
202
-
203
-
204
- def draw_circles(
205
- ax: Axes,
206
- x: npt.NDArray,
207
- y: npt.NDArray,
208
- *,
209
- y_min: Optional[float] = None,
210
- y_max: Optional[float] = None,
211
- cmap: str | Colormap = "viridis",
212
- ) -> PatchCollection:
213
- """Draw a sequential of circles."""
214
-
215
- y_min = y.min() if y_min is None else y_min
216
- y_max = y.max() if y_max is None else y_max
217
- norm = Normalize(y_min, y_max)
218
-
219
- color_map = cmap if isinstance(cmap, Colormap) else cm.get_cmap(name=cmap)
220
- colors = color_map(norm(y))
221
-
222
- circles = [
223
- Circle((0, 0), xi, color=color) for xi, color in reversed(list(zip(x, colors)))
224
- ]
225
- patches = PatchCollection(circles, match_original=True)
226
- patches.set_cmap(color_map)
227
- patches.set_norm(norm)
228
- patches: PatchCollection = ax.add_collection(patches) # type: ignore
229
-
230
- ax.set_aspect(1)
231
- ax.autoscale()
232
- return patches
233
-
234
-
235
- def get_fig_ax(
236
- fig: Figure | None = None, ax: Axes | None = None
237
- ) -> Tuple[Figure, Axes]:
238
- if fig is None:
239
- fig = plt.gcf() if ax is None else ax.get_figure()
240
-
241
- if ax is None:
242
- ax = fig.gca()
243
-
244
- return fig, ax
swcgeom/utils/sdf.py CHANGED
@@ -174,7 +174,11 @@ class SDFDifference(SDF):
174
174
 
175
175
 
176
176
  class SDFCompose(SDFUnion):
177
- """Compose multiple SDFs."""
177
+ """Compose multiple SDFs.
178
+
179
+ .. deprecated:: 0.14.0
180
+ Use :cls:`SDFUnion` instead.
181
+ """
178
182
 
179
183
  def __init__(self, sdfs: Iterable[SDF]) -> None:
180
184
  warnings.warn(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: swcgeom
3
- Version: 0.14.0
3
+ Version: 0.16.0
4
4
  Summary: Neuron geometry library for swc format
5
5
  Author-email: yzx9 <yuan.zx@outlook.com>
6
6
  License: Apache-2.0
@@ -19,14 +19,14 @@ Requires-Dist: sdflit >=0.2.1
19
19
  Requires-Dist: seaborn >=0.12.0
20
20
  Requires-Dist: tifffile >=2022.8.12
21
21
  Requires-Dist: typing-extensions >=4.4.0
22
+ Requires-Dist: tqdm >=4.46.1
22
23
  Requires-Dist: v3d-py-helper >=0.1.0
23
24
  Provides-Extra: all
24
25
  Requires-Dist: beautifulsoup4 >=4.11.1 ; extra == 'all'
25
26
  Requires-Dist: certifi >=2023.5.7 ; extra == 'all'
26
27
  Requires-Dist: chardet >=5.2.0 ; extra == 'all'
27
28
  Requires-Dist: lmdb >=1.4.1 ; extra == 'all'
28
- Requires-Dist: pycurl >=7.0.0 ; extra == 'all'
29
- Requires-Dist: tqdm >=4.46.1 ; extra == 'all'
29
+ Requires-Dist: requests >=2.0.0 ; extra == 'all'
30
30
  Requires-Dist: urllib3 >=1.26.0 ; extra == 'all'
31
31
 
32
32
  # SWCGEOM
@@ -0,0 +1,67 @@
1
+ swcgeom/__init__.py,sha256=z88Zwcjv-ii7c7dYd9QPg9XrUVorQjtrgGbQCsEnQhc,265
2
+ swcgeom/_version.py,sha256=6rRRmvuDj83YMwAXEQTx-SPTN2ocQjA6cw2_dMCfweM,413
3
+ swcgeom/analysis/__init__.py,sha256=esL_poW8u-_bmp7vR9ldcumX3_xodtaVfM1USqxQo5w,377
4
+ swcgeom/analysis/branch_features.py,sha256=s6PTMwwvxrVtZXRZlQbUSIw4M9-1IG63kf-Nxc0tMB0,1958
5
+ swcgeom/analysis/feature_extractor.py,sha256=coe07_bJau96BkimcnXzuf4KqjY5_QRLwqaumFsu_tQ,14031
6
+ swcgeom/analysis/lmeasure.py,sha256=GI5HoIXkRp_GEDHd_JXJOMeAtZ26HP6lbSfF_0L-2r8,27559
7
+ swcgeom/analysis/node_features.py,sha256=fevnyrF-t4PX39ifLypiDW6EUWB8i-a3PpBnQZU3VOc,3407
8
+ swcgeom/analysis/path_features.py,sha256=iE21HBxAoGLxk_qK7MBwQhyUOBqNPcnk4urVHr9SVqk,889
9
+ swcgeom/analysis/sholl.py,sha256=KeUyEXLatHjmn4hOSs8y_0o8UKDq9VoIufJ_81SOtgw,7249
10
+ swcgeom/analysis/trunk.py,sha256=L2tjUIUmrRQpah_W3ZETGWd16bDXJ5F8Sk2XBNGms0Q,5558
11
+ swcgeom/analysis/visualization.py,sha256=mKOpzTPkLpr1ggGL1MZPZRTG92GEg4idLT4eN5z5KOs,5654
12
+ swcgeom/analysis/volume.py,sha256=nWPR7wGOk3Wl5eh97YMws0X-2jk8K7lmFp4-03wL3lY,4628
13
+ swcgeom/core/__init__.py,sha256=BEfFBnpaKnJOBID5G5kpGcL7_E1Fj0eZZDITDVwvmRY,445
14
+ swcgeom/core/branch.py,sha256=NchxRgXpFv_ImShvQBPU_9xNzufTrPMvEYmx7d46JNA,4162
15
+ swcgeom/core/branch_tree.py,sha256=Ece6q1VNCRLLMj29N_MjXmmlHT8h4tpWCuDE0uSgKJo,1873
16
+ swcgeom/core/compartment.py,sha256=-2EYkGfqN12he2dsrtO1afC52Bk_fMD5aRLO_useGCQ,3248
17
+ swcgeom/core/node.py,sha256=Kwqoh_WMBLIt2WNDwF-7EwS-C8lONG5krGPmmdHwhvY,3329
18
+ swcgeom/core/path.py,sha256=mxexT7eEHpRaCapE4t0dzfQGgW_zPPzn6N1MkD-jLgI,4579
19
+ swcgeom/core/population.py,sha256=MVVAgGki9SQYMuEJpWyG0eBX4ImR2wpfvWxMqAnXRa8,9824
20
+ swcgeom/core/swc.py,sha256=lSYxAa25l6O8WZ9JtSSET-RZMr6EA1Tq_aXL_x0H9Rc,6795
21
+ swcgeom/core/tree.py,sha256=fQM_Z5-bWsh55hS1pde52tSjKE9-aZY75wbKmDOOQcQ,12195
22
+ swcgeom/core/tree_utils.py,sha256=WWh7uizkyG0u7Zs6ZmkSLPYBsU4XC-gqPeOiVGyaqGE,7749
23
+ swcgeom/core/tree_utils_impl.py,sha256=kN2ByjqqQtZUfmC_ac25tXOaE-CMiV2lP58VxFphLEU,1616
24
+ swcgeom/core/swc_utils/__init__.py,sha256=qghRxjtzvq5KKfN4HhvLpZNsGPfZQu-Jj2x62_5-TbQ,575
25
+ swcgeom/core/swc_utils/assembler.py,sha256=XtjEWz_iAOMpQzLnErCiCjbnqrbB7JA4t2-LLi2R4rQ,889
26
+ swcgeom/core/swc_utils/base.py,sha256=6jNf1EeMz7yJQr3rYSi5EuU2ZPjeefB9vIRFaY53PbA,4788
27
+ swcgeom/core/swc_utils/checker.py,sha256=yuLPRoSt9c7No4GGePa05kxjGFCs0zYS7oB1HadNeMI,2852
28
+ swcgeom/core/swc_utils/io.py,sha256=6_--Qoe8kDja4PWsjwqRAvPJZNMFILFgauHaeWeGikU,6444
29
+ swcgeom/core/swc_utils/normalizer.py,sha256=_Ysi8bSJ2JBnIGB8o6BvAg2mcz6xuJp9rgNLZqpLuR8,5083
30
+ swcgeom/core/swc_utils/subtree.py,sha256=43QITYvgXu3b_kfIod2Irrj3dSfrA-gTFev5VxzRafI,1995
31
+ swcgeom/images/__init__.py,sha256=QBP1ZGGo2nWAcV7Krz-vbvW_jN4ChqXrrpoScXcUURs,96
32
+ swcgeom/images/augmentation.py,sha256=cV4k4KR_WcsRajyr0DuhHVDRRZcN4FQ7OIzB_rb2FUo,4173
33
+ swcgeom/images/contrast.py,sha256=ViZVW6XI-l2sLVTODLRLtHinv_7lVgtH-xZmaw1nQLw,2160
34
+ swcgeom/images/folder.py,sha256=YY9YjF17nDwOQEXhzFe-Dj0zPTcG0WP1-gisscImmYg,6674
35
+ swcgeom/images/io.py,sha256=s7YgzlVbl1fTI0PvW09p4_Z-hDdU9Ofh8d99nyhMyY4,21445
36
+ swcgeom/transforms/__init__.py,sha256=1rr4X--qY_lBi7l7_NHyvvkoWpQOQOqkioRT8I20olI,562
37
+ swcgeom/transforms/base.py,sha256=gN5Iqi-OHkYrsjllSOdxI6Yzav3jJGoi6kUPy-38FAs,4101
38
+ swcgeom/transforms/branch.py,sha256=R0rVti--u70IiUKyHSx6MsDYJyy6zSCf18Uia2Cmh28,5410
39
+ swcgeom/transforms/geometry.py,sha256=XR73fO_8T7otUFIllqKOWW0OnrsXBc7yA01oDT99yMc,7385
40
+ swcgeom/transforms/image_preprocess.py,sha256=ZVPpRoO69dmLF5K7CWsGaQJXB2G5gxdvA-FcDmfz4yQ,3662
41
+ swcgeom/transforms/image_stack.py,sha256=RIldGAOI3QeoeBtr0VKeBKJVg-fWSmzWll63SvsaTfI,5775
42
+ swcgeom/transforms/images.py,sha256=ia6h8L7rIubNb02YlbOa-CTScttQJmiS5dHT4D2HpWg,2679
43
+ swcgeom/transforms/mst.py,sha256=Oc_HnaXjg5EXC7ZnOPneHX0-rXizDAEUcjq63GTj-ac,6251
44
+ swcgeom/transforms/neurolucida_asc.py,sha256=O4fK1OMropPnIEVdMenbyT_sV39gEGIv_6vIl6yUOVg,14146
45
+ swcgeom/transforms/path.py,sha256=Gk2iunGQMX7vE83bdo8xoDO-KAT1Vvep0iZs7oFLzFQ,1089
46
+ swcgeom/transforms/population.py,sha256=EmZ6ntuOKe8mXJxMW7nCUA-w2DVlEVe2n0IOVz49tCY,833
47
+ swcgeom/transforms/tree.py,sha256=YzLvKUwTOj92286jHah0CtRYQIxHiNiMGKcgsc_dB0E,6333
48
+ swcgeom/transforms/tree_assembler.py,sha256=vi_X9CNo5IxHP5J7bRl2z91PWufU6HmYlz1iyfdPUxE,5121
49
+ swcgeom/utils/__init__.py,sha256=LXL0wqq6-ggNweZrftp2lrNHCmVJ6LHIto3DuwlYz3c,466
50
+ swcgeom/utils/debug.py,sha256=qay2qJpViLX82mzxdndxQFn-pi1vaEj9CbLGuGt8Y9k,465
51
+ swcgeom/utils/download.py,sha256=By2qZezo6h1Ke_4YpSIhDgcisOrpjVqRmNzbhynC2xs,2834
52
+ swcgeom/utils/dsu.py,sha256=3aCbtpnl_D0OXnowTS8-kuwnCS4BKBYL5ECiFQ1fUW8,1435
53
+ swcgeom/utils/ellipse.py,sha256=LB3q5CIy75GEUdTauIpKySwIHaDrwXzzkBhOCnjJ8Vw,3259
54
+ swcgeom/utils/file.py,sha256=1hchQDsPgn-i-Vz5OQtcogxav_ajCQ_OaEZCLmqczRg,2515
55
+ swcgeom/utils/neuromorpho.py,sha256=xfQ5npDsI_3UHMFbzrBNU453ZG6C6Y271NvU6cExfuc,19107
56
+ swcgeom/utils/numpy_helper.py,sha256=xuvXpZgP-ZeuwTvPFD3DIxwJ5BK4fMCU7k5_5fUHaWE,1425
57
+ swcgeom/utils/plotter_2d.py,sha256=R34_cLfcx_ycPuXS4D0n6ERse7mmzcnhMlkz8KU4yk4,3740
58
+ swcgeom/utils/renderer.py,sha256=yGEu2SBvUQCVwsU8MT273HHgQ9uk5R0Pmo_bJaTN5yU,4233
59
+ swcgeom/utils/sdf.py,sha256=zNDgwXKRNIVcV4ORMmDXup6Bhf_vlHqwa-b3WZn6KhE,10684
60
+ swcgeom/utils/solid_geometry.py,sha256=TV02jhcoCLCqtYA9hfE50LFD_VRfixMiOSiHB5Jb2_U,2431
61
+ swcgeom/utils/transforms.py,sha256=PmP5fL_iVguq4GR2aqXhM0TeCsiFVnrPZMZG6zLohrE,6983
62
+ swcgeom/utils/volumetric_object.py,sha256=DVRGGmQrAL0oaW6hbNtp5TStbic9DfyJdCzsv2FNw2c,15134
63
+ swcgeom-0.16.0.dist-info/LICENSE,sha256=JPtohhZ4XURqoKI0ZqnMYb7dobCOoZR_n5EpnaLTp3E,11344
64
+ swcgeom-0.16.0.dist-info/METADATA,sha256=cSs43xlPOCFXa9GcEGPGUE0tjDo6vDtskZ8IvlZAcuA,2332
65
+ swcgeom-0.16.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
66
+ swcgeom-0.16.0.dist-info/top_level.txt,sha256=hmLyUXWS61Gxl07haswFEKKefYPBVJYlUlol8ghNkjY,8
67
+ swcgeom-0.16.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,62 +0,0 @@
1
- swcgeom/__init__.py,sha256=z88Zwcjv-ii7c7dYd9QPg9XrUVorQjtrgGbQCsEnQhc,265
2
- swcgeom/_version.py,sha256=9XbM6DRatFmjNkeSNxF4a6enpQeo8nPyAy9RTPPwPpY,413
3
- swcgeom/analysis/__init__.py,sha256=esL_poW8u-_bmp7vR9ldcumX3_xodtaVfM1USqxQo5w,377
4
- swcgeom/analysis/branch_features.py,sha256=s6PTMwwvxrVtZXRZlQbUSIw4M9-1IG63kf-Nxc0tMB0,1958
5
- swcgeom/analysis/feature_extractor.py,sha256=coe07_bJau96BkimcnXzuf4KqjY5_QRLwqaumFsu_tQ,14031
6
- swcgeom/analysis/node_features.py,sha256=fevnyrF-t4PX39ifLypiDW6EUWB8i-a3PpBnQZU3VOc,3407
7
- swcgeom/analysis/path_features.py,sha256=iE21HBxAoGLxk_qK7MBwQhyUOBqNPcnk4urVHr9SVqk,889
8
- swcgeom/analysis/sholl.py,sha256=9hSW8rZm1gvSIgcEZg8IVPT8kzBgBfwqbwP4E8R7L44,6390
9
- swcgeom/analysis/trunk.py,sha256=L2tjUIUmrRQpah_W3ZETGWd16bDXJ5F8Sk2XBNGms0Q,5558
10
- swcgeom/analysis/visualization.py,sha256=mKOpzTPkLpr1ggGL1MZPZRTG92GEg4idLT4eN5z5KOs,5654
11
- swcgeom/analysis/volume.py,sha256=nWPR7wGOk3Wl5eh97YMws0X-2jk8K7lmFp4-03wL3lY,4628
12
- swcgeom/core/__init__.py,sha256=ZUudZavxAIUU6Q0lBHrQ4ybmL5lBfvzyYsTtpuih9wg,332
13
- swcgeom/core/branch.py,sha256=uuJCxaByRu-OdDZVWEffSFcmZWY-6ZWUhHN1M2Awj1s,3980
14
- swcgeom/core/branch_tree.py,sha256=sN0viBVg5A4r9dMCkGNAaVttrdR4bEoZZBbHZFKdXj4,1892
15
- swcgeom/core/node.py,sha256=HvfgsW4WU01hkRIPci8KF4bQMAkwtAxOGfUL4yUbuBs,3623
16
- swcgeom/core/path.py,sha256=CsEelHiDR0JPBP1dTvoCSRvX3kBlZxkQilosnncV4nQ,4188
17
- swcgeom/core/population.py,sha256=YZLAtkZKJeErOsE5MwhqieGjoMa7sWjFl5xxmXVPTco,8786
18
- swcgeom/core/segment.py,sha256=yabRdFj7KlkJP4V67jAlCIRzpHduNnq3bRBIRMuANfA,3158
19
- swcgeom/core/swc.py,sha256=lSYxAa25l6O8WZ9JtSSET-RZMr6EA1Tq_aXL_x0H9Rc,6795
20
- swcgeom/core/tree.py,sha256=oAx31r2jFzxSW7vnM17m8sMVVI3_xzxRyDQh19MPTlQ,12126
21
- swcgeom/core/tree_utils.py,sha256=xPy9b3MO43QR7VSvJvrwioXyQLGAPLotQjekn_-UiLg,7308
22
- swcgeom/core/tree_utils_impl.py,sha256=5Cb63ziVVLADnkjfuq1T-ePw2TQQ5TKk4gcPZR6f_wY,1123
23
- swcgeom/core/swc_utils/__init__.py,sha256=qghRxjtzvq5KKfN4HhvLpZNsGPfZQu-Jj2x62_5-TbQ,575
24
- swcgeom/core/swc_utils/assembler.py,sha256=RoMJ3RjLC4O7mk62QxXVTQ5SUHagrFmpEw3nOnnqeJo,4563
25
- swcgeom/core/swc_utils/base.py,sha256=huVxjuMLlTHbEb-KSEFDLgU0Ss3723t2Gr4Z_gQtl00,4737
26
- swcgeom/core/swc_utils/checker.py,sha256=E72GtLZ_1IqQQ7aWQGs0dZ3Z609__bw3EYQqeWrk-EI,2657
27
- swcgeom/core/swc_utils/io.py,sha256=6_--Qoe8kDja4PWsjwqRAvPJZNMFILFgauHaeWeGikU,6444
28
- swcgeom/core/swc_utils/normalizer.py,sha256=_Ysi8bSJ2JBnIGB8o6BvAg2mcz6xuJp9rgNLZqpLuR8,5083
29
- swcgeom/core/swc_utils/subtree.py,sha256=bd4XOLmRDfQSn_ktfQM3Hn8ONpCuZ_TdTWhE9-7QXW4,1999
30
- swcgeom/images/__init__.py,sha256=QBP1ZGGo2nWAcV7Krz-vbvW_jN4ChqXrrpoScXcUURs,96
31
- swcgeom/images/augmentation.py,sha256=v9zluYXmBEbafaDBTpvJovi4_KWJmHZZSvcYHzG0oWo,4099
32
- swcgeom/images/folder.py,sha256=urh60ITreGgEwSbCbgexJFM8_-C9WLAQ9jUN50sox10,4034
33
- swcgeom/images/io.py,sha256=VZWBq-_TMrKKdMaqpbZWZP6fCGIxWdhdIfb0ePcDy-4,20272
34
- swcgeom/transforms/__init__.py,sha256=Mi2mOgkQ50JbZ9LmgXgJIuAA5eio67oe2AOs2CCCxTQ,463
35
- swcgeom/transforms/base.py,sha256=22kkpQ11YCrH1SWWMHVqYjHp6cAlhslhdi1wKgAnT_s,3416
36
- swcgeom/transforms/branch.py,sha256=mdrTC9T4zENS9DdwlFaoFHcWDuFAgKgiNicJZ1gLsOc,5445
37
- swcgeom/transforms/geometry.py,sha256=zPmEf6ApJKzeZBbZ7qJYZXpY3-mrABN2dr7AUNqENiQ,6619
38
- swcgeom/transforms/image_stack.py,sha256=uJfRhXz86NQUxA3MguCoHpq4WBUAUjgZjMH1n-Wqoiw,5297
39
- swcgeom/transforms/images.py,sha256=tUl3dtqWfrhWR7WrOUc6LzWHnOzz3fwEgV3mMLRhn0c,908
40
- swcgeom/transforms/mst.py,sha256=B6ZRqeEfCHLHFu0tdOsOgplbYHra4VPYjnneXMU-cNY,6413
41
- swcgeom/transforms/path.py,sha256=Gk2iunGQMX7vE83bdo8xoDO-KAT1Vvep0iZs7oFLzFQ,1089
42
- swcgeom/transforms/population.py,sha256=ZrKfMAMx4l729f-JLgw0dnGIPtPUoV0ZZoNNyA5cBw8,826
43
- swcgeom/transforms/tree.py,sha256=Q5OnSti0ZeTNb-WpA_UZsDN7dhLN8YweEF_Siyrj66c,6420
44
- swcgeom/transforms/tree_assembler.py,sha256=UZ9OUg1bQNecYIY_7ippg3S8gpuoi617ZUE0jg6BrQE,3177
45
- swcgeom/utils/__init__.py,sha256=QfezYuQzgmPziNiWz2T1h77V-gjpuBoUi3mC-K-PZlI,427
46
- swcgeom/utils/debug.py,sha256=qay2qJpViLX82mzxdndxQFn-pi1vaEj9CbLGuGt8Y9k,465
47
- swcgeom/utils/download.py,sha256=By2qZezo6h1Ke_4YpSIhDgcisOrpjVqRmNzbhynC2xs,2834
48
- swcgeom/utils/dsu.py,sha256=3aCbtpnl_D0OXnowTS8-kuwnCS4BKBYL5ECiFQ1fUW8,1435
49
- swcgeom/utils/ellipse.py,sha256=LB3q5CIy75GEUdTauIpKySwIHaDrwXzzkBhOCnjJ8Vw,3259
50
- swcgeom/utils/file.py,sha256=1hchQDsPgn-i-Vz5OQtcogxav_ajCQ_OaEZCLmqczRg,2515
51
- swcgeom/utils/neuromorpho.py,sha256=CDK2tUM2pNwHv_lEserHhQs_VlY3Rn557-jtV63EFlk,14420
52
- swcgeom/utils/numpy_helper.py,sha256=A-F-eFdGktCHVAQ_HcXiFB3Y1YhhSNfAmtOl8483Dvo,1292
53
- swcgeom/utils/renderer.py,sha256=xHVZ06Z1MeKBPC3nKzuwA1HryzR0ga79y6johZA4-q0,7290
54
- swcgeom/utils/sdf.py,sha256=K-LSnwwNsGF85GW1kNBaqXAAVesxZAEsrn0nvOA2LcA,10614
55
- swcgeom/utils/solid_geometry.py,sha256=TV02jhcoCLCqtYA9hfE50LFD_VRfixMiOSiHB5Jb2_U,2431
56
- swcgeom/utils/transforms.py,sha256=PmP5fL_iVguq4GR2aqXhM0TeCsiFVnrPZMZG6zLohrE,6983
57
- swcgeom/utils/volumetric_object.py,sha256=DVRGGmQrAL0oaW6hbNtp5TStbic9DfyJdCzsv2FNw2c,15134
58
- swcgeom-0.14.0.dist-info/LICENSE,sha256=JPtohhZ4XURqoKI0ZqnMYb7dobCOoZR_n5EpnaLTp3E,11344
59
- swcgeom-0.14.0.dist-info/METADATA,sha256=4DWijpWXVwo7_Cf8H-EH9DVDfQ31XoA9wEMhshow_kg,2347
60
- swcgeom-0.14.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
61
- swcgeom-0.14.0.dist-info/top_level.txt,sha256=hmLyUXWS61Gxl07haswFEKKefYPBVJYlUlol8ghNkjY,8
62
- swcgeom-0.14.0.dist-info/RECORD,,