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
@@ -20,6 +20,7 @@ from typing import Literal
20
20
 
21
21
  import numpy as np
22
22
  import numpy.typing as npt
23
+
23
24
  from swcgeom.core import Branch, Compartment, Node, Tree
24
25
 
25
26
  __all__ = ["LMeasure"]
@@ -28,30 +29,26 @@ __all__ = ["LMeasure"]
28
29
  class LMeasure:
29
30
  """L-Measure analysis.
30
31
 
31
- The L-Measure analysis provide a set of morphometric features for
32
- multiple levels analysis, as described in the paper [1]_
32
+ The L-Measure analysis provide a set of morphometric features for multiple levels
33
+ analysis, as described in the paper [1]_
33
34
 
34
- References
35
- ----------
36
- .. [1] Scorcioni R, Polavaram S, Ascoli GA. L-Measure: a
37
- web-accessible tool for the analysis, comparison and search of
38
- digital reconstructions of neuronal morphologies. Nat Protoc.
39
- 2008;3(5):866-76. doi: 10.1038/nprot.2008.51. PMID: 18451794;
40
- PMCID: PMC4340709.
35
+ References:
36
+ .. [1] Scorcioni R, Polavaram S, Ascoli GA. L-Measure: a web-accessible tool for
37
+ the analysis, comparison and search of digital reconstructions of neuronal
38
+ morphologies. Nat Protoc. 2008;3(5):866-76. doi: 10.1038/nprot.2008.51.
39
+ PMID: 18451794; PMCID: PMC4340709.
41
40
 
42
- See Also
43
- --------
44
- L-Measure: http://cng.gmu.edu:8080/Lm/help/index.htm
41
+ See Also:
42
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/index.htm
45
43
  """
46
44
 
47
45
  def __init__(self, compartment_point: Literal[0, -1] = -1):
48
46
  """
49
- Parameters
50
- ----------
51
- compartment_point : 0 | -1, default=-1
52
- The point of the compartment to be used for the measurements.
53
- If 0, the first point of the compartment is used. If -1, the
54
- last point of the compartment is used.
47
+ Args:
48
+ compartment_point:
49
+ The point of the compartment to be used for the measurements. If 0, the
50
+ first point of the compartment is used. If -1, the last point of the
51
+ compartment is used.
55
52
  """
56
53
  super().__init__()
57
54
  self.compartment_point = compartment_point
@@ -61,78 +58,69 @@ class LMeasure:
61
58
  def n_stems(self, tree: Tree) -> int:
62
59
  """Number of stems that is connected to soma.
63
60
 
64
- This function returns the number of stems attached to the soma.
65
- When the type of the Compartment changes from type=1 to others
66
- it is labeled a stem. These stems can also be considered as
67
- independent subtrees for subtree level analysis.
61
+ This function returns the number of stems attached to the soma. When the type
62
+ of the Compartment changes from type=1 to others it is labeled a stem. These
63
+ stems can also be considered as independent subtrees for subtree level analysis.
68
64
 
69
- See Also
70
- --------
71
- L-Measure: http://cng.gmu.edu:8080/Lm/help/N_stems.htm
65
+ See Also:
66
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/N_stems.htm
72
67
  """
73
68
  return len(tree.soma().children())
74
69
 
75
70
  def n_bifs(self, tree: Tree) -> int:
76
71
  """Number of bifurcations.
77
72
 
78
- This function returns the number of bifurcations for the given
79
- input neuron. A bifurcation point has two daughters.
73
+ This function returns the number of bifurcations for the given input neuron. A
74
+ bifurcation point has two daughters.
80
75
 
81
- See Also
82
- --------
83
- L-Measure: http://cng.gmu.edu:8080/Lm/help/N_bifs.htm
76
+ See Also:
77
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/N_bifs.htm
84
78
  """
85
79
  return len(tree.get_furcations())
86
80
 
87
81
  def n_branch(self, tree: Tree) -> int:
88
82
  """Number of branches.
89
83
 
90
- This function returns the number of branches in the given input
91
- neuron. A branch is one or more compartments that lie between
92
- two branching points or between one branching point and a
93
- termination point.
84
+ This function returns the number of branches in the given input neuron. A
85
+ branch is one or more compartments that lie between two branching points or
86
+ between one branching point and a termination point.
94
87
 
95
- See Also
96
- --------
97
- L-Measure: http://cng.gmu.edu:8080/Lm/help/N_branch.htm
88
+ See Also:
89
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/N_branch.htm
98
90
  """
99
91
  return len(tree.get_branches())
100
92
 
101
93
  def n_tips(self, tree: Tree) -> int:
