From 75cdf2f22283e7dc8a39b11e81dd26ee62265d4c Mon Sep 17 00:00:00 2001
From: bcumming <bcumming@cscs.ch>
Date: Tue, 24 May 2016 11:06:09 +0200
Subject: [PATCH] refactor unit tests

---
 src/cell.cpp              |   4 +-
 src/cell.hpp              |   2 +-
 tests/CMakeLists.txt      |   3 +-
 tests/test_fvm.cpp        | 105 +++++++++++++++
 tests/test_parameters.cpp |  42 ++++++
 tests/test_run.cpp        | 265 --------------------------------------
 6 files changed, 152 insertions(+), 269 deletions(-)
 create mode 100644 tests/test_parameters.cpp
 delete mode 100644 tests/test_run.cpp

diff --git a/src/cell.cpp b/src/cell.cpp
index 72bad02a..a6986f06 100644
--- a/src/cell.cpp
+++ b/src/cell.cpp
@@ -155,9 +155,9 @@ std::vector<int> cell::compartment_counts() const
     return comp_count;
 }
 
-int cell::num_compartments() const
+size_t cell::num_compartments() const
 {
-    auto n = 0;
+    auto n = 0u;
     for(auto &s : segments_) {
         n += s->num_compartments();
     }
diff --git a/src/cell.hpp b/src/cell.hpp
index 6e5d95f9..ba5f9b6b 100644
--- a/src/cell.hpp
+++ b/src/cell.hpp
@@ -86,7 +86,7 @@ class cell {
     value_type area() const;
 
     /// the total number of compartments over all segments
-    int num_compartments() const;
+    size_t num_compartments() const;
 
     std::vector<segment_ptr> const& segments() const;
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 11b88107..cb33af4d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -16,10 +16,11 @@ set(TEST_SOURCES
     test_algorithms.cpp
     test_cell.cpp
     test_compartments.cpp
+    test_fvm.cpp
     test_matrix.cpp
     test_mechanisms.cpp
+    test_parameters.cpp
     test_point.cpp
-    test_run.cpp
     test_segment.cpp
     test_stimulus.cpp
     test_swcio.cpp
diff --git a/tests/test_fvm.cpp b/tests/test_fvm.cpp
index e69de29b..85a25f35 100644
--- a/tests/test_fvm.cpp
+++ b/tests/test_fvm.cpp
@@ -0,0 +1,105 @@
+#include <fstream>
+
+#include "gtest.h"
+#include "util.hpp"
+
+#include "../src/cell.hpp"
+#include "../src/fvm.hpp"
+
+TEST(fvm, cable)
+{
+    using namespace nest::mc;
+
+    nest::mc::cell cell;
+
+    // setup global state for the mechanisms
+    nest::mc::mechanisms::setup_mechanism_helpers();
+
+    cell.add_soma(6e-4); // 6um in cm
+
+    // 1um radius and 4mm long, all in cm
+    cell.add_cable(0, segmentKind::dendrite, 1e-4, 1e-4, 4e-1);
+    cell.add_cable(0, segmentKind::dendrite, 1e-4, 1e-4, 4e-1);
+
+    //std::cout << cell.segment(1)->area() << " is the area\n";
+    EXPECT_EQ(cell.model().tree.num_segments(), 3u);
+
+    // add passive to all 3 segments in the cell
+    for(auto& seg :cell.segments()) {
+        seg->add_mechanism(pas_parameters());
+    }
+
+    cell.soma()->add_mechanism(hh_parameters());
+    cell.segment(2)->add_mechanism(hh_parameters());
+
+    auto& soma_hh = cell.soma()->mechanism("hh");
+
+    soma_hh.set("gnabar", 0.12);
+    soma_hh.set("gkbar", 0.036);
+    soma_hh.set("gl", 0.0003);
+    soma_hh.set("el", -54.387);
+
+    cell.segment(1)->set_compartments(4);
+    cell.segment(2)->set_compartments(4);
+
+    using fvm_cell = fvm::fvm_cell<double, int>;
+    fvm_cell fvcell(cell);
+    auto& J = fvcell.jacobian();
+
+    EXPECT_EQ(cell.num_compartments(), 9u);
+
+    // assert that the matrix has one row for each compartment
+    EXPECT_EQ(J.size(), cell.num_compartments());
+
+    fvcell.setup_matrix(0.02);
+
+    // assert that the number of cv areas is the same as the matrix size
+    // i.e. both should equal the number of compartments
+    EXPECT_EQ(fvcell.cv_areas().size(), J.size());
+}
+
+TEST(fvm, init)
+{
+    using namespace nest::mc;
+
+    nest::mc::cell cell;
+
+    // setup global state for the mechanisms
+    nest::mc::mechanisms::setup_mechanism_helpers();
+
+    cell.add_soma(12.6157/2.0);
+    //auto& props = cell.soma()->properties;
+
+    cell.add_cable(0, segmentKind::dendrite, 0.5, 0.5, 200);
+
+    const auto m = cell.model();
+    EXPECT_EQ(m.tree.num_segments(), 2u);
+
+    // in this context (i.e. attached to a segment on a high-level cell)
+    // a mechanism is essentially a set of parameters
+    // - the only "state" is that used to define parameters
+    cell.soma()->add_mechanism(hh_parameters());
+
+    auto& soma_hh = cell.soma()->mechanism("hh");
+
+    soma_hh.set("gnabar", 0.12);
+    soma_hh.set("gkbar", 0.036);
+    soma_hh.set("gl", 0.0003);
+    soma_hh.set("el", -54.3);
+
+    // check that parameter values were set correctly
+    EXPECT_EQ(cell.soma()->mechanism("hh").get("gnabar").value, 0.12);
+    EXPECT_EQ(cell.soma()->mechanism("hh").get("gkbar").value, 0.036);
+    EXPECT_EQ(cell.soma()->mechanism("hh").get("gl").value, 0.0003);
+    EXPECT_EQ(cell.soma()->mechanism("hh").get("el").value, -54.3);
+
+    cell.segment(1)->set_compartments(10);
+
+    using fvm_cell = fvm::fvm_cell<double, int>;
+    fvm_cell fvcell(cell);
+    auto& J = fvcell.jacobian();
+    EXPECT_EQ(J.size(), 11u);
+
+    fvcell.setup_matrix(0.01);
+}
+
diff --git a/tests/test_parameters.cpp b/tests/test_parameters.cpp
new file mode 100644
index 00000000..0dce58b0
--- /dev/null
+++ b/tests/test_parameters.cpp
@@ -0,0 +1,42 @@
+
+#include <fstream>
+
+#include "gtest.h"
+#include "util.hpp"
+
+#include <parameter_list.hpp>
+
+// test out the parameter infrastructure
+TEST(parameters, setting)
+{
+    nest::mc::parameter_list list("test");
+    EXPECT_EQ(list.name(), "test");
+    EXPECT_EQ(list.num_parameters(), 0);
+
+    nest::mc::parameter p("a", 0.12, {0, 10});
+
+    // add_parameter() returns a bool that indicates whether
+    // it was able to successfull add the parameter
+    EXPECT_TRUE(list.add_parameter(std::move(p)));
+    EXPECT_EQ(list.num_parameters(), 1);
+
+    // test in place construction of a parameter
+    EXPECT_TRUE(list.add_parameter({"b", -3.0}));
+    EXPECT_EQ(list.num_parameters(), 2);
+
+    // check that adding a parameter that already exists returns false
+    // and does not increase the number of parameters
+    EXPECT_FALSE(list.add_parameter({"b", -3.0}));
+    EXPECT_EQ(list.num_parameters(), 2);
+
+    auto &parms = list.parameters();
+    EXPECT_EQ(parms[0].name, "a");
+    EXPECT_EQ(parms[0].value, 0.12);
+    EXPECT_EQ(parms[0].range.min, 0);
+    EXPECT_EQ(parms[0].range.max, 10);
+
+    EXPECT_EQ(parms[1].name, "b");
+    EXPECT_EQ(parms[1].value, -3);
+    EXPECT_FALSE(parms[1].range.has_lower_bound());
+    EXPECT_FALSE(parms[1].range.has_upper_bound());
+}
diff --git a/tests/test_run.cpp b/tests/test_run.cpp
deleted file mode 100644
index aa4d9bba..00000000
--- a/tests/test_run.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-#include <fstream>
-
-#include "gtest.h"
-#include "util.hpp"
-
-#include "../src/cell.hpp"
-#include "../src/fvm.hpp"
-
-// based on hh/Neuron/steps_A.py
-TEST(run, single_compartment)
-{
-    using namespace nest::mc;
-
-    std::vector<std::vector<double>> results(2);
-
-    nest::mc::cell cell;
-
-    // setup global state for the mechanisms
-    nest::mc::mechanisms::setup_mechanism_helpers();
-
-    // Soma with diameter 18.8um and HH channel
-    auto soma = cell.add_soma(18.8/2.0);
-    soma->mechanism("membrane").set("r_L", 123); // no effect for single compartment cell
-    soma->add_mechanism(hh_parameters());
-
-    // add stimulus to the soma
-    //cell.add_stimulus({0,0}, {5., 3., 0.1});
-    cell.add_stimulus({0,0.5}, {10., 100., 0.1});
-
-    // make the lowered finite volume cell
-    fvm::fvm_cell<double, int> model(cell);
-
-    // set initial conditions
-    using memory::all;
-    model.voltage()(all) = -65.;
-    model.initialize(); // have to do this _after_ initial conditions are set
-
-    // run the simulation
-    auto dt     =   0.0005; // ms
-    auto tfinal =   120.; // ms
-    int nt = tfinal/dt;
-    results[0].push_back(0.);
-    results[1].push_back(model.voltage()[0]);
-    for(auto i=0; i<nt; ++i) {
-        model.advance(dt);
-        // save voltage at soma
-        results[0].push_back((i+1)*dt);
-        results[1].push_back(model.voltage()[0]);
-    }
-
-    testing::write_vis_file("v.dat", results);
-}
-
-TEST(run, ball_and_stick)
-{
-    using namespace nest::mc;
-
-    std::vector<std::vector<double>> results(3);
-
-    nest::mc::cell cell;
-
-    // setup global state for the mechanisms
-    nest::mc::mechanisms::setup_mechanism_helpers();
-
-    // Soma with diameter 12.6157 um and HH channel
-    auto soma = cell.add_soma(12.6157/2.0);
-    soma->add_mechanism(hh_parameters());
-
-    // add dendrite of length 200 um and diameter 1 um with passive channel
-    auto dendrite = cell.add_cable(0, segmentKind::dendrite, 0.5, 0.5, 200);
-    dendrite->set_compartments(10);
-    dendrite->add_mechanism(pas_parameters());
-
-    dendrite->mechanism("membrane").set("r_L", 100); // no effect for single compartment cell
-
-    // add stimulus
-    //cell.add_stimulus({0,0}, {5., 1., 0.1}); // soma
-    cell.add_stimulus({1,1}, {5., 1., 0.5});
-
-    // make the lowered finite volume cell
-    fvm::fvm_cell<double, int> model(cell);
-
-    std::cout << "CV areas " << model.cv_areas() << "\n";
-
-    // set initial conditions
-    using memory::all;
-    model.voltage()(all) = -65.;
-    model.initialize(); // have to do this _after_ initial conditions are set
-
-    // run the simulation
-    auto pos = model.size()-1;
-    auto dt = 0.001; // ms
-    auto tfinal = 25.; // ms
-    int nt = tfinal/dt;
-    results[0].push_back(0.);
-    results[1].push_back(model.voltage()[0]);
-    results[2].push_back(model.voltage()[pos]);
-    for(auto i=0; i<nt; ++i) {
-        model.advance(dt);
-        results[0].push_back((i+1)*dt);
-        results[1].push_back(model.voltage()[0]);
-        results[2].push_back(model.voltage()[pos]);
-    }
-
-    testing::write_vis_file("v.dat", results);
-}
-
-TEST(run, cable)
-{
-    using namespace nest::mc;
-
-    nest::mc::cell cell;
-
-    // setup global state for the mechanisms
-    nest::mc::mechanisms::setup_mechanism_helpers();
-
-    cell.add_soma(6e-4); // 6um in cm
-
-    // 1um radius and 4mm long, all in cm
-    cell.add_cable(0, segmentKind::dendrite, 1e-4, 1e-4, 4e-1);
-    cell.add_cable(0, segmentKind::dendrite, 1e-4, 1e-4, 4e-1);
-
-    //std::cout << cell.segment(1)->area() << " is the area\n";
-    EXPECT_EQ(cell.model().tree.num_segments(), 3u);
-
-    // add passive to all 3 segments in the cell
-    for(auto& seg :cell.segments()) {
-        seg->add_mechanism(pas_parameters());
-    }
-
-    cell.soma()->add_mechanism(hh_parameters());
-    cell.segment(2)->add_mechanism(hh_parameters());
-
-    auto& soma_hh = cell.soma()->mechanism("hh");
-
-    soma_hh.set("gnabar", 0.12);
-    soma_hh.set("gkbar", 0.036);
-    soma_hh.set("gl", 0.0003);
-    soma_hh.set("el", -54.387);
-
-    cell.segment(1)->set_compartments(4);
-    cell.segment(2)->set_compartments(4);
-
-    using fvm_cell = fvm::fvm_cell<double, int>;
-    fvm_cell fvcell(cell);
-    auto& J = fvcell.jacobian();
-    EXPECT_EQ(J.size(), 9u);
-
-    fvcell.setup_matrix(0.02);
-    EXPECT_EQ(fvcell.cv_areas().size(), J.size());
-
-    // inspect ion channels
-    /*
-    std::cout << "ion na index : " << fvcell.ion_na().node_index() << "\n";
-    std::cout << "ion ca index : " << fvcell.ion_ca().node_index() << "\n";
-    std::cout << "ion k  index : " << fvcell.ion_k().node_index() << "\n";
-
-    std::cout << "ion na E : " << fvcell.ion_na().reversal_potential() << "\n";
-    std::cout << "ion ca E : " << fvcell.ion_ca().reversal_potential() << "\n";
-    std::cout << "ion k  E : " << fvcell.ion_k().reversal_potential() << "\n";
-    */
-
-    //auto& cable_parms = cell.segment(1)->mechanism("membrane");
-    //std::cout << soma_hh << std::endl;
-    //std::cout << cable_parms << std::endl;
-
-    //std::cout << "l " << J.l() << "\n";
-    //std::cout << "d " << J.d() << "\n";
-    //std::cout << "u " << J.u() << "\n";
-    //std::cout << "p " << J.p() << "\n";
-
-    J.rhs()(memory::all) = 1.;
-    J.rhs()[0] = 10.;
-
-    J.solve();
-}
-
-TEST(run, init)
-{
-    using namespace nest::mc;
-
-    nest::mc::cell cell;
-
-    // setup global state for the mechanisms
-    nest::mc::mechanisms::setup_mechanism_helpers();
-
-    cell.add_soma(12.6157/2.0);
-    //auto& props = cell.soma()->properties;
-
-    cell.add_cable(0, segmentKind::dendrite, 0.5, 0.5, 200);
-
-    const auto m = cell.model();
-    EXPECT_EQ(m.tree.num_segments(), 2u);
-
-    // in this context (i.e. attached to a segment on a high-level cell)
-    // a mechanism is essentially a set of parameters
-    // - the only "state" is that used to define parameters
-    cell.soma()->add_mechanism(hh_parameters());
-
-    auto& soma_hh = cell.soma()->mechanism("hh");
-
-    soma_hh.set("gnabar", 0.12);
-    soma_hh.set("gkbar", 0.036);
-    soma_hh.set("gl", 0.0003);
-    soma_hh.set("el", -54.3);
-
-    // check that parameter values were set correctly
-    EXPECT_EQ(cell.soma()->mechanism("hh").get("gnabar").value, 0.12);
-    EXPECT_EQ(cell.soma()->mechanism("hh").get("gkbar").value, 0.036);
-    EXPECT_EQ(cell.soma()->mechanism("hh").get("gl").value, 0.0003);
-    EXPECT_EQ(cell.soma()->mechanism("hh").get("el").value, -54.3);
-
-    cell.segment(1)->set_compartments(10);
-
-    using fvm_cell = fvm::fvm_cell<double, int>;
-    fvm_cell fvcell(cell);
-    auto& J = fvcell.jacobian();
-    EXPECT_EQ(J.size(), 11u);
-
-    fvcell.setup_matrix(0.01);
-    //std::cout << "areas " << fvcell.cv_areas() << "\n";
-
-    J.rhs()(memory::all) = 1.;
-    J.rhs()[0] = 10.;
-
-    J.solve();
-
-    //std::cout << "x" << J.rhs() << "\n";
-}
-
-// test out the parameter infrastructure
-TEST(run, parameters)
-{
-    nest::mc::parameter_list list("test");
-    EXPECT_EQ(list.name(), "test");
-    EXPECT_EQ(list.num_parameters(), 0);
-
-    nest::mc::parameter p("a", 0.12, {0, 10});
-
-    // add_parameter() returns a bool that indicates whether
-    // it was able to successfull add the parameter
-    EXPECT_EQ(list.add_parameter(std::move(p)), true);
-    EXPECT_EQ(list.num_parameters(), 1);
-
-    // test in place construction of a parameter
-    EXPECT_EQ(list.add_parameter({"b", -3.0}), true);
-    EXPECT_EQ(list.num_parameters(), 2);
-
-    // check that adding a parameter that already exists returns false
-    // and does not increase the number of parameters
-    EXPECT_EQ(list.add_parameter({"b", -3.0}), false);
-    EXPECT_EQ(list.num_parameters(), 2);
-
-    auto &parms = list.parameters();
-    EXPECT_EQ(parms[0].name, "a");
-    EXPECT_EQ(parms[0].value, 0.12);
-    EXPECT_EQ(parms[0].range.min, 0);
-    EXPECT_EQ(parms[0].range.max, 10);
-
-    EXPECT_EQ(parms[1].name, "b");
-    EXPECT_EQ(parms[1].value, -3);
-    EXPECT_EQ(parms[1].range.has_lower_bound(), false);
-    EXPECT_EQ(parms[1].range.has_upper_bound(), false);
-}
-
-- 
GitLab