swcgeom 0.18.1__py3-none-any.whl → 0.19.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 (68) hide show
  1. swcgeom/__init__.py +12 -1
  2. swcgeom/analysis/__init__.py +6 -6
  3. swcgeom/analysis/feature_extractor.py +22 -24
  4. swcgeom/analysis/features.py +18 -40
  5. swcgeom/analysis/lmeasure.py +227 -323
  6. swcgeom/analysis/sholl.py +17 -23
  7. swcgeom/analysis/trunk.py +23 -28
  8. swcgeom/analysis/visualization.py +37 -44
  9. swcgeom/analysis/visualization3d.py +16 -25
  10. swcgeom/analysis/volume.py +33 -47
  11. swcgeom/core/__init__.py +12 -13
  12. swcgeom/core/branch.py +10 -17
  13. swcgeom/core/branch_tree.py +3 -2
  14. swcgeom/core/compartment.py +1 -1
  15. swcgeom/core/node.py +3 -6
  16. swcgeom/core/path.py +11 -16
  17. swcgeom/core/population.py +32 -51
  18. swcgeom/core/swc.py +25 -16
  19. swcgeom/core/swc_utils/__init__.py +10 -12
  20. swcgeom/core/swc_utils/assembler.py +5 -12
  21. swcgeom/core/swc_utils/base.py +40 -31
  22. swcgeom/core/swc_utils/checker.py +3 -8
  23. swcgeom/core/swc_utils/io.py +32 -47
  24. swcgeom/core/swc_utils/normalizer.py +17 -23
  25. swcgeom/core/swc_utils/subtree.py +13 -20
  26. swcgeom/core/tree.py +61 -51
  27. swcgeom/core/tree_utils.py +36 -49
  28. swcgeom/core/tree_utils_impl.py +4 -6
  29. swcgeom/images/__init__.py +2 -2
  30. swcgeom/images/augmentation.py +23 -39
  31. swcgeom/images/contrast.py +22 -46
  32. swcgeom/images/folder.py +32 -34
  33. swcgeom/images/io.py +80 -121
  34. swcgeom/transforms/__init__.py +13 -13
  35. swcgeom/transforms/base.py +28 -19
  36. swcgeom/transforms/branch.py +31 -41
  37. swcgeom/transforms/branch_tree.py +3 -1
  38. swcgeom/transforms/geometry.py +13 -4
  39. swcgeom/transforms/image_preprocess.py +2 -0
  40. swcgeom/transforms/image_stack.py +40 -35
  41. swcgeom/transforms/images.py +31 -24
  42. swcgeom/transforms/mst.py +27 -40
  43. swcgeom/transforms/neurolucida_asc.py +13 -13
  44. swcgeom/transforms/path.py +4 -0
  45. swcgeom/transforms/population.py +4 -0
  46. swcgeom/transforms/tree.py +16 -11
  47. swcgeom/transforms/tree_assembler.py +37 -54
  48. swcgeom/utils/__init__.py +12 -12
  49. swcgeom/utils/download.py +7 -14
  50. swcgeom/utils/dsu.py +12 -0
  51. swcgeom/utils/ellipse.py +26 -14
  52. swcgeom/utils/file.py +8 -13
  53. swcgeom/utils/neuromorpho.py +78 -92
  54. swcgeom/utils/numpy_helper.py +15 -12
  55. swcgeom/utils/plotter_2d.py +10 -16
  56. swcgeom/utils/plotter_3d.py +7 -9
  57. swcgeom/utils/renderer.py +16 -8
  58. swcgeom/utils/sdf.py +12 -23
  59. swcgeom/utils/solid_geometry.py +58 -2
  60. swcgeom/utils/transforms.py +164 -100
  61. swcgeom/utils/volumetric_object.py +29 -53
  62. {swcgeom-0.18.1.dist-info → swcgeom-0.19.0.dist-info}/METADATA +7 -6
  63. swcgeom-0.19.0.dist-info/RECORD +67 -0
  64. {swcgeom-0.18.1.dist-info → swcgeom-0.19.0.dist-info}/WHEEL +1 -1
  65. swcgeom/_version.py +0 -16
  66. swcgeom-0.18.1.dist-info/RECORD +0 -68
  67. {swcgeom-0.18.1.dist-info → swcgeom-0.19.0.dist-info/licenses}/LICENSE +0 -0
  68. {swcgeom-0.18.1.dist-info → swcgeom-0.19.0.dist-info}/top_level.txt +0 -0
@@ -36,26 +36,56 @@ Vec3f = tuple[float, float, float]
36
36
 
37
37
 
38
38
  def angle(a: npt.ArrayLike, b: npt.ArrayLike) -> float:
39
- """Get the angle of vectors.
39
+ """Get the signed angle between two vectors.
40
40
 