102
94
  """Number of terminal tips.
103
95
 
104
- This function returns the number of terminal tips for the given
105
- input neuron. This function counts the number of compartments
106
- that terminate as terminal endpoints.
96
+ This function returns the number of terminal tips for the given input neuron.
97
+ This function counts the number of compartments that terminate as terminal
98
+ endpoints.
107
99
 
108
- See Also
109
- --------
110
- L-Measure: http://cng.gmu.edu:8080/Lm/help/N_tips.htm
100
+ See Also:
101
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/N_tips.htm
111
102
  """
112
103
  return len(tree.get_tips())
113
104
 
114
105
  def terminal_segment(self) -> int:
115
106
  """Terminal Segment.
116
107
 
117
- TerminalSegment is the branch that ends as a terminal branch.
118
- This function returns "1" for all the compartments in the
119
- terminal branch.
108
+ TerminalSegment is the branch that ends as a terminal branch. This function
109
+ returns "1" for all the compartments in the terminal branch.
120
110
 
121
- See Also
122
- --------
123
- L-Measure: http://cng.gmu.edu:8080/Lm/help/TerminalSegment.htm
111
+ See Also:
112
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/TerminalSegment.htm
124
113
  """
125
114
  raise NotImplementedError()
126
115
 
127
116
  def branch_pathlength(self, branch: Branch) -> float:
128
117
  """Length of the branch.
129
118
 
130
- This function returns the sum of the length of all compartments
131
- forming the giveN_branch.
119
+ This function returns the sum of the length of all compartments forming the
120
+ giveN_branch.
132
121
 
133
- See Also
134
- --------
135
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Branch_pathlength.htm
122
+ See Also:
123
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Branch_pathlength.htm
136
124
  """
137
125
  # ? as a topological measurement, this should accept a tree
138
126
  return branch.length()
@@ -140,12 +128,11 @@ class LMeasure:
140
128
  def contraction(self, branch: Branch) -> float:
141
129
  """Contraction of the branch.
142
130
 
143
- This function returns the ratio between Euclidean distance of a
144
- branch and its path length.
131
+ This function returns the ratio between Euclidean distance of a branch and its
132
+ path length.
145
133
 
146
- See Also
147
- --------
148
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Contraction.htm
134
+ See Also:
135
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Contraction.htm
149
136
  """
150
137
  # ? as a topological measurement, this should accept a tree
151
138
  euclidean = branch[0].distance(branch[-1])
@@ -154,13 +141,11 @@ class LMeasure:
154
141
  def fragmentation(self, branch: Branch) -> int:
155
142
  """Number of compartments.
156
143
 
157
- This function returns the total number of compartments that
158
- constitute a branch between two bifurcation points or between a
159
- bifurcation point and a terminal tip.
144
+ This function returns the total number of compartments that constitute a branch
145
+ between two bifurcation points or between a bifurcation point and a terminal tip.
160
146
 
161
- See Also
162
- --------
163
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Fragmentation.htm
147
+ See Also:
148
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Fragmentation.htm
164
149
  """
165
150
  # ? as a topological measurement, this should accept a tree
166
151
  return branch.number_of_edges()
@@ -168,19 +153,17 @@ class LMeasure:
168
153
  def partition_asymmetry(self, n: Tree.Node) -> float:
169
154
  """Partition asymmetry.
170
155
 
171
- This is computed only on bifurcation. If n1 is the number of
172
- tips on the left and n2 on the right. Asymmetry return
173
- abs(n1-n2)/(n1+n2-2).
156
+ This is computed only on bifurcation. If `n1` is the number of tips on the left
157
+ and `n2` on the right. Asymmetry return `abs(n1-n2)/(n1+n2-2)`.
174
158
 
175
- See Also
176
- --------
177
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Partition_asymmetry.htm
159
+ See Also:
160
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Partition_asymmetry.htm
178
161
  """
179
162
 
180
163
  children = n.children()
181
- assert (
182
- len(children) == 2
183
- ), "Partition asymmetry is only defined for bifurcations"
164
+ assert len(children) == 2, (
165
+ "Partition asymmetry is only defined for bifurcations"
166
+ )
184
167
  n1 = len(children[0].subtree().get_tips())
185
168
  n2 = len(children[1].subtree().get_tips())
186
169
  if n1 == n2:
@@ -190,27 +173,24 @@ class LMeasure:
190
173
  def fractal_dim(self):
