From f12f934f365d9e68f01bfd857982be80da2ddd10 Mon Sep 17 00:00:00 2001
From: Ben Cumming <bcumming@cscs.ch>
Date: Wed, 19 Feb 2020 20:48:49 +0100
Subject: [PATCH] ability to query cable_cell for cable segments that define a
 region (#961)

Add `cable_cell::concrete_region(region)` method that returns a the cable segments in a region.

This is required by the Arbor GUI #953 so that it can illustrate regions (and locsets) defined by users on a concrete cell morphology.

Note that the `concrete_region` and `concrete_locset` interfaces will need to be extended with random number seed information when we add full support for that, but shouldn't need to be replaced or changed otherwise.

Fixes #960.
---
 arbor/cable_cell.cpp               | 14 +++++++++++---
 arbor/include/arbor/cable_cell.hpp |  5 ++++-
 python/cells.cpp                   |  5 ++++-
 python/example/single_cell_swc.py  |  4 ++--
 python/single_cell_model.cpp       |  2 +-
 5 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/arbor/cable_cell.cpp b/arbor/cable_cell.cpp
index 462c5602..2ec43f27 100644
--- a/arbor/cable_cell.cpp
+++ b/arbor/cable_cell.cpp
@@ -104,9 +104,13 @@ struct cable_cell_impl {
         }
     }
 
-    mlocation_list locations(const locset& l) const {
+    mlocation_list concrete_locset(const locset& l) const {
         return thingify(l, provider);
     }
+
+    mcable_list concrete_region(const region& r) const {
+        return thingify(r, provider);
+    }
 };
 
 using impl_ptr = std::unique_ptr<cable_cell_impl, void (*)(cable_cell_impl*)>;
@@ -137,8 +141,12 @@ const mprovider& cable_cell::provider() const {
     return impl_->provider;
 }
 
-mlocation_list cable_cell::locations(const locset& l) const {
-    return impl_->locations(l);
+mlocation_list cable_cell::concrete_locset(const locset& l) const {
+    return impl_->concrete_locset(l);
+}
+
+mcable_list cable_cell::concrete_region(const region& r) const {
+    return impl_->concrete_region(r);
 }
 
 const cable_cell_location_map& cable_cell::location_assignments() const {
diff --git a/arbor/include/arbor/cable_cell.hpp b/arbor/include/arbor/cable_cell.hpp
index e268062a..1a752292 100644
--- a/arbor/include/arbor/cable_cell.hpp
+++ b/arbor/include/arbor/cable_cell.hpp
@@ -179,7 +179,10 @@ public:
     }
 
     // Access to a concrete list of locations for a locset.
-    mlocation_list locations(const locset&) const;
+    mlocation_list concrete_locset(const locset&) const;
+
+    // Access to a concrete list of cable segments for a region.
+    mcable_list concrete_region(const region&) const;
 
     // Generic access to painted and placed items.
     const cable_cell_region_map& region_assignments() const;
diff --git a/python/cells.cpp b/python/cells.cpp
index 10d98efe..852b51a7 100644
--- a/python/cells.cpp
+++ b/python/cells.cpp
@@ -527,8 +527,11 @@ void register_cells(pybind11::module& m) {
             "Add a voltage spike detector at each location in locations.")
         // Get locations associated with a locset label.
         .def("locations",
-            [](arb::cable_cell& c, const char* label) {return c.locations(label);},
+            [](arb::cable_cell& c, const char* label) {return c.concrete_locset(label);},
             "label"_a, "The locations of the cell morphology for a locset label.")
+        .def("region",
+            [](arb::cable_cell& c, const char* label) {return c.concrete_region(label);},
+            "label"_a, "The cable segments of the cell morphology for a region label.")
         // Discretization control.
         .def("compartments_on_samples",
             [](arb::cable_cell& c) {c.default_parameters.discretization = arb::cv_policy_every_sample{};},
diff --git a/python/example/single_cell_swc.py b/python/example/single_cell_swc.py
index 4cdbb9c4..993f6d98 100644
--- a/python/example/single_cell_swc.py
+++ b/python/example/single_cell_swc.py
@@ -9,8 +9,8 @@ tree = arbor.load_swc('../../test/unit/swc/example.swc')
 
 # Define the regions and locsets in the model.
 defs = {'soma': '(tag 1)',  # soma has tag 1 in swc files.
-        'axon': '(tag 2)',  # axon has tag 1 in swc files.
-        'dend': '(tag 3)',  # dendrites have tag 1 in swc files.
+        'axon': '(tag 2)',  # axon has tag 2 in swc files.
+        'dend': '(tag 3)',  # dendrites have tag 3 in swc files.
         'root': '(root)',   # the start of the soma in this morphology is at the root of the cell.
         'stim_site': '(location 1 0.5)'} # site for the stimulus, in the middle of branch 1.
 labels = arbor.label_dict(defs)
diff --git a/python/single_cell_model.cpp b/python/single_cell_model.cpp
index 29d5df5d..249e0325 100644
--- a/python/single_cell_model.cpp
+++ b/python/single_cell_model.cpp
@@ -169,7 +169,7 @@ public:
             throw pyarb_error(
                 util::pprintf("sampling frequency is not greater than zero", what));
         }
-        for (auto& l: cell_.locations(where)) {
+        for (auto& l: cell_.concrete_locset(where)) {
             probes_.push_back({l, frequency});
         }
     }
-- 
GitLab