From 282d1eeea888805c04d1c35990715975466bf3cb Mon Sep 17 00:00:00 2001
From: w-klijn <w.f.a.klijn@gmail.com>
Date: Fri, 28 Apr 2017 10:04:47 +0200
Subject: [PATCH] Issue/238 get cell kind (#240)

* Add cell-kind function on the cell_group
* Move the cell_kind to common types
* Have the cell also return its kind when requested
---
 miniapp/miniapp_recipes.cpp       | 5 +++++
 src/cell.hpp                      | 5 +++++
 src/cell_group.hpp                | 2 ++
 src/common_types.hpp              | 7 +++++++
 src/mc_cell_group.hpp             | 6 +++++-
 src/recipe.hpp                    | 6 ++++++
 tests/unit/test_cell.cpp          | 9 +++++++++
 tests/unit/test_mc_cell_group.cpp | 8 ++++++++
 8 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/miniapp/miniapp_recipes.cpp b/miniapp/miniapp_recipes.cpp
index 88474975..0aa559a5 100644
--- a/miniapp/miniapp_recipes.cpp
+++ b/miniapp/miniapp_recipes.cpp
@@ -111,6 +111,11 @@ public:
         return cell;
     }
 
+    cell_kind get_cell_kind(cell_gid_type) const override {
+        // The basic_cell_recipe only produces mc cells, so return cable1d_neuron for now
+        return cell_kind::cable1d_neuron;
+    }
+
     cell_count_info get_cell_count_info(cell_gid_type i) const override {
         cell_count_info cc = {1, param_.num_synapses, 0 };
         unsigned cell_segments = get_morphology(i).components();
diff --git a/src/cell.hpp b/src/cell.hpp
index 0c2bdd13..40a49b51 100644
--- a/src/cell.hpp
+++ b/src/cell.hpp
@@ -99,6 +99,11 @@ public:
          }
      }
 
+    /// Return the kind of cell, used for grouping into cell_groups
+    cell_kind const get_cell_kind() const  {
+        return cell_kind::cable1d_neuron;
+    }
+
     /// add a soma to the cell
     /// radius must be specified
     soma_segment* add_soma(value_type radius, point_type center=point_type());
diff --git a/src/cell_group.hpp b/src/cell_group.hpp
index e6153024..9f5dc595 100644
--- a/src/cell_group.hpp
+++ b/src/cell_group.hpp
@@ -18,6 +18,8 @@ class cell_group {
 public:
     virtual ~cell_group() = default;
 
+    virtual cell_kind const get_cell_kind() const = 0;
+
     virtual void reset() = 0;
     virtual void set_binning_policy(binning_kind policy, time_type bin_interval) = 0;
     virtual void advance(time_type tfinal, time_type dt) = 0;
diff --git a/src/common_types.hpp b/src/common_types.hpp
index c6731a2b..81c7dbe8 100644
--- a/src/common_types.hpp
+++ b/src/common_types.hpp
@@ -53,6 +53,13 @@ DEFINE_LEXICOGRAPHIC_ORDERING(cell_member_type,(a.gid,a.index),(b.gid,b.index))
 
 using time_type = float;
 
+// Enumeration used to indentify the cell type/kind, used by the model to
+// group equal kinds in the same cell group.
+
+enum cell_kind {
+    cable1d_neuron           // Our own special mc neuron
+};
+
 } // namespace mc
 } // namespace nest
 
diff --git a/src/mc_cell_group.hpp b/src/mc_cell_group.hpp
index ec3cbc72..d198a5b7 100644
--- a/src/mc_cell_group.hpp
+++ b/src/mc_cell_group.hpp
@@ -11,6 +11,7 @@
 #include <common_types.hpp>
 #include <event_binner.hpp>
 #include <event_queue.hpp>
+#include <recipe.hpp>
 #include <sampler_function.hpp>
 #include <spike.hpp>
 #include <util/debug.hpp>
@@ -60,6 +61,10 @@ public:
         EXPECTS(spike_sources_.size()==n_detectors);
     }
 
+    cell_kind const get_cell_kind() const override {
+        return cell_kind::cable1d_neuron;
+    }
+
     void reset() override {
         spikes_.clear();
         events_.clear();
@@ -173,7 +178,6 @@ public:
     }
 
 private:
-
     // gid of first cell in group.
     cell_gid_type gid_base_;
 
diff --git a/src/recipe.hpp b/src/recipe.hpp
index fbc78656..f64c7992 100644
--- a/src/recipe.hpp
+++ b/src/recipe.hpp
@@ -46,6 +46,8 @@ public:
     virtual cell_size_type num_cells() const =0;
 
     virtual cell get_cell(cell_gid_type) const =0;
+    virtual cell_kind get_cell_kind(cell_gid_type) const = 0;
+
     virtual cell_count_info get_cell_count_info(cell_gid_type) const =0;
     virtual std::vector<cell_connection> connections_on(cell_gid_type) const =0;
 };
@@ -69,6 +71,10 @@ public:
         return cell(clone_cell, cell_);
     }
 
+    cell_kind get_cell_kind(cell_gid_type) const override {
+        return cell_.get_cell_kind();
+    }
+
     cell_count_info get_cell_count_info(cell_gid_type) const override {
         cell_count_info k;
         k.num_sources = cell_.detectors().size();
diff --git a/tests/unit/test_cell.cpp b/tests/unit/test_cell.cpp
index e08c0650..f36a62f6 100644
--- a/tests/unit/test_cell.cpp
+++ b/tests/unit/test_cell.cpp
@@ -220,3 +220,12 @@ TEST(cell_type, clone)
     EXPECT_NE(c.segment(1)->num_compartments(), d.segment(1)->num_compartments());
     EXPECT_EQ(c.segment(2)->num_compartments(), d.segment(2)->num_compartments());
 }
+
+TEST(cell_type, get_kind)
+{
+    using namespace nest::mc;
+
+    // make a MC cell
+    cell c;
+    EXPECT_EQ( cell_kind::cable1d_neuron, c.get_cell_kind());
+}
diff --git a/tests/unit/test_mc_cell_group.cpp b/tests/unit/test_mc_cell_group.cpp
index 00491537..75c6d355 100644
--- a/tests/unit/test_mc_cell_group.cpp
+++ b/tests/unit/test_mc_cell_group.cpp
@@ -21,6 +21,14 @@ cell make_cell() {
     return c;
 }
 
+
+TEST(mc_cell_group, get_kind) {
+    mc_cell_group<fvm_cell> group{ 0, util::singleton_view(make_cell()) };
+
+    // we are generating a mc_cell_group which should be of the correct type
+    EXPECT_EQ(cell_kind::cable1d_neuron, group.get_cell_kind());
+}
+
 TEST(mc_cell_group, test) {
     mc_cell_group<fvm_cell> group{0, util::singleton_view(make_cell())};
 
-- 
GitLab