191
174
  """Fractal dimension.
192
175
 
193
- Fractal dimension (D) of neuronal branches is computedas the
194
- slope of linear fit of regression line obtained from the
195
- log-log plot of Path distance vs Euclidean distance.
176
+ Fractal dimension (D) of neuronal branches is computedas the slope of linear
177
+ fit of regression line obtained from the log-log plot of Path distance vs
178
+ Euclidean distance.
196
179
 
197
- This method of measuring the fractal follows the reference
198
- given below by Marks & Burke, J Comp Neurol. 2007. [1]_
180
+ This method of measuring the fractal follows the reference given below by
181
+ Marks & Burke, J Comp Neurol. 2007. [1]_
199
182
  - When D = 1, the particle moves in a straight line.
200
183
  - When D = 2, the motion is a space-filling random walk
201
- - When D is only slightly larger than 1, the particle
202
- trajectory resembles a country road or a dendrite branch.
184
+ - When D is only slightly larger than 1, the particle trajectory resembles a
185
+ country road or a dendrite branch.
203
186
 
204
- References
205
- ----------
206
- .. [1] Marks WB, Burke RE. Simulation of motoneuron morphology
207
- in three dimensions. I. Building individual dendritic trees.
208
- J Comp Neurol. 2007 Aug 10;503(5):685-700.
209
- doi: 10.1002/cne.21418. PMID: 17559104.
187
+ References:
188
+ .. [1] Marks WB, Burke RE. Simulation of motoneuron morphology in three
189
+ dimensions. I. Building individual dendritic trees. J Comp Neurol. 2007 Aug
190
+ 10;503(5):685-700. doi: 10.1002/cne.21418. PMID: 17559104.
210
191
 
211
- See Also
212
- --------
213
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Fractal_Dim.htm
192
+ See Also:
193
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Fractal_Dim.htm
214
194
  """
215
195
  raise NotImplementedError()
216
196
 
@@ -219,12 +199,11 @@ class LMeasure:
219
199
  def taper_1(self, branch: Branch) -> float:
220
200
  """The Burke Taper.
221
201
 
222
- This function returns the Burke Taper. This function is
223
- measured between two bifurcation points.
202
+ This function returns the Burke Taper. This function is measured between two
203
+ bifurcation points.
224
204
 
225
- See Also
226
- --------
227
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Taper_1.htm
205
+ See Also:
206
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Taper_1.htm
228
207
  """
229
208
  da, db = 2 * branch[0].r, 2 * branch[-1].r
230
209
  return (da - db) / branch.length()
@@ -232,12 +211,11 @@ class LMeasure:
232
211
  def taper_2(self, branch: Branch) -> float:
233
212
  """The Hillman taper.
234
213
 
235
- This function returns the Hillman taper. This is measured
236
- between two bifurcation points.
214
+ This function returns the Hillman taper. This is measured between two
215
+ bifurcation points.
237
216
 
238
- See Also
239
- --------
240
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Taper_2.htm
217
+ See Also:
218
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Taper_2.htm
241
219
  """
242
220
  da, db = 2 * branch[0].r, 2 * branch[-1].r
243
221
  return (da - db) / da
@@ -245,26 +223,22 @@ class LMeasure:
245
223
  def daughter_ratio(self):
246
224
  """Daughter ratio.
247
225
 
248
- The function returns the ratio between the bigger daughter and
249
- the other one. A daughter is the next immediate compartment
250
- connected to a bifurcation point.
226
+ The function returns the ratio between the bigger daughter and the other one. A
227
+ daughter is the next immediate compartment connected to a bifurcation point.
251
228
 
252
- See Also
253
- --------
254
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Daughter_Ratio.htm
229
+ See Also:
230
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Daughter_Ratio.htm
255
231
  """
256
232
  raise NotImplementedError()
257
233
 
258
234
  def parent_daughter_ratio(self) -> float:
259
235
  """Parent daughter ratio.
260
236
 
261
- This function returns the ratio between the diameter of a
262
- daughter and its father. One values for each daughter is
263
- returned at each bifurcation point.
237
+ This function returns the ratio between the diameter of a daughter and its
238
+ father. One values for each daughter is returned at each bifurcation point.
264
239
 
265
- See Also
266
- --------
267
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Parent_Daughter_Ratio.htm
240
+ See Also:
241
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Parent_Daughter_Ratio.htm
268
242
  """
269
243
  raise NotImplementedError()
270
244
 
@@ -272,21 +246,17 @@ class LMeasure:
272
246
  """Rall Power.
273
247
 
274
248
  Rall value is computed as the best value that fits the equation
275
- (Bif_Dia)^Rall=(Daughter1_dia^Rall+Daughter2_dia^Rall).
276
- According to Rall’s rule we compute rall’s power by linking the
277
- diameter of two daughter branches to the diameter of the
278
- bifurcating parent. We compute the best fit rall’s power within
279
- the boundary values of [0, 5] at incremental steps of 1000
280
- compartments. The final rall value is the idealistic n value
281
- that can propagate the signal transmission without loss from
282
- the starting point to the terminal point in a cable model
283
- assumption.
249
+ `(Bif_Dia)^Rall=(Daughter1_dia^Rall+Daughter2_dia^Rall)`. According to Rall’s
250
+ rule we compute rall’s power by linking the diameter of two daughter branches
251
+ to the diameter of the bifurcating parent. We compute the best fit rall’s power
252
+ within the boundary values of `[0, 5]` at incremental steps of 1000
253
+ compartments. The final rall value is the idealistic n value that can propagate
254
+ the signal transmission without loss from the starting point to the terminal
255
+ point in a cable model assumption.
284
256
 
285
- See Also
286
- --------
287
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Rall_Power.htm
257
+ See Also:
258
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Rall_Power.htm
288
259
  """
