Skip to content
Snippets Groups Projects
Unverified Commit a62d3e81 authored by Sam Yates's avatar Sam Yates Committed by GitHub
Browse files

Add test for correct delivery of events to individual cells in mc_cell_group. (#684)

* Add unit test for event delivery pathing.
* Temporarily disable GJ-specific test pending GJ PR.
parent 2e36621d
No related branches found
No related tags found
No related merge requests found
......@@ -63,6 +63,7 @@ set(unit_sources
test_domain_decomposition.cpp
test_either.cpp
test_event_binner.cpp
test_event_delivery.cpp
test_event_generators.cpp
test_event_queue.cpp
test_filter.cpp
......
// Check that events are routed correctly to underlying cell implementations.
//
// Model:
// * N identical cells, one synapse and gap junction site each.
// * Set up dynamics so that one incoming spike generates one outgoing spike.
// * Inject events one per cell in a given order, and confirm generated spikes
// are in the same order.
// Note: this test anticipates the gap junction PR; the #if guards below
// will be removed when that PR is merged.
#define NO_GJ_YET
#include <arbor/common_types.hpp>
#include <arbor/domain_decomposition.hpp>
#include <arbor/simulation.hpp>
#include <arbor/mc_cell.hpp>
#include <arbor/spike.hpp>
#include <arbor/spike_event.hpp>
#include "util/rangeutil.hpp"
#include "util/transform.hpp"
#include "../simple_recipes.hpp"
#include "../gtest.h"
using namespace arb;
using n_mc_cell_recipe = homogeneous_recipe<cell_kind::cable1d_neuron, mc_cell>;
struct test_recipe: public n_mc_cell_recipe {
explicit test_recipe(int n): n_mc_cell_recipe(n, test_cell()) {}
static mc_cell test_cell() {
mc_cell c;
c.add_soma(10.)->add_mechanism("pas");
c.add_synapse({0, 0.5}, "expsyn");
c.add_detector({0, 0.5}, -64);
#ifndef NO_GJ_YET
c.add_gap_junction({0, 0.5});
#endif
return c;
}
cell_size_type num_sources(cell_gid_type) const override { return 1; }
cell_size_type num_targets(cell_gid_type) const override { return 1; }
};
using gid_vector = std::vector<cell_gid_type>;
using group_gids_type = std::vector<gid_vector>;
std::vector<cell_gid_type> run_test_sim(const recipe& R, const group_gids_type& group_gids) {
arb::context ctx = make_context(proc_allocation{});
unsigned n = R.num_cells();
domain_decomposition D;
D.gid_domain = [](cell_gid_type) { return 0; };
D.num_domains = 1;
D.num_local_cells = n;
D.num_global_cells = n;
for (const auto& gidvec: group_gids) {
group_description group{cell_kind::cable1d_neuron, gidvec, backend_kind::multicore};
D.groups.push_back(group);
}
std::vector<spike> spikes;
simulation sim(R, D, ctx);
sim.set_global_spike_callback(
[&spikes](const std::vector<spike>& ss) {
spikes.insert(spikes.end(), ss.begin(), ss.end());
});
constexpr time_type ev_delta_t = 0.2;
pse_vector cell_events;
for (unsigned i = 0; i<n; ++i) {
cell_events.push_back({{i, 0u}, i*ev_delta_t, 1.f});
}
sim.inject_events(cell_events);
sim.run((n+1)*ev_delta_t, 0.01);
std::vector<cell_gid_type> spike_gids;
util::sort_by(spikes, [](auto s) { return s.time; });
util::assign(spike_gids, util::transform_view(spikes, [](auto s) { return s.source.gid; }));
return spike_gids;
}
TEST(mc_event_delivery, one_cell_per_group) {
gid_vector spike_gids = run_test_sim(test_recipe(10), {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}});
EXPECT_EQ((gid_vector{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), spike_gids);
}
TEST(mc_event_delivery, two_interleaved_groups) {
gid_vector spike_gids = run_test_sim(test_recipe(10), {{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}});
EXPECT_EQ((gid_vector{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), spike_gids);
}
#ifndef NO_GJ_YET
typedef std::vector<std::pair<unsigned, unsigned>> cell_gj_pairs;
struct test_recipe_gj: public test_recipe {
explicit test_recipe_gj(int n, cell_gj_pairs gj_pairs):
test_recipe(n), gj_pairs_(std::move(gj_pairs)) {}
cell_size_type num_gap_junctions(cell_gid_type) const override { return 1; }
std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type i) const override {
std::vector<gap_junction_connection> gjs;
for (auto p: gj_pairs_) {
if (p.first == i || p.second == i) gjs.push_back({{p.first, 0u}, {p.second, 0u}, 0.});
}
return gjs;
}
cell_gj_pairs gj_pairs_;
};
TEST(mc_event_delivery, gj_reordered) {
test_recipe_gj R(5, {{1u, 3u}, {2u, 4u}});
gid_vector spike_gids = run_test_sim(R, {{0, 1, 2, 3, 4}});
EXPECT_EQ((gid_vector{0, 1, 2, 3, 4}), spike_gids);
}
#endif // ndef NO_GJ_YET
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment