Repository: BlueBrain/NeuroM

Issue:
Is `partition_asymmetry` with `Uylings` variant usable?
I find peculiar the implementation of the **Uylings variant** of for the partition asymmetry:

https://github.com/BlueBrain/NeuroM/blob/127d6fd45167b3cf2ae6d41c51ad241846d082dc/neurom/features/bifurcation.py#L102-L124

because all bifurcation points the children of which are leaves will have downstream counts `n,m = (1, 1)`, therefore all morphs would fail the check.

Am I missing a use case where this could work?

@mgeplf @lidakanari @arnaudon @adrien-berchet 

Discussion:
codecov-commenter: # [Codecov](https://codecov.io/gh/BlueBrain/NeuroM/pull/1001?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BlueBrain) Report
> Merging [#1001](https://codecov.io/gh/BlueBrain/NeuroM/pull/1001?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BlueBrain) (432948c) into [master](https://codecov.io/gh/BlueBrain/NeuroM/commit/127d6fd45167b3cf2ae6d41c51ad241846d082dc?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BlueBrain) (127d6fd) will **not change** coverage.
> The diff coverage is `100.00%`.



```diff
@@            Coverage Diff            @@
##            master     #1001   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           36        36           
  Lines         2351      2349    -2     
=========================================
- Hits          2351      2349    -2     
```


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index de024a1..4d0b572 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -3,6 +3,15 @@ Changelog
 
 Version 3.2.0
 -------------
+
+- Fix ``neurom.features.bifurcation.partition_asymmetry`` Uylings variant to not throw
+  for bifurcations with leaves.
+- Fix ``neurom.features.neurite.principal_direction_extents`` to remove duplicate points
+  when calculated.
+- Add ``neurom.features.morphology.volume_density`` feature so that it is calculated
+  correctly when the entire morphology is taken into account instead of summing the per
+  neurite volume densities.
+- Add support for py39 and py310 testing.
 - Fix ``neurom.features.morphology.sholl_frequency`` to return an empty list when a
   neurite_type that is not present in the morphology is specified.
 - Fix ``neurom.features.morphology.trunk_origin_radii`` to warn and use only the root
diff --git a/neurom/features/bifurcation.py b/neurom/features/bifurcation.py
index 65db001..6c628d1 100644
--- a/neurom/features/bifurcation.py
+++ b/neurom/features/bifurcation.py
@@ -115,12 +115,13 @@ def partition_asymmetry(bif_point, uylings=False):
 
     n = float(sum(1 for _ in bif_point.children[0].ipreorder()))
     m = float(sum(1 for _ in bif_point.children[1].ipreorder()))
-    c = 0
-    if uylings:
-        c = 2
-        if n + m <= c:
-            raise NeuroMError('Partition asymmetry cant be calculated by Uylings because the sum of'
-                              'terminal tips is less than 2.')
+
+    if n == m == 1:
+        # By definition the asymmetry A(1, 1) is zero
+        return 0.0
+
+    c = 2.0 if uylings else 0.0
+
     return abs(n - m) / abs(n + m - c)
 
 


Test patch:
diff --git a/tests/features/test_bifurcation.py b/tests/features/test_bifurcation.py
index 530a4c4..f2eea4c 100644
--- a/tests/features/test_bifurcation.py
+++ b/tests/features/test_bifurcation.py
@@ -80,8 +80,7 @@ def test_partition_asymmetry():
     assert bf.partition_asymmetry(root) == 0.5
     assert bf.partition_asymmetry(root.children[0]) == 0.0
     assert bf.partition_asymmetry(root, True) == 1.0
-    with pytest.raises(NeuroMError, match='Uylings'):
-        bf.partition_asymmetry(root.children[0], True)
+    assert bf.partition_asymmetry(root.children[0], True) == 0.0
 
     leaf = root.children[0].children[0]
     assert_raises(NeuroMError, bf.partition_asymmetry, leaf)