289
-
290
260
  rall_power, _, _, _ = self._rall_power(bif)
291
261
  return rall_power
292
262
 
@@ -310,28 +280,23 @@ class LMeasure:
310
280
  def pk(self, bif: Tree.Node) -> float:
311
281
  """Ratio of rall power increased.
312
282
 
313
- After computing the average value for Rall_Power, this function
314
- returns the ratio of (d1^rall+d2^rall)/(bifurcDiam^rall).
283
+ After computing the average value for Rall_Power, this function returns the
284
+ ratio of `(d1^rall+d2^rall)/(bifurcDiam^rall)`.
315
285
 
316
- See Also
317
- --------
318
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk.htm
286
+ See Also:
287
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk.htm
319
288
  """
320
-
321
289
  rall_power, dp, da, db = self._rall_power(bif)
322
290
  return (da**rall_power + db**rall_power) / dp**rall_power
323
291
 
324
292
  def pk_classic(self, bif: Tree.Node) -> float:
325
293
  """Ratio of rall power increased with fixed rall power 1.5.
326
294
 
327
- This function returns the same value as Pk, but with Rall_Power
328
- sets to 1.5.
295
+ This function returns the same value as Pk, but with `Rall_Power` sets to 1.5.
329
296
 
330
- See Also
331
- --------
332
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk_classic.htm
297
+ See Also:
298
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk_classic.htm
333
299
  """
334
-
335
300
  dp, da, db = self._rall_power_d(bif)
336
301
  rall_power = 1.5
337
302
  return (da**rall_power + db**rall_power) / dp**rall_power
@@ -339,14 +304,11 @@ class LMeasure:
339
304
  def pk_2(self, bif: Tree.Node) -> float:
340
305
  """Ratio of rall power increased with fixed rall power 2.
341
306
 
342
- This function returns the same value as Pk, but with Rall_Power
343
- sets to 2 .
307
+ This function returns the same value as Pk, but with `Rall_Power` sets to 2 .
344
308
 
345
- See Also
346
- --------
347
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk_2.htm
309
+ See Also:
310
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Pk_2.htm
348
311
  """
349
-
350
312
  dp, da, db = self._rall_power_d(bif)
351
313
  rall_power = 2
352
314
  return (da**rall_power + db**rall_power) / dp**rall_power
@@ -354,53 +316,44 @@ class LMeasure:
354
316
  def bif_ampl_local(self, bif: Tree.Node) -> float:
355
317
  """Bifurcation angle.
356
318
 
357
- Given a bifurcation, this function returns the angle between
358
- the first two compartments (in degree).
319
+ Given a bifurcation, this function returns the angle between the first two
320
+ compartments (in degree).
359
321
 
360
- See Also
361
- --------
362
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_ampl_local.htm
322
+ See Also:
323
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_ampl_local.htm
363
324
  """
364
-
365
325
  v1, v2 = self._bif_vector_local(bif)
366
326
  return np.degrees(angle(v1, v2))
367
327
 
368
328
  def bif_ampl_remote(self, bif: Tree.Node) -> float:
369
329
  """Bifurcation angle.
370
330
 
371
- This function returns the angle between two bifurcation points
372
- or between bifurcation point and terminal point or between two
373
- terminal points.
331
+ This function returns the angle between two bifurcation points or between
332
+ bifurcation point and terminal point or between two terminal points.
374
333
 
375
- See Also
376
- --------
377
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_ampl_remote.htm
334
+ See Also:
335
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_ampl_remote.htm
378
336
  """
379
-
380
337
  v1, v2 = self._bif_vector_remote(bif)
381
338
  return np.degrees(angle(v1, v2))
382
339
 
383
340
  def bif_tilt_local(self, bif: Tree.Node) -> float:
