swcgeom 0.15.0__py3-none-any.whl → 0.17.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.
- swcgeom/_version.py +2 -2
- swcgeom/analysis/__init__.py +1 -3
- swcgeom/analysis/feature_extractor.py +3 -3
- swcgeom/analysis/{node_features.py → features.py} +105 -3
- swcgeom/analysis/lmeasure.py +821 -0
- swcgeom/analysis/sholl.py +31 -2
- swcgeom/core/__init__.py +4 -0
- swcgeom/core/branch.py +9 -4
- swcgeom/core/{segment.py → compartment.py} +14 -9
- swcgeom/core/node.py +0 -8
- swcgeom/core/path.py +21 -6
- swcgeom/core/population.py +47 -7
- swcgeom/core/swc_utils/assembler.py +12 -1
- swcgeom/core/swc_utils/base.py +12 -5
- swcgeom/core/swc_utils/checker.py +12 -2
- swcgeom/core/tree.py +34 -37
- swcgeom/core/tree_utils.py +4 -0
- swcgeom/images/augmentation.py +6 -1
- swcgeom/images/contrast.py +107 -0
- swcgeom/images/folder.py +71 -14
- swcgeom/images/io.py +74 -88
- swcgeom/transforms/__init__.py +2 -0
- swcgeom/transforms/image_preprocess.py +100 -0
- swcgeom/transforms/image_stack.py +1 -4
- swcgeom/transforms/images.py +176 -5
- swcgeom/transforms/mst.py +5 -5
- swcgeom/transforms/neurolucida_asc.py +495 -0
- swcgeom/transforms/tree.py +5 -1
- swcgeom/utils/__init__.py +1 -0
- swcgeom/utils/neuromorpho.py +425 -300
- swcgeom/utils/numpy_helper.py +14 -4
- swcgeom/utils/plotter_2d.py +130 -0
- swcgeom/utils/renderer.py +28 -139
- swcgeom/utils/sdf.py +5 -1
- {swcgeom-0.15.0.dist-info → swcgeom-0.17.0.dist-info}/METADATA +3 -3
- swcgeom-0.17.0.dist-info/RECORD +65 -0
- {swcgeom-0.15.0.dist-info → swcgeom-0.17.0.dist-info}/WHEEL +1 -1
- swcgeom/analysis/branch_features.py +0 -67
- swcgeom/analysis/path_features.py +0 -37
- swcgeom-0.15.0.dist-info/RECORD +0 -62
- {swcgeom-0.15.0.dist-info → swcgeom-0.17.0.dist-info}/LICENSE +0 -0
- {swcgeom-0.15.0.dist-info → swcgeom-0.17.0.dist-info}/top_level.txt +0 -0
swcgeom/utils/numpy_helper.py
CHANGED
|
@@ -11,7 +11,7 @@ __all__ = ["padding1d", "numpy_err"]
|
|
|
11
11
|
|
|
12
12
|
def padding1d(
|
|
13
13
|
n: int,
|
|
14
|
-
v: npt.
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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,
|
|
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
|
|
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.
|
|
53
|
-
self.
|
|
54
|
-
self.
|
|
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.
|
|
3
|
+
Version: 0.17.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:
|
|
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,65 @@
|
|
|
1
|
+
swcgeom/__init__.py,sha256=z88Zwcjv-ii7c7dYd9QPg9XrUVorQjtrgGbQCsEnQhc,265
|
|
2
|
+
swcgeom/_version.py,sha256=kBQrirg2HABnJUda1U0a6ZmIqeCqRLaPZOws884sTW8,413
|
|
3
|
+
swcgeom/analysis/__init__.py,sha256=NurxIAyjsxjYv9rbzNf65y2sv-iBcGTmLap645hYq9Y,280
|
|
4
|
+
swcgeom/analysis/feature_extractor.py,sha256=MBhnE6JbgCMhfTO8jEXqbLkVIiQh2WvVH2C4JR0IcpI,13948
|
|
5
|
+
swcgeom/analysis/features.py,sha256=meUXUOIqV1PgiRtgYQdFrVuTmyPYQRSJ0C1Ll97XDhU,5965
|
|
6
|
+
swcgeom/analysis/lmeasure.py,sha256=GI5HoIXkRp_GEDHd_JXJOMeAtZ26HP6lbSfF_0L-2r8,27559
|
|
7
|
+
swcgeom/analysis/sholl.py,sha256=KeUyEXLatHjmn4hOSs8y_0o8UKDq9VoIufJ_81SOtgw,7249
|
|
8
|
+
swcgeom/analysis/trunk.py,sha256=L2tjUIUmrRQpah_W3ZETGWd16bDXJ5F8Sk2XBNGms0Q,5558
|
|
9
|
+
swcgeom/analysis/visualization.py,sha256=mKOpzTPkLpr1ggGL1MZPZRTG92GEg4idLT4eN5z5KOs,5654
|
|
10
|
+
swcgeom/analysis/volume.py,sha256=nWPR7wGOk3Wl5eh97YMws0X-2jk8K7lmFp4-03wL3lY,4628
|
|
11
|
+
swcgeom/core/__init__.py,sha256=BEfFBnpaKnJOBID5G5kpGcL7_E1Fj0eZZDITDVwvmRY,445
|
|
12
|
+
swcgeom/core/branch.py,sha256=NchxRgXpFv_ImShvQBPU_9xNzufTrPMvEYmx7d46JNA,4162
|
|
13
|
+
swcgeom/core/branch_tree.py,sha256=Ece6q1VNCRLLMj29N_MjXmmlHT8h4tpWCuDE0uSgKJo,1873
|
|
14
|
+
swcgeom/core/compartment.py,sha256=-2EYkGfqN12he2dsrtO1afC52Bk_fMD5aRLO_useGCQ,3248
|
|
15
|
+
swcgeom/core/node.py,sha256=Kwqoh_WMBLIt2WNDwF-7EwS-C8lONG5krGPmmdHwhvY,3329
|
|
16
|
+
swcgeom/core/path.py,sha256=mxexT7eEHpRaCapE4t0dzfQGgW_zPPzn6N1MkD-jLgI,4579
|
|
17
|
+
swcgeom/core/population.py,sha256=MVVAgGki9SQYMuEJpWyG0eBX4ImR2wpfvWxMqAnXRa8,9824
|
|
18
|
+
swcgeom/core/swc.py,sha256=lSYxAa25l6O8WZ9JtSSET-RZMr6EA1Tq_aXL_x0H9Rc,6795
|
|
19
|
+
swcgeom/core/tree.py,sha256=fQM_Z5-bWsh55hS1pde52tSjKE9-aZY75wbKmDOOQcQ,12195
|
|
20
|
+
swcgeom/core/tree_utils.py,sha256=WWh7uizkyG0u7Zs6ZmkSLPYBsU4XC-gqPeOiVGyaqGE,7749
|
|
21
|
+
swcgeom/core/tree_utils_impl.py,sha256=kN2ByjqqQtZUfmC_ac25tXOaE-CMiV2lP58VxFphLEU,1616
|
|
22
|
+
swcgeom/core/swc_utils/__init__.py,sha256=qghRxjtzvq5KKfN4HhvLpZNsGPfZQu-Jj2x62_5-TbQ,575
|
|
23
|
+
swcgeom/core/swc_utils/assembler.py,sha256=XtjEWz_iAOMpQzLnErCiCjbnqrbB7JA4t2-LLi2R4rQ,889
|
|
24
|
+
swcgeom/core/swc_utils/base.py,sha256=6jNf1EeMz7yJQr3rYSi5EuU2ZPjeefB9vIRFaY53PbA,4788
|
|
25
|
+
swcgeom/core/swc_utils/checker.py,sha256=yuLPRoSt9c7No4GGePa05kxjGFCs0zYS7oB1HadNeMI,2852
|
|
26
|
+
swcgeom/core/swc_utils/io.py,sha256=6_--Qoe8kDja4PWsjwqRAvPJZNMFILFgauHaeWeGikU,6444
|
|
27
|
+
swcgeom/core/swc_utils/normalizer.py,sha256=_Ysi8bSJ2JBnIGB8o6BvAg2mcz6xuJp9rgNLZqpLuR8,5083
|
|
28
|
+
swcgeom/core/swc_utils/subtree.py,sha256=43QITYvgXu3b_kfIod2Irrj3dSfrA-gTFev5VxzRafI,1995
|
|
29
|
+
swcgeom/images/__init__.py,sha256=QBP1ZGGo2nWAcV7Krz-vbvW_jN4ChqXrrpoScXcUURs,96
|
|
30
|
+
swcgeom/images/augmentation.py,sha256=cV4k4KR_WcsRajyr0DuhHVDRRZcN4FQ7OIzB_rb2FUo,4173
|
|
31
|
+
swcgeom/images/contrast.py,sha256=ViZVW6XI-l2sLVTODLRLtHinv_7lVgtH-xZmaw1nQLw,2160
|
|
32
|
+
swcgeom/images/folder.py,sha256=YY9YjF17nDwOQEXhzFe-Dj0zPTcG0WP1-gisscImmYg,6674
|
|
33
|
+
swcgeom/images/io.py,sha256=05VlDcrtt3Un7M2hFddV0aWopgj55TuukSBjHLYwLHg,20704
|
|
34
|
+
swcgeom/transforms/__init__.py,sha256=1rr4X--qY_lBi7l7_NHyvvkoWpQOQOqkioRT8I20olI,562
|
|
35
|
+
swcgeom/transforms/base.py,sha256=gN5Iqi-OHkYrsjllSOdxI6Yzav3jJGoi6kUPy-38FAs,4101
|
|
36
|
+
swcgeom/transforms/branch.py,sha256=R0rVti--u70IiUKyHSx6MsDYJyy6zSCf18Uia2Cmh28,5410
|
|
37
|
+
swcgeom/transforms/geometry.py,sha256=XR73fO_8T7otUFIllqKOWW0OnrsXBc7yA01oDT99yMc,7385
|
|
38
|
+
swcgeom/transforms/image_preprocess.py,sha256=ZVPpRoO69dmLF5K7CWsGaQJXB2G5gxdvA-FcDmfz4yQ,3662
|
|
39
|
+
swcgeom/transforms/image_stack.py,sha256=RIldGAOI3QeoeBtr0VKeBKJVg-fWSmzWll63SvsaTfI,5775
|
|
40
|
+
swcgeom/transforms/images.py,sha256=3j8X8L9q0nSMJ_fP-73jL-zYtgi3fn3Erti9Ej1UZYo,5760
|
|
41
|
+
swcgeom/transforms/mst.py,sha256=Oc_HnaXjg5EXC7ZnOPneHX0-rXizDAEUcjq63GTj-ac,6251
|
|
42
|
+
swcgeom/transforms/neurolucida_asc.py,sha256=O4fK1OMropPnIEVdMenbyT_sV39gEGIv_6vIl6yUOVg,14146
|
|
43
|
+
swcgeom/transforms/path.py,sha256=Gk2iunGQMX7vE83bdo8xoDO-KAT1Vvep0iZs7oFLzFQ,1089
|
|
44
|
+
swcgeom/transforms/population.py,sha256=EmZ6ntuOKe8mXJxMW7nCUA-w2DVlEVe2n0IOVz49tCY,833
|
|
45
|
+
swcgeom/transforms/tree.py,sha256=YzLvKUwTOj92286jHah0CtRYQIxHiNiMGKcgsc_dB0E,6333
|
|
46
|
+
swcgeom/transforms/tree_assembler.py,sha256=vi_X9CNo5IxHP5J7bRl2z91PWufU6HmYlz1iyfdPUxE,5121
|
|
47
|
+
swcgeom/utils/__init__.py,sha256=LXL0wqq6-ggNweZrftp2lrNHCmVJ6LHIto3DuwlYz3c,466
|
|
48
|
+
swcgeom/utils/debug.py,sha256=qay2qJpViLX82mzxdndxQFn-pi1vaEj9CbLGuGt8Y9k,465
|
|
49
|
+
swcgeom/utils/download.py,sha256=By2qZezo6h1Ke_4YpSIhDgcisOrpjVqRmNzbhynC2xs,2834
|
|
50
|
+
swcgeom/utils/dsu.py,sha256=3aCbtpnl_D0OXnowTS8-kuwnCS4BKBYL5ECiFQ1fUW8,1435
|
|
51
|
+
swcgeom/utils/ellipse.py,sha256=LB3q5CIy75GEUdTauIpKySwIHaDrwXzzkBhOCnjJ8Vw,3259
|
|
52
|
+
swcgeom/utils/file.py,sha256=1hchQDsPgn-i-Vz5OQtcogxav_ajCQ_OaEZCLmqczRg,2515
|
|
53
|
+
swcgeom/utils/neuromorpho.py,sha256=xfQ5npDsI_3UHMFbzrBNU453ZG6C6Y271NvU6cExfuc,19107
|
|
54
|
+
swcgeom/utils/numpy_helper.py,sha256=xuvXpZgP-ZeuwTvPFD3DIxwJ5BK4fMCU7k5_5fUHaWE,1425
|
|
55
|
+
swcgeom/utils/plotter_2d.py,sha256=R34_cLfcx_ycPuXS4D0n6ERse7mmzcnhMlkz8KU4yk4,3740
|
|
56
|
+
swcgeom/utils/renderer.py,sha256=yGEu2SBvUQCVwsU8MT273HHgQ9uk5R0Pmo_bJaTN5yU,4233
|
|
57
|
+
swcgeom/utils/sdf.py,sha256=zNDgwXKRNIVcV4ORMmDXup6Bhf_vlHqwa-b3WZn6KhE,10684
|
|
58
|
+
swcgeom/utils/solid_geometry.py,sha256=TV02jhcoCLCqtYA9hfE50LFD_VRfixMiOSiHB5Jb2_U,2431
|
|
59
|
+
swcgeom/utils/transforms.py,sha256=PmP5fL_iVguq4GR2aqXhM0TeCsiFVnrPZMZG6zLohrE,6983
|
|
60
|
+
swcgeom/utils/volumetric_object.py,sha256=DVRGGmQrAL0oaW6hbNtp5TStbic9DfyJdCzsv2FNw2c,15134
|
|
61
|
+
swcgeom-0.17.0.dist-info/LICENSE,sha256=JPtohhZ4XURqoKI0ZqnMYb7dobCOoZR_n5EpnaLTp3E,11344
|
|
62
|
+
swcgeom-0.17.0.dist-info/METADATA,sha256=wtsF7F3P38QJtBXm0wpsAQRofs2sjXAbNHrlrFDLM-4,2332
|
|
63
|
+
swcgeom-0.17.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
64
|
+
swcgeom-0.17.0.dist-info/top_level.txt,sha256=hmLyUXWS61Gxl07haswFEKKefYPBVJYlUlol8ghNkjY,8
|
|
65
|
+
swcgeom-0.17.0.dist-info/RECORD,,
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""Branch anlysis of tree."""
|
|
2
|
-
|
|
3
|
-
from functools import cached_property
|
|
4
|
-
from typing import List, TypeVar
|
|
5
|
-
|
|
6
|
-
import numpy as np
|
|
7
|
-
import numpy.typing as npt
|
|
8
|
-
|
|
9
|
-
from swcgeom.core import Branch, Tree
|
|
10
|
-
|
|
11
|
-
__all__ = ["BranchFeatures"]
|
|
12
|
-
|
|
13
|
-
T = TypeVar("T", bound=Branch)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class BranchFeatures:
|
|
17
|
-
"""Analysis bransh of tree."""
|
|
18
|
-
|
|
19
|
-
tree: Tree
|
|
20
|
-
|
|
21
|
-
def __init__(self, tree: Tree) -> None:
|
|
22
|
-
self.tree = tree
|
|
23
|
-
|
|
24
|
-
def get_count(self) -> int:
|
|
25
|
-
return len(self._branches)
|
|
26
|
-
|
|
27
|
-
def get_length(self) -> npt.NDArray[np.float32]:
|
|
28
|
-
"""Get length of branches."""
|
|
29
|
-
length = [br.length() for br in self._branches]
|
|
30
|
-
return np.array(length, dtype=np.float32)
|
|
31
|
-
|
|
32
|
-
def get_tortuosity(self) -> npt.NDArray[np.float32]:
|
|
33
|
-
"""Get tortuosity of path."""
|
|
34
|
-
return np.array([br.tortuosity() for br in self._branches], dtype=np.float32)
|
|
35
|
-
|
|
36
|
-
def get_angle(self, eps: float = 1e-7) -> npt.NDArray[np.float32]:
|
|
37
|
-
"""Get agnle between branches.
|
|
38
|
-
|
|
39
|
-
Returns
|
|
40
|
-
-------
|
|
41
|
-
angle : npt.NDArray[np.float32]
|
|
42
|
-
An array of shape (N, N), which N is length of branches.
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
return self.calc_angle(self._branches, eps=eps)
|
|
46
|
-
|
|
47
|
-
@staticmethod
|
|
48
|
-
def calc_angle(branches: List[T], eps: float = 1e-7) -> npt.NDArray[np.float32]:
|
|
49
|
-
"""Calc agnle between branches.
|
|
50
|
-
|
|
51
|
-
Returns
|
|
52
|
-
-------
|
|
53
|
-
angle : npt.NDArray[np.float32]
|
|
54
|
-
An array of shape (N, N), which N is length of branches.
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
vector = np.array([br[-1].xyz() - br[0].xyz() for br in branches])
|
|
58
|
-
vector_dot = np.matmul(vector, vector.T)
|
|
59
|
-
vector_norm = np.linalg.norm(vector, ord=2, axis=1, keepdims=True)
|
|
60
|
-
vector_norm_dot = np.matmul(vector_norm, vector_norm.T) + eps
|
|
61
|
-
arccos = np.clip(vector_dot / vector_norm_dot, -1, 1)
|
|
62
|
-
angle = np.arccos(arccos)
|
|
63
|
-
return angle
|
|
64
|
-
|
|
65
|
-
@cached_property
|
|
66
|
-
def _branches(self) -> List[Tree.Branch]:
|
|
67
|
-
return self.tree.get_branches()
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"""Depth distribution of tree."""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from functools import cached_property
|
|
5
|
-
from typing import List
|
|
6
|
-
|
|
7
|
-
import numpy as np
|
|
8
|
-
import numpy.typing as npt
|
|
9
|
-
|
|
10
|
-
from swcgeom.core import Tree
|
|
11
|
-
|
|
12
|
-
__all__ = ["PathFeatures"]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class PathFeatures:
|
|
16
|
-
"""Path analysis of tree."""
|
|
17
|
-
|
|
18
|
-
tree: Tree
|
|
19
|
-
|
|
20
|
-
def __init__(self, tree: Tree) -> None:
|
|
21
|
-
self.tree = tree
|
|
22
|
-
|
|
23
|
-
def get_count(self) -> int:
|
|
24
|
-
return len(self._paths)
|
|
25
|
-
|
|
26
|
-
def get_length(self) -> npt.NDArray[np.float32]:
|
|
27
|
-
"""Get length of paths."""
|
|
28
|
-
length = [path.length() for path in self._paths]
|
|
29
|
-
return np.array(length, dtype=np.float32)
|
|
30
|
-
|
|
31
|
-
def get_tortuosity(self) -> npt.NDArray[np.float32]:
|
|
32
|
-
"""Get tortuosity of path."""
|
|
33
|
-
return np.array([path.tortuosity() for path in self._paths], dtype=np.float32)
|
|
34
|
-
|
|
35
|
-
@cached_property
|
|
36
|
-
def _paths(self) -> List[Tree.Path]:
|
|
37
|
-
return self.tree.get_paths()
|
swcgeom-0.15.0.dist-info/RECORD
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
swcgeom/__init__.py,sha256=z88Zwcjv-ii7c7dYd9QPg9XrUVorQjtrgGbQCsEnQhc,265
|
|
2
|
-
swcgeom/_version.py,sha256=oHv-EAjiXbJma3jZ0Tq6UPimiWYyyw2Ao9S8zdq9uWs,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=Ece6q1VNCRLLMj29N_MjXmmlHT8h4tpWCuDE0uSgKJo,1873
|
|
15
|
-
swcgeom/core/node.py,sha256=HvfgsW4WU01hkRIPci8KF4bQMAkwtAxOGfUL4yUbuBs,3623
|
|
16
|
-
swcgeom/core/path.py,sha256=CsEelHiDR0JPBP1dTvoCSRvX3kBlZxkQilosnncV4nQ,4188
|
|
17
|
-
swcgeom/core/population.py,sha256=I9xSeGUveLhxkOg_5FWLcvf4yJVJ6j9_n03Hna3y_6w,8790
|
|
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=K2k7o8OZ9r2YeMmIebT8_0qvkwJYtLLzFHECz3fmmts,12365
|
|
21
|
-
swcgeom/core/tree_utils.py,sha256=3aCHghny5Z727sxkt6P8E2MMr34vK6irfPCelMn3vk4,7681
|
|
22
|
-
swcgeom/core/tree_utils_impl.py,sha256=kN2ByjqqQtZUfmC_ac25tXOaE-CMiV2lP58VxFphLEU,1616
|
|
23
|
-
swcgeom/core/swc_utils/__init__.py,sha256=qghRxjtzvq5KKfN4HhvLpZNsGPfZQu-Jj2x62_5-TbQ,575
|
|
24
|
-
swcgeom/core/swc_utils/assembler.py,sha256=_ByaVFc61rfCS2p9QUw4g40uF4pZ6NJaDc--TcV4jWo,642
|
|
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=43QITYvgXu3b_kfIod2Irrj3dSfrA-gTFev5VxzRafI,1995
|
|
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=2REkrdNghLm1z8kZ2PDVvtsupzog8kARkeMjLuLiLFo,4955
|
|
33
|
-
swcgeom/images/io.py,sha256=jUyKjtau8_5V-PN1kRsPHtP1OtueJi1zEf5-7PZ_tG8,21226
|
|
34
|
-
swcgeom/transforms/__init__.py,sha256=Mi2mOgkQ50JbZ9LmgXgJIuAA5eio67oe2AOs2CCCxTQ,463
|
|
35
|
-
swcgeom/transforms/base.py,sha256=gN5Iqi-OHkYrsjllSOdxI6Yzav3jJGoi6kUPy-38FAs,4101
|
|
36
|
-
swcgeom/transforms/branch.py,sha256=R0rVti--u70IiUKyHSx6MsDYJyy6zSCf18Uia2Cmh28,5410
|
|
37
|
-
swcgeom/transforms/geometry.py,sha256=XR73fO_8T7otUFIllqKOWW0OnrsXBc7yA01oDT99yMc,7385
|
|
38
|
-
swcgeom/transforms/image_stack.py,sha256=KhZ26Ps88jk_7NkI9dkS2E7NZXUvMaN3Ln9WzJ-vPu0,5823
|
|
39
|
-
swcgeom/transforms/images.py,sha256=l5Hx8x27zoClUz3s11j2oj0Lt9ROh5JJfjoIU_vd3H8,898
|
|
40
|
-
swcgeom/transforms/mst.py,sha256=ceL_EWpCtoSy9zYD6wPP5zO68eNTrDl9JExoPLcE_Lw,6236
|
|
41
|
-
swcgeom/transforms/path.py,sha256=Gk2iunGQMX7vE83bdo8xoDO-KAT1Vvep0iZs7oFLzFQ,1089
|
|
42
|
-
swcgeom/transforms/population.py,sha256=EmZ6ntuOKe8mXJxMW7nCUA-w2DVlEVe2n0IOVz49tCY,833
|
|
43
|
-
swcgeom/transforms/tree.py,sha256=Q45sVA7yi8pINV7ENOWPKz6DnEM3U5uJxwkFKNFS5VE,6262
|
|
44
|
-
swcgeom/transforms/tree_assembler.py,sha256=vi_X9CNo5IxHP5J7bRl2z91PWufU6HmYlz1iyfdPUxE,5121
|
|
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.15.0.dist-info/LICENSE,sha256=JPtohhZ4XURqoKI0ZqnMYb7dobCOoZR_n5EpnaLTp3E,11344
|
|
59
|
-
swcgeom-0.15.0.dist-info/METADATA,sha256=VJX8KlMJWpYCZ-bMUYy_kL05sAHXmvHLMqUepQaKNTQ,2347
|
|
60
|
-
swcgeom-0.15.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
61
|
-
swcgeom-0.15.0.dist-info/top_level.txt,sha256=hmLyUXWS61Gxl07haswFEKKefYPBVJYlUlol8ghNkjY,8
|
|
62
|
-
swcgeom-0.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|