From ab537bb146b8956a2f8779456eb5a2c1d1e81383 Mon Sep 17 00:00:00 2001
From: Sam Yates <halfflat@gmail.com>
Date: Mon, 20 Sep 2021 15:56:49 +0200
Subject: [PATCH] Fix on-components on empty cable bug (#1658)

* Filter results of `ls::on_components(1, reg)` to avoid duplicate or
coincident locations arising from terminal zero-length cables in region
argument.
---
 arbor/morph/locset.cpp        |  5 ++---
 test/unit/test_morph_expr.cpp | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arbor/morph/locset.cpp b/arbor/morph/locset.cpp
index d69616ac..fc2188e1 100644
--- a/arbor/morph/locset.cpp
+++ b/arbor/morph/locset.cpp
@@ -353,7 +353,7 @@ mlocation_list thingify_(const on_components_& n, const mprovider& p) {
         }
         else if (n.relpos==1) {
             double diameter = 0;
-            mlocation_list most_distal = {prox};
+            mlocation_list most_distal;
 
             for (mcable c: comp) {
                 mlocation x = dist_loc(c);
@@ -368,7 +368,7 @@ mlocation_list thingify_(const on_components_& n, const mprovider& p) {
                 }
             }
 
-            util::append(L, most_distal);
+            util::append(L, maxset(p.morphology(), support(most_distal)));
         }
         else {
             double diameter = util::max_value(util::transform_view(comp,
@@ -385,7 +385,6 @@ mlocation_list thingify_(const on_components_& n, const mprovider& p) {
                     L.push_back(mlocation{c.branch, s});
                 }
             }
-
         }
     }
 
diff --git a/test/unit/test_morph_expr.cpp b/test/unit/test_morph_expr.cpp
index 2aebcd16..ccb3d166 100644
--- a/test/unit/test_morph_expr.cpp
+++ b/test/unit/test_morph_expr.cpp
@@ -240,6 +240,26 @@ TEST(locset, thingify) {
         EXPECT_EQ(thingify(oc_end_b02, mp),  (ll{{0, 1}, {2, 1}}));
         EXPECT_EQ(thingify(ls::on_components(0.25, reg::cable(1, 0.5, 1)), mp),  (ll{{1, 0.625}}));
     }
+    {
+        // Regression test for on-components applied to a region with zero-length cables.
+
+        auto mp = mprovider(morphology(sm));
+
+        auto reg1 = join(reg::branch(1), reg::cable(2, 0, 0));
+        auto reg2 = join(reg::cable(2, 0, 0), reg::cable(3, 0.5, 0.5));
+
+        auto l1a = ls::on_components(1., reg1);
+        EXPECT_EQ(thingify(l1a, mp), (ll{{2, 0}}));
+
+        auto l2a = ls::on_components(1., reg2);
+        EXPECT_EQ(thingify(l2a, mp), (ll{{2, 0}, {3, 0.5}}));
+
+        auto l2b = ls::on_components(0.3, reg2);
+        EXPECT_EQ(thingify(l2b, mp), (ll{{2, 0}, {3, 0.5}}));
+
+        auto l2c = ls::on_components(0, reg2);
+        EXPECT_EQ(thingify(l2c, mp), (ll{{2, 0}, {3, 0.5}}));
+    }
     {
         auto mp = mprovider(morphology(sm));
 
-- 
GitLab