384
341
  """Bifuarcation tilt.
385
342
 
386
- This function returns the angle between the previous
387
- compartment of bifurcating father and the two daughter
388
- compartments of the same bifurcation. The smaller of the two
389
- angles is returned as the result.
343
+ This function returns the angle between the previous compartment of bifurcating
344
+ father and the two daughter compartments of the same bifurcation. The smaller
345
+ of the two angles is returned as the result.
390
346
 
391
- Tilt is measured as outer angle between parent and child
392
- compartments. L-Measure returns smaller angle of the two
393
- children, but intuitively this can be viewed as the angle of
394
- deflection of the parent orientation compared to the
347
+ Tilt is measured as outer angle between parent and child compartments.
348
+ L-Measure returns smaller angle of the two children, but intuitively this can
349
+ be viewed as the angle of deflection of the parent orientation compared to the
395
350
  orientation of the mid line of the bifurcation amplitude angle.
396
351
 
397
352
  (i.e.) new tilt(NT) = pi - 1/2 Bif_amp_remote - old tilt(OT)
398
353
 
399
- See Also
400
- --------
401
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_tilt_local.htm
354
+ See Also:
355
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_tilt_local.htm
402
356
  """
403
-
404
357
  parent = bif.parent()
405
358
  assert parent is not None, "Bifurcation tilt is not defined for root"
406
359
  v = parent.xyz() - bif.xyz()
@@ -413,25 +366,21 @@ class LMeasure:
413
366
  def bif_tilt_remote(self, bif: Tree.Node) -> float:
414
367
  """Bifuarcation tilt.
415
368
 
416
- This function returns the angle between the previous father
417
- node of the current bifurcating father and its two daughter
418
- nodes. A node is a terminating point or a bifurcation point or
419
- a root point. Smaller of the two angles is returned as the
420
- result. This angle is not computed for the root node.
369
+ This function returns the angle between the previous father node of the current
370
+ bifurcating father and its two daughter nodes. A node is a terminating point or
371
+ a bifurcation point or a root point. Smaller of the two angles is returned as
372
+ the result. This angle is not computed for the root node.
421
373
 
422
- Tilt is measured as outer angle between parent and child
423
- compartments. L-Measure returns smaller angle of the two
424
- children, but intuitively this can be viewed as the angle of
425
- deflection of the parent orientation compared to the
426
- orientation of the mid line of the bifurcation amplitude angle.
374
+ Tilt is measured as outer angle between parent and child compartments. L-Measure
375
+ returns smaller angle of the two children, but intuitively this can be viewed as
376
+ the angle of deflection of the parent orientation compared to the orientation of
377
+ the mid line of the bifurcation amplitude angle.
427
378
 
428
379
  (i.e.) new tilt(NT) = pi - 1/2 Bif_amp_remote - old tilt(OT)
429
380
 
430
- See Also
431
- --------
432
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_tilt_remote.htm
381
+ See Also:
382
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_tilt_remote.htm
433
383
  """
434
-
435
384
  parent = bif.parent()
436
385
  assert parent is not None, "Bifurcation tilt is not defined for root"
437
386
  v = parent.xyz() - bif.xyz()
@@ -444,27 +393,22 @@ class LMeasure:
444
393
  def bif_torque_local(self, bif: Tree.Node) -> float:
445
394
  """Bifurcation torque.
446
395
 
447
- This function returns the angle between the plane of previous
448
- bifurcation and the current bifurcation. Bifurcation plane is
449
- identified by the two daughter compartments leaving the
450
- bifurcation.
396
+ This function returns the angle between the plane of previous bifurcation and
397
+ the current bifurcation. Bifurcation plane is identified by the two daughter
398
+ compartments leaving the bifurcation.
451
399
 
452
- A torque is the inner angle measured between two planes
453
- (current & parent) of bifurcations. Plane DCE has current
454
- bifurcation and plane CAB has parent bifurcation. Although LM
455
- returns the absolute angle between CAB and DCE as the result,
456
- it must be noted that intuitively what we are measuring is
457
- relative change in the angle of second plane (DCE) with respect
458
- to the first plane (CAB). Therefore, angles > 90 degrees should
459
- be considered as pi - angle.
400
+ A torque is the inner angle measured between two planes (current & parent) of
401
+ bifurcations. Plane DCE has current bifurcation and plane CAB has parent
402
+ bifurcation. Although LM returns the absolute angle between CAB and DCE as the
403
+ result, it must be noted that intuitively what we are measuring is relative
404
+ change in the angle of second plane (DCE) with respect to the first plane (CAB).
405
+ Therefore, angles > 90 degrees should be considered as pi - angle.
460
406
 
461
407
  i.e. in Example1 tilt = 30deg. and in Example2 tilt = 180-110 = 70deg.
462
408
 
463
- See Also
464
- --------
465
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_torque_local.htm
409
+ See Also:
410
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_torque_local.htm
466
411
  """
467
-
468
412
  parent = bif.parent()
469
413
  assert parent is not None, "Bifurcation torque is not defined for root"
470
414
  idx = parent.branch().origin_id()[0]
@@ -480,29 +424,24 @@ class LMeasure:
480
424
  def bif_torque_remote(self, bif: Tree.Node) -> float:
481
425
  """Bifurcation torque.
482
426
 
483
- This function returns the angle between, current plane of
484
- bifurcation and previous plane of bifurcation. This is a
485
- bifurcation level metric and from the figure, the current
486
- plane of bifurcation is formed between C D and E where all
487
- three are bifurcation points and the previous plane is formed
488
- between A B and C bifurcation points.
489
-
490
- A torque is the inner angle measured between two planes
491
- (current & parent) of bifurcations. Plane DCE has current
492
- bifurcation and plane CAB has parent bifurcation. Although LM
493
- returns the absolute angle between CAB and DCE as the result,
494
- it must be noted that intuitively what we are measuring is
495
- relative change in the angle of second plane (DCE) with respect
496
- to the first plane (CAB). Therefore, angles > 90 degrees should
497
- be considered as pi - angle.
427
+ This function returns the angle between, current plane of bifurcation and
428
+ previous plane of bifurcation. This is a bifurcation level metric and from the
429
+ figure, the current plane of bifurcation is formed between C D and E where all
430
+ three are bifurcation points and the previous plane is formed between A B and
431
+ C bifurcation points.
432
+
433
+ A torque is the inner angle measured between two planes (current & parent) of
434
+ bifurcations. Plane DCE has current bifurcation and plane CAB has parent
435
+ bifurcation. Although LM returns the absolute angle between CAB and DCE as the
436
+ result, it must be noted that intuitively what we are measuring is relative
437
+ change in the angle of second plane (DCE) with respect to the first plane (CAB).
438
+ Therefore, angles > 90 degrees should be considered as pi - angle.
498
439
 
499
440
  i.e. in Example1 tilt = 30deg. and in Example2 tilt = 180-110 = 70deg.
500
441
 
501
- See Also
502
- --------
503
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_torque_remote.htm
442
+ See Also:
443
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Bif_torque_remote.htm
504
444
  """
505
-
506
445
  parent = bif.parent()
507
446
  assert parent is not None, "Bifurcation torque is not defined for root"
508
447
  idx = parent.branch().origin_id()[0]
@@ -538,12 +477,10 @@ class LMeasure:
538
477
  def last_parent_diam(self, branch: Branch) -> float:
539
478
  """The diameter of last bifurcation before the terminal tips.
540
479
 
541
- This function returns the diameter of last bifurcation before
542
- the terminal tips.
480
+ This function returns the diameter of last bifurcation before the terminal tips.
543
481
 
544
- See Also
545
- --------
546
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Last_parent_diam.htm
482
+ See Also:
483
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Last_parent_diam.htm
547
484
  """
548
485
 
549
486
  raise NotImplementedError()
@@ -551,27 +488,23 @@ class LMeasure:
551
488
  def diam_threshold(self, branch: Branch) -> float:
552
489
  """
553
490
 
554
- This function returns Diameter of first compartment after the
555
- last bifurcation leading to a terminal tip.
491
+ This function returns Diameter of first compartment after the last bifurcation
492
+ leading to a terminal tip.
556
493
 
557
- See Also
558
- --------
559
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Diam_threshold.htm
494
+ See Also:
495
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Diam_threshold.htm
560
496
  """
561
-
562
497
  raise NotImplementedError()
563
498
 
564
499
  def hillman_threshold(self, branch: Branch) -> float:
565
500
  """Hillman Threshold.
566
501
 
567
- Computes the weighted average between 50% of father and 25% of
568
- daughter diameters of the terminal bifurcation.
502
+ Computes the weighted average between 50% of father and 25% of daughter
503
+ diameters of the terminal bifurcation.
569
504
 
570
- See Also
571
- --------
572
- L-Measure: http://cng.gmu.edu:8080/Lm/help/HillmanThreshold.htm
505
+ See Also:
506
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/HillmanThreshold.htm
573
507
  """
574
-
575
508
  raise NotImplementedError()
576
509
 
577
510
  # Compartment level geometrical measurements
@@ -579,41 +512,35 @@ class LMeasure:
579
512
  def diameter(self, node: Node) -> float:
580
513
  """This function returns diameter of each compartment the neuron.
581
514
 
582
- See Also
583
- --------
584
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Diameter.htm
515
+ See Also:
516
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Diameter.htm
585
517
  """
586
-
587
518
  return 2 * node.r
588
519
 
589
520
  def diameter_pow(self, node: Node) -> float:
590
521
  """Computes the diameter raised to the power 1.5 for each compartment.
591
522
 
592
- See Also
593
- --------
594
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Diameter_pow.htm
523
+ See Also:
524
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Diameter_pow.htm
595
525
  """