41
- Returns
42
- -------
43
- angle : float
44
- Angle in radians.
41
+ The angle is positive if the rotation from a to b is counter-clockwise, and
42
+ negative if clockwise.
43
+
44
+ >>> angle([1, 0, 0], [1, 0, 0]) # identical
45
+ 0.0
46
+ >>> angle([1, 0, 0], [0, 1, 0]) # 90 degrees counter-clockwise
47
+ 1.5707963267948966
48
+ >>> angle([1, 0, 0], [0, -1, 0]) # 90 degrees clockwise
49
+ -1.5707963267948966
50
+
51
+ Returns:
52
+ angle: Angle in radians between -π and π.
45
53
  """
46
- a, b = np.array(a), np.array(b)
47
- costheta = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
48
- theta = np.arccos(costheta)
49
- return theta if np.cross(a, b) > 0 else -theta
50
54
 
55
+ a = np.asarray(a)
56
+ b = np.asarray(b)
51
57
 
52
- def scale3d(sx: float, sy: float, sz: float) -> npt.NDArray[np.float32]:
53
- """Get the 3D scale transfomation matrix.
58
+ # Normalize vectors
59
+ a_norm = a / np.linalg.norm(a)
60
+ b_norm = b / np.linalg.norm(b)
61
+
62
+ # Calculate cosine of angle
63
+ cos_theta = np.dot(a_norm, b_norm)
64
+ cos_theta = np.clip(cos_theta, -1.0, 1.0) # Ensure within valid range
65
+ theta = np.arccos(cos_theta)
66
+
67
+ # Determine sign using cross product
68
+ cross = np.cross(a_norm, b_norm)
69
+ sign = np.sign(cross[2]) # Use z-component for 3D
70
+ return float(sign * theta)
54
71
 
55
- Returns
56
- -------
57
- T : np.NDArray
58
- The homogeneous transfomation matrix, shape (4, 4).
72
+
73
+ def scale3d(sx: float, sy: float, sz: float) -> npt.NDArray[np.float32]:
74
+ """Get the 3D scale transformation matrix.
75
+
76
+ >>> np.allclose(
77
+ ... scale3d(2, 3, 4),
78
+ ... [
79
+ ... [2.0, 0.0, 0.0, 0.0],
80
+ ... [0.0, 3.0, 0.0, 0.0],
81
+ ... [0.0, 0.0, 4.0, 0.0],
82
+ ... [0.0, 0.0, 0.0, 1.0],
83
+ ... ],
84
+ ... )
85
+ True
86
+
87
+ Returns:
88
+ T: The homogeneous transformation matrix, shape (4, 4).
59
89
  """
60
90
  return np.array(
61
91
  [
@@ -69,12 +99,21 @@ def scale3d(sx: float, sy: float, sz: float) -> npt.NDArray[np.float32]:
69
99
 
70
100
 
71
101
  def translate3d(tx: float, ty: float, tz: float) -> npt.NDArray[np.float32]:
72
- """Get the 3D translate transfomation matrix.
73
-
74
- Returns
75
- -------
76
- T : np.NDArray
77
- The homogeneous transfomation matrix, shape (4, 4).
102
+ """Get the 3D translate transformation matrix.
103
+
104
+ >>> np.allclose(
105
+ ... translate3d(1, 2, 3),
106
+ ... [
107
+ ... [1.0, 0.0, 0.0, 1.0],
108
+ ... [0.0, 1.0, 0.0, 2.0],
109
+ ... [0.0, 0.0, 1.0, 3.0],
110
+ ... [0.0, 0.0, 0.0, 1.0],
111
+ ... ],
112
+ ... )
113
+ True
114
+
115
+ Returns:
116
+ T: The homogeneous transformation matrix, shape (4, 4).
78
117
  """
79
118
  return np.array(
80
119
  [
@@ -88,10 +127,10 @@ def translate3d(tx: float, ty: float, tz: float) -> npt.NDArray[np.float32]:
88
127
 
89
128
 
90
129
  def rotate3d(n: npt.ArrayLike, theta: float) -> npt.NDArray[np.float32]:
91
- r"""Get the 3D rotation transfomation matrix.
130
+ r"""Get the 3D rotation transformation matrix.
92
131
 
93
- Rotate v with axis n by an angle theta according to the right hand rule,
94
- follow rodrigues' rotaion formula.
132
+ Rotate v with axis n by an angle theta according to the right hand rule, follow
133
+ rodrigues' rotation formula.
95
134
 
96
135
  .. math::
97
136
 
@@ -105,17 +144,12 @@ def rotate3d(n: npt.ArrayLike, theta: float) -> npt.NDArray[np.float32]:
105
144
  -n_y & n_x & 0
106
145
  \end{pmatrix}
107
146
 
108
- Parameters
109
- ----------
110
- n : ArrayLike
111
- Rotation axis.
112
- theta : float
113
- Rotation angle in radians.
114
-
115
- Returns
116
- -------
117
- T : np.NDArray
118
- The homogeneous transfomation matrix, shape (4, 4).
147
+ Args:
148
+ n: Rotation axis.
149
+ theta: Rotation angle in radians.
150
+
151
+ Returns:
152
+ T: The homogeneous transformation matrix, shape (4, 4).
119
153
  """
120
154
 
121
155
  n = np.array(n)
@@ -138,20 +172,28 @@ def rotate3d(n: npt.ArrayLike, theta: float) -> npt.NDArray[np.float32]:
138
172
 
139
173
 
140
174
  def rotate3d_x(theta: float) -> npt.NDArray[np.float32]:
141
- """Get the 3D rotation transfomation matrix.
175
+ """Get the 3D rotation transformation matrix.
142
176
 
143
177
  Rotate 3D vector `v` with `x`-axis by an angle theta according to the right
144
178
  hand rule.
145
179
 
146
- Parameters
147
- ----------
148
- theta : float
149
- Rotation angle in radians.
150
-
151
- Returns
152
- -------
153
- T : np.NDArray
154
- The homogeneous transfomation matrix, shape (4, 4).
180
+ >>> np.allclose(
181
+ ... rotate3d_x(np.pi / 2), # 90 degree rotation
182
+ ... [
183
+ ... [+1.0, +0.0, +0.0, +0.0],
184
+ ... [+0.0, +0.0, -1.0, +0.0],
185
+ ... [+0.0, +1.0, +0.0, +0.0],
186
+ ... [+0.0, +0.0, +0.0, +1.0],
187
+ ... ],
188
+ ... )
189
+ True
190
+
191
+ Args:
192
+ theta: float
193
+ Rotation angle in radians.
194
+
195
+ Returns:
196
+ T: The homogeneous transformation matrix, shape (4, 4).
155
197
  """
156
198
 
157
199
  return np.array(
@@ -166,20 +208,27 @@ def rotate3d_x(theta: float) -> npt.NDArray[np.float32]:
166
208
 
167
209
 
168
210
  def rotate3d_y(theta: float) -> npt.NDArray[np.float32]:
169
- """Get the 3D rotation transfomation matrix.
211
+ """Get the 3D rotation transformation matrix.
170
212
 
171
213
  Rotate 3D vector `v` with `y`-axis by an angle theta according to the right
172
214
  hand rule.
173
215
 
174
- Parameters
175
- ----------
176
- theta : float
177
- Rotation angle in radians.
178
-
179
- Returns
180
- -------
181
- T : np.NDArray
182
- The homogeneous transfomation matrix, shape (4, 4).
216
+ >>> np.allclose(
217
+ ... rotate3d_y(np.pi / 2), # 90 degree rotation
218
+ ... [
219
+ ... [+0.0, +0.0, +1.0, +0.0],
220
+ ... [+0.0, +1.0, +0.0, +0.0],
221
+ ... [-1.0, +0.0, +0.0, +0.0],
222
+ ... [+0.0, +0.0, +0.0, +1.0],
223
+ ... ],
224
+ ... )
225
+ True
226
+
227
+ Args:
228
+ theta: Rotation angle in radians.
229
+
230
+ Returns:
231
+ T: The homogeneous transformation matrix, shape (4, 4).
183
232
  """
184
233
  return np.array(
185
234
  [
@@ -193,20 +242,29 @@ def rotate3d_y(theta: float) -> npt.NDArray[np.float32]:
193
242
 
194
243
 
195
244
  def rotate3d_z(theta: float) -> npt.NDArray[np.float32]:
196
- """Get the 3D rotation transfomation matrix.
197
-
198
- Rotate 3D vector `v` with `z`-axis by an angle theta according to the right
199
- hand rule.
200
-
201
- Parameters
202
- ----------
203
- theta : float
204
- Rotation angle in radians.
205
-
206
- Returns
207
- -------
208
- T : np.NDArray
209
- The homogeneous transfomation matrix, shape (4, 4).
245
+ """Get the 3D rotation transformation matrix.
246
+
247
+ Rotate 3D vector `v` with `z`-axis by an angle theta according to the right hand
248
+ rule.
249
+
250
+ >>> np.allclose(
251
+ ... rotate3d_z(np.pi / 2), # 90 degree rotation
252
+ ... [
253
+ ... [+0.0, -1.0, +0.0, +0.0],
254
+ ... [+1.0, +0.0, +0.0, +0.0],
255
+ ... [+0.0, +0.0, +1.0, +0.0],
256
+ ... [+0.0, +0.0, +0.0, +1.0],
257
+ ... ],
258
+ ... )
259
+ True
260
+
261
+ Args:
262
+ theta: float
263
+ Rotation angle in radians.
264
+
265
+ Returns:
266
+ T: np.NDArray
267
+ The homogeneous transformation matrix, shape (4, 4).
210
268
  """
211
269
  return np.array(
212
270
  [
@@ -222,17 +280,20 @@ def rotate3d_z(theta: float) -> npt.NDArray[np.float32]:
222
280
  def to_homogeneous(xyz: npt.ArrayLike, w: float) -> npt.NDArray[np.float32]:
223
281
  """Fill xyz to homogeneous coordinates.
224
282
 
225
- Parameters
226
- ----------
227
- xyz : ArrayLike
228
- Coordinate of shape (..., 3)
229
- w : float
230
- w of homogeneous coordinate, 1 for dot, 0 for vector.
231
-
232
- Returns
233
- -------
234
- xyz4 : npt.NDArray[np.float32]
235
- Array of shape (..., 4)
283
+ >>> np.allclose(to_homogeneous([1, 2, 3], 1), [1.0, 2.0, 3.0, 1.0])
284
+ True
285
+ >>> np.allclose(
286
+ ... to_homogeneous([[1, 2, 3], [4, 5, 6]], 0),
287
+ ... [[1.0, 2.0, 3.0, 0.0], [4.0, 5.0, 6.0, 0.0]],
288
+ ... )
289
+ True
290
+
291
+ Args:
292
+ xyz: Coordinate of shape (..., 3)
293
+ w: w of homogeneous coordinate, 1 for dot, 0 for vector.
294
+
295
+ Returns:
296
+ xyz4: Array of shape (..., 4)
236
297
  """
237
298
  xyz = np.array(xyz)
238
299
  if xyz.ndim == 1:
@@ -247,17 +308,12 @@ def to_homogeneous(xyz: npt.ArrayLike, w: float) -> npt.NDArray[np.float32]:
247
308
  def _to_homogeneous(xyz: npt.NDArray, w: float) -> npt.NDArray[np.float32]:
248
309
  """Fill xyz to homogeneous coordinates.
249
310
 
250
- Parameters
251
- ----------
252
- xyz : npt.NDArray
253
- Coordinate of shape (N, 3)
254
- w : float
255
- w of homogeneous coordinate, 1 for dot, 0 for vector.
256
-
257
- Returns
258
- -------
259
- xyz4 : npt.NDArray[np.float32]
260
- Array of shape (N, 4)
311
+ Args:
312
+ xyz: Coordinate of shape (N, 3)
313
+ w: w of homogeneous coordinate, 1 for dot, 0 for vector.
314
+
315
+ Returns:
316
+ xyz4: Array of shape (N, 4)
261
317
  """
262
318
  if xyz.shape[1] == 4:
263
319
  return xyz
@@ -273,14 +329,10 @@ def model_view_transformation(
273
329
  ) -> npt.NDArray[np.float32]:
274
330
  r"""Play model/view transformation.
275
331
 
276
- Parameters
277
- ----------
278
- position: Tuple[float, float, float]
279
- Camera position \vec{e}.
280
- look_at: Tuple[float, float, float]
281
- Camera look-at \vec{g}.
282
- up: Tuple[float, float, float]
283
- Camera up direction \vec{t}.
332
+ Args:
333
+ position: Camera position \vec{e}.
334
+ look_at: Camera look-at \vec{g}.
335
+ up: Camera up direction \vec{t}.
284
336
  """
285
337
 
286
338
  e = np.array(position, dtype=np.float32)
@@ -301,7 +353,19 @@ def model_view_transformation(
301
353
 
302
354
 
303
355
  def orthographic_projection_simple() -> npt.NDArray[np.float32]:
304
- """Simple orthographic projection by drop z-axis"""
356
+ """Simple orthographic projection by drop z-axis
357
+
358
+ >>> np.allclose(
359
+ ... orthographic_projection_simple(),
360
+ ... [
361
+ ... [1.0, 0.0, 0.0, 0.0],
362
+ ... [0.0, 1.0, 0.0, 0.0],
363
+ ... [0.0, 0.0, 0.0, 0.0],
364
+ ... [0.0, 0.0, 0.0, 0.0],
365
+ ... ],
366
+ ... )
367
+ True
368
+ """
305
369
  return np.array(
306
370
  [
307
371
  [1, 0, 0, 0],
@@ -31,7 +31,7 @@ computations.
31
31
 
32
32
  import warnings
33
33
  from abc import ABC, abstractmethod
34
- from typing import Generic, Optional, TypeVar
34
+ from typing import Generic, TypeVar
35
35
 
36
36
  import numpy as np
37
37
  import numpy.typing as npt
@@ -98,7 +98,7 @@ class VolMCObject(VolObject, ABC):
98
98
  cache_volume: float | None = None
99
99
  cache_volume_n_samples: int = 0
100
100
 
101
- def __init__(self, *, n_samples: Optional[int] = None) -> None:
101
+ def __init__(self, *, n_samples: int | None = None) -> None:
102
102
  super().__init__()
103
103
  if n_samples is not None:
104
104
  warnings.warn(
@@ -113,17 +113,12 @@ class VolMCObject(VolObject, ABC):
113
113
  def sample(self, n: int) -> tuple[npt.NDArray[np.float32], float]:
114
114
  """Sample points.
115
115
 
116
- Parameters
117
- ----------
118
- n : int
119
- Number of points to sample.
120
-
121
- Returns
122
- -------
123
- points : ndarray
124
- Sampled points.
125
- volume : float
126
- Volume of the sample range.
116
+ Args:
117
+ n: Number of points to sample.
118
+
119
+ Returns:
120
+ points: Sampled points.
121
+ volume: Volume of the sample range.
127
122
  """
128
123
  raise NotImplementedError()
129
124
 
@@ -135,21 +130,17 @@ class VolMCObject(VolObject, ABC):
135
130
  def is_in(self, p: npt.NDArray[np.float32]) -> npt.NDArray[np.bool_]:
136
131
  """Is p in the object.
137
132
 
138
- Returns
139
- -------
140
- is_in : npt.NDArray[np.bool_]
141
- Array of shape (N,), if bounding box is `None`, `True` will
142
- be returned.
133
+ Returns:
134
+ is_in: Array of shape (N,).
135
+ If bounding box is `None`, `True` will be returned.
143
136
  """
144
137
  return np.array([self.inside(pp) for pp in p])
145
138
 
146
- def _get_volume(self, *, n_samples: Optional[int] = None) -> float:
139
+ def _get_volume(self, *, n_samples: int | None = None) -> float:
147
140
  """Get volume by Monte Carlo integration.
148
141
 
149
- Parameters
150
- ----------
151
- n_samples : int, default 1_000_000
152
- Number of samples
142
+ Args:
143
+ n_samples: Number of samples, default 1_000_000
153
144
  """
154
145
 
155
146
  # legacy
@@ -178,9 +169,7 @@ class VolMCObject(VolObject, ABC):
178
169
  class VolSDFObject(VolMCObject):
179
170
  """Volumetric SDF Object.
180
171
 
181
- Notes
182
- -----
183
- SDF must has a bounding box.
172
+ NOTE: SDF must has a bounding box.
184
173
  """
185
174
 
186
175
  def __init__(self, sdf: SDF, **kwargs) -> None:
@@ -294,10 +283,8 @@ class VolSphere(VolSDFObject):
294
283
  V = \frac{4}{3} * π * r^3
295
284
  \end{equation}
296
285
 
297
- Returns
298
- -------
299
- volume : float
300
- Volume.
286
+ Returns:
287
+ volume: volume of sphere.
301
288
  """
302
289
  return 4 / 3 * np.pi * radius**3
303
290
 
@@ -309,17 +296,12 @@ class VolSphere(VolSDFObject):
309
296
  V = π * h^2 * (3r - h) / 3
310
297
  \end{equation}
311
298
 
312
- Parameters
313
- ----------
314
- r : float
315
- radius of the sphere
316
- h : float
317
- height of the spherical cap
318
-
319
- Returns
320
- -------
321
- volume : float
322
- volume of the spherical cap
299
+ Args:
300
+ r: radius of the sphere
301
+ h: height of the spherical cap
302
+
303
+ Returns:
304
+ volume: volume of the spherical cap
323
305
  """
324
306
  return np.pi * h**2 * (3 * r - h) / 3
325
307
 
@@ -361,10 +343,8 @@ class VolFrustumCone(VolSDFObject):
361
343
  V = \frac{1}{3} * π * h * (r^2 + r * R + R^2)
362
344
  \end{equation}
363
345
 
364
- Returns
365
- -------
366
- volume : float
367
- Volume.
346
+ Returns:
347
+ volume: volume of frustum.
368
348
  """
369
349
  return (1 / 3) * np.pi * height * (r1**2 + r1 * r2 + r2**2)
370
350
 
@@ -386,10 +366,8 @@ class VolSphere2Intersection(VolSDFIntersection[VolSphere, VolSphere]):
386
366
  V = \frac{\pi}{12d} * (r_1 + r_2 - d)^2 (d^2 + 2d r_1 - 3r_1^2 + 2d r_2 - 3r_2^2 + 6 r_1r_2)
387
367
  \end{equation}
388
368
 
389
- Returns
390
- -------
391
- volume : float
392
- Intersect volume.
369
+ Returns:
370
+ volume: Intersect volume.
393
371
  """
394
372
 
395
373
  r1, r2 = obj1.radius, obj2.radius
@@ -440,10 +418,8 @@ class VolSphereFrustumConeIntersection(VolSDFIntersection[VolSphere, VolFrustumC
440
418
  ) -> float:
441
419
  r"""Calculate intersect volume of sphere and frustum cone.
442
420
 
443
- Returns
444
- -------
445
- volume : float
446
- Intersect volume.
421
+ Returns:
422
+ volume: Intersect volume.
447
423
  """
448
424
 
449
425
  h = frustum_cone.height()
@@ -1,8 +1,8 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: swcgeom
3
- Version: 0.18.1
3
+ Version: 0.19.0
4
4
  Summary: Neuron geometry library for swc format
5
- Author-email: yzx9 <yuan.zx@outlook.com>
5
+ Author-email: yzx9 <pypi@yzx9.xyz>
6
6
  License: Apache-2.0
7
7
  Project-URL: repository, https://github.com/yzx9/swcgeom
8
8
  Keywords: neuronscience,neuron,neuroanatomy,neuron-morphology
@@ -15,12 +15,12 @@ Requires-Dist: numpy>=1.22.3
15
15
  Requires-Dist: pandas>=1.4.2
16
16
  Requires-Dist: pynrrd>=1.1.0
17
17
  Requires-Dist: scipy>=1.9.1
18
- Requires-Dist: sdflit>=0.2.1
18
+ Requires-Dist: sdflit>=0.2.6
19
19
  Requires-Dist: seaborn>=0.12.0
20
20
  Requires-Dist: tifffile>=2022.8.12
21
- Requires-Dist: typing_extensions>=4.4.0
21
+ Requires-Dist: typing-extensions>=4.4.0
22
22
  Requires-Dist: tqdm>=4.46.1
23
- Requires-Dist: v3d-py-helper==0.1.0
23
+ Requires-Dist: v3d-py-helper>=0.4.1
24
24
  Provides-Extra: all
25
25
  Requires-Dist: beautifulsoup4>=4.11.1; extra == "all"
26
26
  Requires-Dist: certifi>=2023.5.7; extra == "all"
@@ -28,6 +28,7 @@ Requires-Dist: chardet>=5.2.0; extra == "all"
28
28
  Requires-Dist: lmdb>=1.4.1; extra == "all"
29
29
  Requires-Dist: requests>=2.0.0; extra == "all"
30
30
  Requires-Dist: urllib3>=1.26.0; extra == "all"
31
+ Dynamic: license-file
31
32
 
32
33
  # SWCGEOM
33
34
 
@@ -0,0 +1,67 @@
1
+ swcgeom/__init__.py,sha256=7Hjtjg2r_dRP-oUmNX_Zza1NqV6703L0XnpuhKQ3wcs,939
2
+ swcgeom/analysis/__init__.py,sha256=1Bp93CxYzKqnTLzRdy8GpnhhBf6t8S2sgpEIhOJOj6w,945
3
+ swcgeom/analysis/feature_extractor.py,sha256=kCrsH5Df6KdocD8hKH_5SeLwdvEuWP09CbLUPaoFGdM,14787
4
+ swcgeom/analysis/features.py,sha256=vn_4sbwTY2muCXJqYEbQilxzSFhugaDlhips_Tt2vE8,6585
5
+ swcgeom/analysis/lmeasure.py,sha256=5B4ltZGvIJCHe1KDkxIvGWv2Ar4_oC5F67Q8n87CnOg,27840
6
+ swcgeom/analysis/sholl.py,sha256=6k7Ek6VxWJcGuTan98Ib18cjtpAzKulEeZds2kzyN6M,7043
7
+ swcgeom/analysis/trunk.py,sha256=q_Rdh0v-aimZKp1krji6B1lynZ7Rc9hYJhESGiLjFDY,5944
8
+ swcgeom/analysis/visualization.py,sha256=MXlBZG5mmoXwjHVcJfERVEYZveSkwTNweKBAIOb1dFM,6029
9
+ swcgeom/analysis/visualization3d.py,sha256=0PRhUOdYPl071xK5PaTl5HFrkOXfwyfHw-d3RD0W1zs,2932
10
+ swcgeom/analysis/volume.py,sha256=mUZRCY8KUdWZiMqZvP6_BlETLsb2_dotxC8vqu50450,5074
11
+ swcgeom/core/__init__.py,sha256=_iC91Q0nU7pUqydHON9hbelf4WY68uhNTRlAzS__CYk,1152
12
+ swcgeom/core/branch.py,sha256=xqGHtoZodId3lREaDHuHgpZruGsOddqA8hPMmlXmcLk,4651
13
+ swcgeom/core/branch_tree.py,sha256=uNkzcg5q99n-Wg3H7eCJQfOE6DP9m-FucCXaFCmBsdc,2443
14
+ swcgeom/core/compartment.py,sha256=QABZiXELtSnsg5u2M2yTOD-9aosg2KB3wRVQvm1ccpY,3851
15
+ swcgeom/core/node.py,sha256=HEFS7pTmGP7xlP0DfvOxbFPAGY87H7uW1exdKKeB6os,4302
16
+ swcgeom/core/path.py,sha256=tkYJttFv_mke9hc_2eqnPC5WJMicQC103W4-Xalo13I,5023
17
+ swcgeom/core/population.py,sha256=IhSZn_2ZKE8nqxpPhVGQU5hedcnkQMBCOCQnfTn5K9Q,10696
18
+ swcgeom/core/swc.py,sha256=AM-KQqVopVTnCpDfVRz6MsjT9Vr8wTEHeqz1aUXGq10,7416
19
+ swcgeom/core/tree.py,sha256=04_HM2lAI-sxQKmarSmXN0obHSD4WHaAPZr0f6nwI5E,13158
20
+ swcgeom/core/tree_utils.py,sha256=tfVDrhxbvGPNOzI4NifWNTzE7ckPWgCziStvYg2hU2A,7859
21
+ swcgeom/core/tree_utils_impl.py,sha256=XK86XX2rX6kq2x_gEjX2uIKHBuAq762C10blWiK2-MA,2156
22
+ swcgeom/core/swc_utils/__init__.py,sha256=oPXmYeFrlDm-rBXhU-5Y4TeKuq_2jbNWqh0_1v7pM3c,1233
23
+ swcgeom/core/swc_utils/assembler.py,sha256=4DahkrtqJKNyFhvrxQVLam1dwjznQ2anAl9X31Hd6LQ,1440
24
+ swcgeom/core/swc_utils/base.py,sha256=98J9R7rAZO685pzIJWfC66T8cfWzepf405cYXWzuuHQ,5273
25
+ swcgeom/core/swc_utils/checker.py,sha256=jCSGEgK9OuVV4ErOq2FStq4AJC4uFDAsnoYHwq-5a6A,3141
26
+ swcgeom/core/swc_utils/io.py,sha256=N90bRWZjtmUrnvlcwD_LTROJUs0OGnYDneGYF6jLnEs,6691
27
+ swcgeom/core/swc_utils/normalizer.py,sha256=LnPw00iiqWeacvXK0hf1_jvK3NkjvgOwrntSAHOaIDc,5576
28
+ swcgeom/core/swc_utils/subtree.py,sha256=kPB2_6DEX147mFNRy2viLqEOms8ypf6a7riLTu-qr_E,2530
29
+ swcgeom/images/__init__.py,sha256=gwBZzrsswJ2hyRQA72khFk2JPo1JfWko4-huuAYNCOU,705
30
+ swcgeom/images/augmentation.py,sha256=3ZWPRee3h1x1v_k2dDpAxCeUApvn2hu0TOPhTwuTe2g,4586
31
+ swcgeom/images/contrast.py,sha256=fLA8snaEJS-0dXkgitDmXepsMgpa4OE9MMGrU5YBz4M,2462
32
+ swcgeom/images/folder.py,sha256=YKJn5M090SKRVf-y5IG7sAmL6d8PsV2QeSquiuzFGHk,6847
33
+ swcgeom/images/io.py,sha256=p0Vm1VAQOlF-EbvOMFnf6xllWVsaJn-2NhFII7rejlI,20310
34
+ swcgeom/transforms/__init__.py,sha256=nE4Uyn5vpYyNiMltTiNHDRkyjYbW6B4ToyZOxUj0TU0,1370
35
+ swcgeom/transforms/base.py,sha256=v1EIpL5Kxg2Q1AfzZ8wSkocjSWHpD9cTeBk8dSmzDRc,4951
36
+ swcgeom/transforms/branch.py,sha256=gWR3lmd5b0PWYypF4WRRQ25O5DSlXok4wfm3Ycmxnbs,7560
37
+ swcgeom/transforms/branch_tree.py,sha256=Sc9gV-BD-KCY0kchID5zs1bIb-XwP0COLsynFPeHbaE,2882
38
+ swcgeom/transforms/geometry.py,sha256=8_v1ifR3taO-hL71fObLOv1jPXu3H1yaeerXkvoNn2k,8140
39
+ swcgeom/transforms/image_preprocess.py,sha256=bp3TIzK8sRetFdoExqfGhFkRSeZ-mv4GQzfxX2otu5c,4296
40
+ swcgeom/transforms/image_stack.py,sha256=SBtyLBWlBxlnt_q2uMXHgQicX5LeDwiKpmf1A-rJRUM,7353
41
+ swcgeom/transforms/images.py,sha256=uYIAwfQqzJwvG_yddeZ0fLXzQQbhF_OrpJ11iFQSPxQ,6264
42
+ swcgeom/transforms/mst.py,sha256=5XW_9R7mKI9HZmKZseTyQbizyaTv_sRybCj_4LmMxfM,6395
43
+ swcgeom/transforms/neurolucida_asc.py,sha256=YR-ycJAUflMFS14gBmdV1wtiSUrY3dixX0FiKd9DPds,14675
44
+ swcgeom/transforms/path.py,sha256=tqwSd6FDcL-xahs1u4r2GdJCdXvpL5BxpTTyQZbIZfs,1738
45
+ swcgeom/transforms/population.py,sha256=I9FqiW5IGlpN8DlED_8JnUx3gm9Y1GlNyEni5W5rNGU,1457
46
+ swcgeom/transforms/tree.py,sha256=TzLYuY9LxjLKFOG34AtlH8S6aO1IcCuRJ0vJYCF5Iso,8237
47
+ swcgeom/transforms/tree_assembler.py,sha256=a46N_XYpyPHoEOVdhyztcilA5e64_pqLtdF__oWF4Rg,5374
48
+ swcgeom/utils/__init__.py,sha256=sduLt0_W5KfoatIQ5Sj26DndwiCQhpPVkZhUVi7akFE,1215
49
+ swcgeom/utils/debug.py,sha256=ZOYLfj32YDjSU1tJrtThWF2SROwYhG2z7j4Fq0q4Dsw,1046
50
+ swcgeom/utils/download.py,sha256=8h1dLJu4Z09g6NgMI-78E1co1ebmKBQoz2TBebTZG9w,4145
51
+ swcgeom/utils/dsu.py,sha256=cci0YXGlOmL1wjqJKyp6la8SuvgBQrEcfuwjLtsGv6o,2267
52
+ swcgeom/utils/ellipse.py,sha256=kKDHTe4ZrVq88HISLyztkEedwR36ItwffB9yOLGCnKQ,4227
53
+ swcgeom/utils/file.py,sha256=Rfn0SDHk0BzHxUIqjFgCPcSTRLADcW3SWAMyPfBe2FI,3080
54
+ swcgeom/utils/neuromorpho.py,sha256=V_L_AU1Jhtg4CCLz_oYfj1mvvFX29DQNDz2BFB8Oetk,19294
55
+ swcgeom/utils/numpy_helper.py,sha256=XrHuG5ac45LhBJyvTm5QsB8CKl-v2dhb4cStcX_Ut0I,2183
56
+ swcgeom/utils/plotter_2d.py,sha256=ZVMQsiTjoHr5FKJfh_DTcsyXTJH4tM0_Zdg5lxnNzJ0,4359
57
+ swcgeom/utils/plotter_3d.py,sha256=lMxvjq51Aj7yBuiw2KOfWkPZwkPHMkaFuORxt2qHaTo,1405
58
+ swcgeom/utils/renderer.py,sha256=ILl9k1sxKK_s2CoKVfJhMKxQrYub1sJvbw4qAX0Ld20,4799
59
+ swcgeom/utils/sdf.py,sha256=wqetIH-7j3TKalIdkgIf-w4CarElvFMFSMJqCPv8IIE,10966
60
+ swcgeom/utils/solid_geometry.py,sha256=YoGDTqCs9lCS8YXrHyKhuA34zOUcPGaRZP_LvjIGSQ8,4578
61
+ swcgeom/utils/transforms.py,sha256=gTT4G6AvmCg2JFDx45OjUQaa4eoWQjP8_iLvk2rE70o,9576
62
+ swcgeom/utils/volumetric_object.py,sha256=fbTU_4rebc7r1dlYNnIeHfLg-vKdXP0ohrINVhe8RRg,15307
63
+ swcgeom-0.19.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
64
+ swcgeom-0.19.0.dist-info/METADATA,sha256=58gMTGMhk-QInpjCbn7HYHGdBHup0PBYEt8KiHsJ7YU,2323
65
+ swcgeom-0.19.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
66
+ swcgeom-0.19.0.dist-info/top_level.txt,sha256=hmLyUXWS61Gxl07haswFEKKefYPBVJYlUlol8ghNkjY,8
67
+ swcgeom-0.19.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
swcgeom/_version.py DELETED
@@ -1,16 +0,0 @@
1
- # file generated by setuptools_scm
2
- # don't change, don't track in version control
3
- TYPE_CHECKING = False
4
- if TYPE_CHECKING:
5
- from typing import Tuple, Union
6
- VERSION_TUPLE = Tuple[Union[int, str], ...]
7
- else:
8
- VERSION_TUPLE = object
9
-
10
- version: str
11
- __version__: str
12
- __version_tuple__: VERSION_TUPLE
13
- version_tuple: VERSION_TUPLE
14
-
15
- __version__ = version = '0.18.1'
16
- __version_tuple__ = version_tuple = (0, 18, 1)