596
-
597
526
  return self.diameter(node) ** 1.5
598
527
 
599
528
  def length(self, compartment: Compartment) -> float:
600
529
  """Length of the compartment.
601
530
 
602
- This function returns the length of compartments by computing
603
- the distance between the two end points of a compartment.
531
+ This function returns the length of compartments by computing the distance
532
+ between the two end points of a compartment.
604
533
 
605
- See Also
606
- --------
607
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Length.htm
534
+ See Also:
535
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Length.htm
608
536
  """
609
537
  return compartment.length()
610
538
 
611
539
  def surface(self, compartment: Compartment) -> float:
612
540
  """This function returns surface of the compartment.
613
541
 
614
- See Also
615
- --------
616
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Surface.htm
542
+ See Also:
543
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Surface.htm
617
544
  """
618
545
  p = compartment[self.compartment_point]
619
546
  return cylinder_side_surface_area(p.r, compartment.length())
@@ -621,18 +548,16 @@ class LMeasure:
621
548
  def section_area(self, node: Node) -> float:
622
549
  """This function returns the SectionArea of the compartment.
623
550
 
624
- See Also
625
- --------
626
- L-Measure: http://cng.gmu.edu:8080/Lm/help/SectionArea.htm
551
+ See Also:
552
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/SectionArea.htm
627
553
  """
628
554
  return circle_area(node.r)
629
555
 
630
556
  def volume(self, compartment: Compartment) -> float:
631
557
  """This function returns the volume of the compartment.
632
558
 
633
- See Also
634
- --------
635
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Volume.htm
559
+ See Also:
560
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Volume.htm
636
561
  """
637
562
  p = compartment[self.compartment_point]
638
563
  return cylinder_volume(p.r, compartment.length())
@@ -640,12 +565,11 @@ class LMeasure:
640
565
  def euc_distance(self, node: Tree.Node) -> float:
641
566
  """Euclidean distance from compartment to soma.
642
567
 
643
- This function returns the Euclidean distance of a compartment
644
- with respect to soma.
568
+ This function returns the Euclidean distance of a compartment with respect to
569
+ soma.
645
570
 
646
- See Also
647
- --------
648
- L-Measure: http://cng.gmu.edu:8080/Lm/help/EucDistance.htm
571
+ See Also:
572
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/EucDistance.htm
649
573
  """
650
574
 
651
575
  soma = node.attach.soma()
@@ -656,11 +580,9 @@ class LMeasure:
656
580
 
657
581
  This function returns the PathDistance of a compartment.
658
582
 
659
- See Also
660
- --------
661
- L-Measure: http://cng.gmu.edu:8080/Lm/help/PathDistance.htm
583
+ See Also:
584
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/PathDistance.htm
662
585
  """
663
-
664
586
  n = node
665
587
  length = 0
666
588
  while (parent := n.parent()) is not None:
@@ -673,11 +595,9 @@ class LMeasure:
673
595
 
674
596
  This function returns the order of the branch with respect to soma.
675
597
 
676
- See Also
677
- --------
678
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Branch_Order.htm
598
+ See Also:
599
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Branch_Order.htm
679
600
  """
680
-
681
601
  n = node
682
602
  order = 0
683
603
  while n is not None:
@@ -687,30 +607,26 @@ class LMeasure:
687
607
  return order
688
608
 
689
609
  def terminal_degree(self, node: Tree.Node) -> int:
690
- """The number of tips of the comparment.
610
+ """The number of tips of the compartment.
691
611
 
692
- This function gives the total number of tips that each
693
- compartment will terminate into.
612
+ This function gives the total number of tips that each compartment will
613
+ terminate into.
694
614
 
695
- See Also
696
- --------
697
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Terminal_degree.htm
615
+ See Also:
616
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Terminal_degree.htm
698
617
  """
699
-
700
618
  return len(node.subtree().get_tips())
701
619
 
702
620
  def helix(self, compartment: Tree.Compartment) -> float:
703
621
  """Helix of the compartment.
704
622
 
705
- The function computes the helix by choosing the 3 segments at a
706
- time (or four points at a time) and computes the normal form on
707
- the 3 vectors to find the 4th vector.
623
+ The function computes the helix by choosing the 3 segments at a time (or four
624
+ points at a time) and computes the normal form on the 3 vectors to find the 4th
625
+ vector.
708
626
 
709
- See Also
710
- --------
711
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Helix.htm
627
+ See Also:
628
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Helix.htm
712
629
  """
713
-
714
630
  n1 = compartment.attach.node(compartment.origin_id()[0])
715
631
  n2 = compartment.attach.node(compartment.origin_id()[1])
716
632
  parent = n1.parent()
@@ -730,42 +646,36 @@ class LMeasure:
730
646
  def width(self, tree: Tree) -> float:
731
647
  """With of the neuron.
732
648
 
733
- Width is computed on the x-coordinates and it is the difference
734
- of minimum and maximum x-values after eliminating the outer
735
- points on the either ends by using the 95% approximation of the
736
- x-values of the given input neuron.
649
+ Width is computed on the x-coordinates and it is the difference of minimum and
650
+ maximum x-values after eliminating the outer points on the either ends by using
651
+ the 95% approximation of the x-values of the given input neuron.
737
652
 
738
- See Also
739
- --------
740
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Width.htm
653
+ See Also:
654
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Width.htm
741
655
  """
742
656
  return max_filtered_difference(tree.x(), 95)
743
657
 
744
658
  def height(self, tree: Tree) -> float:
745
659
  """Height of the neuron.
746
660
 
747
- Height is computed on the y-coordinates and it is the
748
- difference of minimum and maximum y-values after eliminating
749
- the outer points on the either ends by using the 95%
750
- approximation of the y-values of the given input neuron.
661
+ Height is computed on the y-coordinates and it is the difference of minimum and
662
+ maximum y-values after eliminating the outer points on the either ends by using
663
+ the 95% approximation of the y-values of the given input neuron.
751
664
 
752
- See Also
753
- --------
754
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Height.htm
665
+ See Also:
666
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Height.htm
755
667
  """
756
668
  return max_filtered_difference(tree.y(), 95)
757
669
 
758
670
  def depth(self, tree: Tree) -> float:
759
671
  """Depth of the neuron.
760
672
 
761
- Depth is computed on the x-coordinates and it is the difference
762
- of minimum and maximum x-values after eliminating the outer
763
- points on the either ends by using the 95% approximation of the
764
- x-values of the given input neuron.
673
+ Depth is computed on the x-coordinates and it is the difference of minimum and
674
+ maximum x-values after eliminating the outer points on the either ends by using
675
+ the 95% approximation of the x-values of the given input neuron.
765
676
 
766
- See Also
767
- --------
768
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Depth.htm
677
+ See Also:
678
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Depth.htm
769
679
  """
770
680
  return max_filtered_difference(tree.z(), 95)
771
681
 
@@ -774,29 +684,25 @@ class LMeasure:
774
684
  def soma_surface(self, tree: Tree) -> float:
775
685
  """Soma surface area.
776
686
 
777
- This function computes the surface of the soma (Type=1). If the
778
- soma is composed of just one compartment, then it uses the
779
- sphere assumption, otherwise it returns the sum of the external
780
- cylindrical surfaces of compartments forming the soma. There
781
- can be multiple soma's, one soma or no soma at all.
687
+ This function computes the surface of the soma (Type=1). If the soma is
688
+ composed of just one compartment, then it uses the sphere assumption, otherwise
689
+ it returns the sum of the external cylindrical surfaces of compartments forming
690
+ the soma. There can be multiple soma's, one soma or no soma at all.
782
691
 
783
- See Also
784
- --------
785
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Soma_Surface.htm
692
+ See Also:
693
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Soma_Surface.htm
786
694
  """
787
695
  return sphere_surface_area(tree.soma().r) # TODO: handle multiple soma
788
696
 
789
697
  def type(self):
790
698
  """The type of compartment.
791
699
 
792
- This function returns type of compartment. Each compartment of
793
- the neuron is of a particular type; soma = 1, axon = 2, basal
794
- dendrites = 3, apical dendrites= 4. The type values are
795
- assigned directly from the given input neuron.
700
+ This function returns type of compartment. Each compartment of the neuron is of
701
+ a particular type; soma = 1, axon = 2, basal dendrites = 3, apical dendrites= 4.
702
+ The type values are assigned directly from the given input neuron.
796
703
 
797
- See Also
798
- --------
799
- L-Measure: http://cng.gmu.edu:8080/Lm/help/Type.htm
704
+ See Also:
705
+ L-Measure: http://cng.gmu.edu:8080/Lm/help/Type.htm
800
706
  """
801
707
  raise NotImplementedError()
802
708
 
@@ -841,10 +747,8 @@ def pill_surface_area(ra: float, rb: float, h: float) -> float:
841
747
  def angle(a: npt.ArrayLike, b: npt.ArrayLike) -> float:
842
748
  """Get the angle of vectors.
843
749
 
844
- Returns
845
- -------
846
- angle : float
847
- Angle [0, PI) in radians.
750
+ Returns:
751
+ angle: Angle [0, PI) in radians.
848
752
  """
849
753
 
850
754
  a, b = np.array(a), np.array(b)