From a1894edc929111fe95e3f881eb80dab8e3ba2387 Mon Sep 17 00:00:00 2001 From: Sam Yates <yates@cscs.ch> Date: Tue, 3 Jul 2018 09:39:59 +0200 Subject: [PATCH] Move cell description types to public includes. (#508) Further work to public install target. * Move SIMD classes, cell description classes, simple sampler to public include. * Rename `cell` to `mc_cell`, `segment` to `mc_segment`, and remove `_description` from cell description class names and includes. * Move `compartment_model` out of `mc_cell` interface and use only in `fvm_layout.cpp`. * (Provisionally) remove area/volume methods on `mc_cell` and `mc_segment`. --- arbor/CMakeLists.txt | 2 +- arbor/backends/multicore/multicore_common.hpp | 2 - .../multicore/partition_by_constraint.hpp | 5 +- arbor/backends/multicore/shared_state.cpp | 4 +- arbor/backends/multicore/shared_state.hpp | 4 +- arbor/benchmark_cell_group.cpp | 7 +- arbor/benchmark_cell_group.hpp | 9 +- arbor/cell_group.hpp | 3 +- arbor/cell_group_factory.cpp | 1 - arbor/cell_group_factory.hpp | 11 +- arbor/communication/communicator.hpp | 4 +- arbor/event_generator.hpp | 2 +- .../{compartment.hpp => fvm_compartment.hpp} | 71 +----- arbor/fvm_layout.cpp | 43 +++- arbor/fvm_layout.hpp | 8 +- arbor/fvm_lowered_cell_impl.hpp | 7 +- arbor/lif_cell_group.cpp | 8 +- arbor/lif_cell_group.hpp | 17 +- arbor/{cell.cpp => mc_cell.cpp} | 104 +++------ arbor/mc_cell_group.cpp | 10 +- arbor/mc_cell_group.hpp | 4 +- arbor/mechcat.cpp | 2 +- arbor/merge_events.cpp | 32 +-- arbor/merge_events.hpp | 3 +- arbor/morphology.cpp | 4 +- arbor/partition_load_balance.cpp | 3 +- arbor/recipe.hpp | 3 +- arbor/sampler_map.hpp | 2 +- arbor/simulation.cpp | 23 +- arbor/simulation.hpp | 2 +- arbor/spike_source_cell_group.cpp | 14 +- arbor/spike_source_cell_group.hpp | 7 +- arbor/swcio.cpp | 9 +- arbor/swcio.hpp | 6 +- example/bench/recipe.cpp | 5 +- example/brunel/brunel_miniapp.cpp | 6 +- example/generators/event_gen.cpp | 6 +- example/miniapp/miniapp.cpp | 8 +- example/miniapp/miniapp_recipes.cpp | 12 +- example/miniapp/morphology_pool.cpp | 7 +- example/miniapp/morphology_pool.hpp | 5 +- example/miniapp/trace.hpp | 3 +- {arbor => include/arbor}/benchmark_cell.hpp | 2 +- {arbor => include/arbor}/constants.hpp | 0 .../arbor/lif_cell.hpp | 2 +- arbor/cell.hpp => include/arbor/mc_cell.hpp | 58 ++--- .../arbor/mc_segment.hpp | 121 +++------- {arbor => include/arbor}/morphology.hpp | 0 {arbor => include/arbor}/point.hpp | 0 {arbor => include/arbor}/sampling.hpp | 3 +- {arbor => include/arbor}/simd/approx.hpp | 0 {arbor => include/arbor}/simd/avx.hpp | 4 +- {arbor => include/arbor}/simd/avx512.hpp | 4 +- {arbor => include/arbor}/simd/generic.hpp | 2 +- {arbor => include/arbor}/simd/implbase.hpp | 0 {arbor => include/arbor}/simd/native.hpp | 0 {arbor => include/arbor}/simd/simd.hpp | 6 +- {arbor => include/arbor}/simd/simd_io.hpp | 2 +- {arbor => include/arbor}/simple_sampler.hpp | 35 +-- .../arbor}/spike_source_cell.hpp | 2 +- {arbor => include/arbor}/time_sequence.hpp | 12 +- {arbor => include/arbor}/util/any.hpp | 10 +- {arbor => include/arbor}/util/any_ptr.hpp | 0 {arbor => include/arbor}/util/make_unique.hpp | 4 +- {arbor => include/arbor}/util/unique_any.hpp | 16 +- lmorpho/lmorpho.cpp | 2 +- lmorpho/lsystem.cpp | 5 +- lmorpho/lsystem.hpp | 2 +- lmorpho/morphio.cpp | 7 +- lmorpho/morphio.hpp | 2 +- modcc/printer/cprinter.cpp | 2 +- test/common_cells.hpp | 35 ++- test/simple_recipes.hpp | 11 +- test/ubench/mech_vec.cpp | 15 +- test/unit/CMakeLists.txt | 2 +- test/unit/test_any.cpp | 10 +- test/unit/test_compartments.cpp | 89 ++------ test/unit/test_domain_decomposition.cpp | 12 +- test/unit/test_fvm_layout.cpp | 209 +++++++++++------- test/unit/test_fvm_lowered.cpp | 18 +- test/unit/test_lif_cell_group.cpp | 19 +- test/unit/{test_cell.cpp => test_mc_cell.cpp} | 86 +++---- test/unit/test_mc_cell_group.cpp | 4 +- test/unit/test_mc_cell_group_gpu.cpp | 2 +- test/unit/test_mechinfo.cpp | 2 +- test/unit/test_partition_by_constraint.cpp | 6 +- test/unit/test_point.cpp | 2 +- test/unit/test_probe.cpp | 12 +- test/unit/test_segment.cpp | 44 +--- test/unit/test_simd.cpp | 4 +- test/unit/test_spike_source.cpp | 9 +- test/unit/test_swcio.cpp | 54 +++-- test/unit/test_synapses.cpp | 16 +- test/unit/test_time_seq.cpp | 6 +- test/unit/test_unique_any.cpp | 7 +- test/validation/convergence_test.hpp | 14 +- test/validation/trace_analysis.cpp | 8 +- test/validation/trace_analysis.hpp | 32 ++- test/validation/validate_ball_and_stick.cpp | 34 +-- .../validate_compartment_policy.cpp | 4 +- test/validation/validate_kinetic.cpp | 12 +- test/validation/validate_soma.cpp | 6 +- test/validation/validate_synapses.cpp | 20 +- test/validation/validation_data.cpp | 6 +- test/validation/validation_data.hpp | 5 +- 105 files changed, 709 insertions(+), 897 deletions(-) rename arbor/{compartment.hpp => fvm_compartment.hpp} (78%) rename arbor/{cell.cpp => mc_cell.cpp} (51%) rename {arbor => include/arbor}/benchmark_cell.hpp (93%) rename {arbor => include/arbor}/constants.hpp (100%) rename arbor/lif_cell_description.hpp => include/arbor/lif_cell.hpp (94%) rename arbor/cell.hpp => include/arbor/mc_cell.hpp (85%) rename arbor/segment.hpp => include/arbor/mc_segment.hpp (74%) rename {arbor => include/arbor}/morphology.hpp (100%) rename {arbor => include/arbor}/point.hpp (100%) rename {arbor => include/arbor}/sampling.hpp (95%) rename {arbor => include/arbor}/simd/approx.hpp (100%) rename {arbor => include/arbor}/simd/avx.hpp (99%) rename {arbor => include/arbor}/simd/avx512.hpp (99%) rename {arbor => include/arbor}/simd/generic.hpp (97%) rename {arbor => include/arbor}/simd/implbase.hpp (100%) rename {arbor => include/arbor}/simd/native.hpp (100%) rename {arbor => include/arbor}/simd/simd.hpp (99%) rename {arbor => include/arbor}/simd/simd_io.hpp (94%) rename {arbor => include/arbor}/simple_sampler.hpp (53%) rename {arbor => include/arbor}/spike_source_cell.hpp (87%) rename {arbor => include/arbor}/time_sequence.hpp (96%) rename {arbor => include/arbor}/util/any.hpp (94%) rename {arbor => include/arbor}/util/any_ptr.hpp (100%) rename {arbor => include/arbor}/util/make_unique.hpp (74%) rename {arbor => include/arbor}/util/unique_any.hpp (91%) rename test/unit/{test_cell.cpp => test_mc_cell.cpp} (80%) diff --git a/arbor/CMakeLists.txt b/arbor/CMakeLists.txt index 4df24314..8208a98e 100644 --- a/arbor/CMakeLists.txt +++ b/arbor/CMakeLists.txt @@ -9,7 +9,7 @@ set(arbor_sources builtin_mechanisms.cpp cell_group_factory.cpp common_types_io.cpp - cell.cpp + mc_cell.cpp event_binner.cpp fvm_layout.cpp fvm_lowered_cell_impl.cpp diff --git a/arbor/backends/multicore/multicore_common.hpp b/arbor/backends/multicore/multicore_common.hpp index f2ef70ec..b0b3ed4e 100644 --- a/arbor/backends/multicore/multicore_common.hpp +++ b/arbor/backends/multicore/multicore_common.hpp @@ -11,8 +11,6 @@ #include <arbor/fvm_types.hpp> #include "backends/event.hpp" -#include "math.hpp" -#include "simd/simd.hpp" #include "util/padded_alloc.hpp" #include "multi_event_stream.hpp" diff --git a/arbor/backends/multicore/partition_by_constraint.hpp b/arbor/backends/multicore/partition_by_constraint.hpp index b4cf0c06..dc7d4d92 100644 --- a/arbor/backends/multicore/partition_by_constraint.hpp +++ b/arbor/backends/multicore/partition_by_constraint.hpp @@ -1,7 +1,8 @@ #pragma once -#include<vector> -#include<simd/simd.hpp> +#include <vector> + +#include <arbor/simd/simd.hpp> namespace arb { namespace multicore { diff --git a/arbor/backends/multicore/shared_state.cpp b/arbor/backends/multicore/shared_state.cpp index 00848199..2af16850 100644 --- a/arbor/backends/multicore/shared_state.cpp +++ b/arbor/backends/multicore/shared_state.cpp @@ -6,15 +6,15 @@ #include <vector> #include <arbor/assert.hpp> +#include <arbor/constants.hpp> #include <arbor/fvm_types.hpp> #include <arbor/common_types.hpp> #include <arbor/ion.hpp> +#include <arbor/simd/simd.hpp> #include "backends/event.hpp" -#include "constants.hpp" #include "io/sepval.hpp" #include "math.hpp" -#include "simd/simd.hpp" #include "util/padded_alloc.hpp" #include "util/rangeutil.hpp" diff --git a/arbor/backends/multicore/shared_state.hpp b/arbor/backends/multicore/shared_state.hpp index 3188dade..af2b19be 100644 --- a/arbor/backends/multicore/shared_state.hpp +++ b/arbor/backends/multicore/shared_state.hpp @@ -11,13 +11,11 @@ #include <arbor/common_types.hpp> #include <arbor/fvm_types.hpp> #include <arbor/ion.hpp> +#include <arbor/simd/simd.hpp> #include <arbor/util/enumhash.hpp> #include "backends/event.hpp" -#include "constants.hpp" #include "event_queue.hpp" -#include "math.hpp" -#include "simd/simd.hpp" #include "util/padded_alloc.hpp" #include "util/rangeutil.hpp" diff --git a/arbor/benchmark_cell_group.cpp b/arbor/benchmark_cell_group.cpp index d89dacd2..6466d7c1 100644 --- a/arbor/benchmark_cell_group.cpp +++ b/arbor/benchmark_cell_group.cpp @@ -1,12 +1,15 @@ #include <chrono> #include <exception> +#include <arbor/benchmark_cell.hpp> +#include <arbor/time_sequence.hpp> + #include <cell_group.hpp> #include <profile/profiler_macro.hpp> #include <recipe.hpp> -#include <benchmark_cell.hpp> #include <benchmark_cell_group.hpp> -#include <time_sequence.hpp> + +#include "util/span.hpp" namespace arb { diff --git a/arbor/benchmark_cell_group.hpp b/arbor/benchmark_cell_group.hpp index 536a7fa1..146baf7f 100644 --- a/arbor/benchmark_cell_group.hpp +++ b/arbor/benchmark_cell_group.hpp @@ -1,9 +1,10 @@ #pragma once -#include <benchmark_cell.hpp> -#include <cell_group.hpp> -#include <recipe.hpp> -#include <time_sequence.hpp> +#include <arbor/benchmark_cell.hpp> +#include <arbor/time_sequence.hpp> + +#include "cell_group.hpp" +#include "recipe.hpp" namespace arb { diff --git a/arbor/cell_group.hpp b/arbor/cell_group.hpp index 3a3d3035..ed53924f 100644 --- a/arbor/cell_group.hpp +++ b/arbor/cell_group.hpp @@ -5,13 +5,12 @@ #include <vector> #include <arbor/common_types.hpp> +#include <arbor/sampling.hpp> #include <arbor/spike.hpp> -#include "cell.hpp" #include "epoch.hpp" #include "event_binner.hpp" #include "event_queue.hpp" -#include "sampling.hpp" #include "schedule.hpp" namespace arb { diff --git a/arbor/cell_group_factory.cpp b/arbor/cell_group_factory.cpp index 4c613695..96079522 100644 --- a/arbor/cell_group_factory.cpp +++ b/arbor/cell_group_factory.cpp @@ -9,7 +9,6 @@ #include <mc_cell_group.hpp> #include <recipe.hpp> #include <spike_source_cell_group.hpp> -#include <util/unique_any.hpp> namespace arb { diff --git a/arbor/cell_group_factory.hpp b/arbor/cell_group_factory.hpp index 12c038b1..88770475 100644 --- a/arbor/cell_group_factory.hpp +++ b/arbor/cell_group_factory.hpp @@ -2,11 +2,12 @@ #include <vector> -#include <backends.hpp> -#include <cell_group.hpp> -#include <domain_decomposition.hpp> -#include <recipe.hpp> -#include <util/unique_any.hpp> +#include <arbor/util/unique_any.hpp> + +#include "backends.hpp" +#include "cell_group.hpp" +#include "domain_decomposition.hpp" +#include "recipe.hpp" namespace arb { diff --git a/arbor/communication/communicator.hpp b/arbor/communication/communicator.hpp index 60c7d5cb..d9a6f759 100644 --- a/arbor/communication/communicator.hpp +++ b/arbor/communication/communicator.hpp @@ -23,6 +23,7 @@ #include "util/double_buffer.hpp" #include "util/partition.hpp" #include "util/rangeutil.hpp" +#include "util/span.hpp" namespace arb { @@ -45,7 +46,6 @@ public: const domain_decomposition& dom_dec, const distributed_context* ctx) { - using util::make_span; context_ = ctx; num_domains_ = context_->size(); num_local_groups_ = dom_dec.groups.size(); @@ -186,7 +186,7 @@ public: const auto& sp = global_spikes.partition(); const auto& cp = connection_part_; - for (auto dom: make_span(0, num_domains_)) { + for (auto dom: make_span(num_domains_)) { auto cons = subrange_view(connections_, cp[dom], cp[dom+1]); auto spks = subrange_view(global_spikes.values(), sp[dom], sp[dom+1]); diff --git a/arbor/event_generator.hpp b/arbor/event_generator.hpp index 6b4fc482..048b62eb 100644 --- a/arbor/event_generator.hpp +++ b/arbor/event_generator.hpp @@ -5,9 +5,9 @@ #include <random> #include <arbor/common_types.hpp> +#include <arbor/time_sequence.hpp> #include "event_queue.hpp" -#include "time_sequence.hpp" #include "util/range.hpp" #include "util/rangeutil.hpp" diff --git a/arbor/compartment.hpp b/arbor/fvm_compartment.hpp similarity index 78% rename from arbor/compartment.hpp rename to arbor/fvm_compartment.hpp index fa220ccf..6361c511 100644 --- a/arbor/compartment.hpp +++ b/arbor/fvm_compartment.hpp @@ -6,84 +6,15 @@ #include <arbor/common_types.hpp> #include <arbor/util/compat.hpp> +#include "algorithms.hpp" #include "math.hpp" -#include "util/counter.hpp" #include "util/iterutil.hpp" #include "util/partition.hpp" -#include "util/span.hpp" #include "util/rangeutil.hpp" #include "util/transform.hpp" namespace arb { -/// Defines the simplest type of compartment -/// The compartment is a conic frustrum -struct compartment { - using value_type = double; - using size_type = cell_local_size_type; - using value_pair = std::pair<value_type, value_type>; - - compartment() = delete; - - compartment( - size_type idx, - value_type len, - value_type r1, - value_type r2 - ) - : index{idx}, - radius{r1, r2}, - length{len} - {} - - - size_type index; - std::pair<value_type, value_type> radius; - value_type length; -}; - -// (NB: auto type deduction and lambda in C++14 will simplify the following) - -template <typename size_type, typename real_type> -class compartment_maker { -public: - compartment_maker(size_type n, real_type length, real_type rL, real_type rR): - r0_{rL}, - dr_{(rR-rL)/n}, - dx_{length/n} - {} - - compartment operator()(size_type i) const { - return compartment(i, dx_, r0_+i*dr_, r0_+(i+1)*dr_); - } - -private: - real_type r0_; - real_type dr_; - real_type dx_; -}; - -template <typename size_type, typename real_type> -using compartment_iterator = - util::transform_iterator<util::counter<size_type>, compartment_maker<size_type, real_type>>; - -template <typename size_type, typename real_type> -using compartment_range = - util::range<compartment_iterator<size_type, real_type>>; - - -template <typename size_type, typename real_type> -compartment_range<size_type, real_type> make_compartment_range( - size_type num_compartments, - real_type radius_L, - real_type radius_R, - real_type length) -{ - return util::transform_view( - util::span<size_type>(0, num_compartments), - compartment_maker<size_type, real_type>(num_compartments, length, radius_L, radius_R)); -} - /// Divided compartments for use with (e.g.) fvm control volume setup struct semi_compartment { diff --git a/arbor/fvm_layout.cpp b/arbor/fvm_layout.cpp index 12b5d7ca..d634fc71 100644 --- a/arbor/fvm_layout.cpp +++ b/arbor/fvm_layout.cpp @@ -3,9 +3,13 @@ #include <unordered_set> #include <vector> +#include <arbor/mc_cell.hpp> #include <arbor/util/enumhash.hpp> +#include "algorithms.hpp" +#include "fvm_compartment.hpp" #include "fvm_layout.hpp" +#include "tree.hpp" #include "util/maputil.hpp" #include "util/meta.hpp" #include "util/partition.hpp" @@ -22,12 +26,27 @@ using util::value_by_key; // Convenience routines -template <typename ResizableContainer, typename Index> -void extend_to(ResizableContainer& c, const Index& i) { - if (util::size(c)<=i) { - c.resize(i+1); +namespace { + template <typename ResizableContainer, typename Index> + void extend_to(ResizableContainer& c, const Index& i) { + if (util::size(c)<=i) { + c.resize(i+1); + } } -} + + struct compartment_model { + arb::tree tree; + std::vector<tree::int_type> parent_index; + std::vector<tree::int_type> segment_index; + + explicit compartment_model(const mc_cell& cell) { + tree = arb::tree(cell.parents()); + auto counts = cell.compartment_counts(); + parent_index = make_parent_index(tree, counts); + segment_index = algorithms::make_index(counts); + } + }; +} // namespace // Cable segment discretization // ---------------------------- @@ -91,7 +110,7 @@ void extend_to(ResizableContainer& c, const Index& i) { // = 1/R · hVâ‚Vâ‚‚/(h₂²Vâ‚+h₲Vâ‚‚) // -fvm_discretization fvm_discretize(const std::vector<cell>& cells) { +fvm_discretization fvm_discretize(const std::vector<mc_cell>& cells) { using value_type = fvm_value_type; using index_type = fvm_index_type; using size_type = fvm_size_type; @@ -99,11 +118,11 @@ fvm_discretization fvm_discretize(const std::vector<cell>& cells) { fvm_discretization D; util::make_partition(D.cell_segment_bounds, - transform_view(cells, [](const cell& c) { return c.num_segments(); })); + transform_view(cells, [](const mc_cell& c) { return c.num_segments(); })); std::vector<index_type> cell_comp_bounds; auto cell_comp_part = make_partition(cell_comp_bounds, - transform_view(cells, [](const cell& c) { return c.num_compartments(); })); + transform_view(cells, [](const mc_cell& c) { return c.num_compartments(); })); D.ncell = cells.size(); D.ncomp = cell_comp_part.bounds().second; @@ -120,7 +139,7 @@ fvm_discretization fvm_discretize(const std::vector<cell>& cells) { std::vector<size_type> seg_comp_bounds; for (auto i: make_span(0, D.ncell)) { const auto& c = cells[i]; - auto cell_graph = c.model(); + compartment_model cell_graph (c); auto cell_comp_ival = cell_comp_part[i]; auto cell_comp_base = cell_comp_ival.first; @@ -132,7 +151,7 @@ fvm_discretization fvm_discretize(const std::vector<cell>& cells) { seg_comp_bounds.clear(); auto seg_comp_part = make_partition( seg_comp_bounds, - transform_view(c.segments(), [](const segment_ptr& s) { return s->num_compartments(); }), + transform_view(c.segments(), [](const mc_segment_ptr& s) { return s->num_compartments(); }), cell_comp_base); const auto nseg = seg_comp_part.size(); @@ -176,7 +195,7 @@ fvm_discretization fvm_discretize(const std::vector<cell>& cells) { auto cm = cable->cm; // [F/m²] auto rL = cable->rL; // [Ω·cm] - auto divs = div_compartments<div_compartment_integrator>(cable, ncomp); + auto divs = div_compartment_integrator(ncomp, cable->radii(), cable->lengths()); seg_info.parent_cv = D.parent_cv[seg_comp_ival.first]; seg_info.parent_cv_area = divs(0).left.area; @@ -230,7 +249,7 @@ fvm_discretization fvm_discretize(const std::vector<cell>& cells) { // IIb. Density mechanism CVs, parameter values; ion channel default concentration contributions. // IIc. Point mechanism CVs, parameter values, and targets. -fvm_mechanism_data fvm_build_mechanism_data(const mechanism_catalogue& catalogue, const std::vector<cell>& cells, const fvm_discretization& D) { +fvm_mechanism_data fvm_build_mechanism_data(const mechanism_catalogue& catalogue, const std::vector<mc_cell>& cells, const fvm_discretization& D) { using util::assign; using util::sort_by; using util::optional; diff --git a/arbor/fvm_layout.hpp b/arbor/fvm_layout.hpp index c23d0372..9d09e5ca 100644 --- a/arbor/fvm_layout.hpp +++ b/arbor/fvm_layout.hpp @@ -1,13 +1,13 @@ #pragma once #include <arbor/fvm_types.hpp> +#include <arbor/mc_cell.hpp> #include <arbor/mechanism.hpp> #include <arbor/mechinfo.hpp> #include <arbor/mechcat.hpp> #include <arbor/util/enumhash.hpp> -#include "cell.hpp" -#include "compartment.hpp" +#include "fvm_compartment.hpp" #include "util/deduce_return.hpp" #include "util/span.hpp" @@ -86,7 +86,7 @@ struct fvm_discretization { } }; -fvm_discretization fvm_discretize(const std::vector<cell>& cells); +fvm_discretization fvm_discretize(const std::vector<mc_cell>& cells); // Post-discretization data for point and density mechanism instantiation. @@ -136,6 +136,6 @@ struct fvm_mechanism_data { std::size_t ntarget = 0; }; -fvm_mechanism_data fvm_build_mechanism_data(const mechanism_catalogue& catalogue, const std::vector<cell>& cells, const fvm_discretization& D); +fvm_mechanism_data fvm_build_mechanism_data(const mechanism_catalogue& catalogue, const std::vector<mc_cell>& cells, const fvm_discretization& D); } // namespace arb diff --git a/arbor/fvm_lowered_cell_impl.hpp b/arbor/fvm_lowered_cell_impl.hpp index 11e9f535..f8a7f6b9 100644 --- a/arbor/fvm_lowered_cell_impl.hpp +++ b/arbor/fvm_lowered_cell_impl.hpp @@ -24,6 +24,7 @@ #include "profile/profiler_macro.hpp" #include "recipe.hpp" #include "sampler_map.hpp" +#include "util/maputil.hpp" #include "util/meta.hpp" #include "util/range.hpp" #include "util/rangeutil.hpp" @@ -292,16 +293,16 @@ void fvm_lowered_cell_impl<B>::initialize( using util::value_by_key; using util::keys; - std::vector<cell> cells; + std::vector<mc_cell> cells; const std::size_t ncell = gids.size(); cells.reserve(ncell); for (auto gid: gids) { - cells.push_back(any_cast<cell>(rec.get_cell_description(gid))); + cells.push_back(any_cast<mc_cell>(rec.get_cell_description(gid))); } auto rec_props = rec.get_global_properties(cell_kind::cable1d_neuron); - auto global_props = rec_props.has_value()? any_cast<cell_global_properties>(rec_props): cell_global_properties{}; + auto global_props = rec_props.has_value()? any_cast<mc_cell_global_properties>(rec_props): mc_cell_global_properties{}; const mechanism_catalogue* catalogue = global_props.catalogue; initial_voltage_ = global_props.init_membrane_potential_mV; diff --git a/arbor/lif_cell_group.cpp b/arbor/lif_cell_group.cpp index e8b282b6..70f51250 100644 --- a/arbor/lif_cell_group.cpp +++ b/arbor/lif_cell_group.cpp @@ -1,5 +1,7 @@ #include <lif_cell_group.hpp> +#include "util/span.hpp" + using namespace arb; // Constructor containing gid of first cell in a group and a container of all cells. @@ -12,8 +14,8 @@ gids_(std::move(gids)) cells_.reserve(gids_.size()); last_time_updated_.resize(gids_.size()); - for (auto lid: util::make_span(0, gids_.size())) { - cells_.push_back(util::any_cast<lif_cell_description>(rec.get_cell_description(gids_[lid]))); + for (auto lid: util::make_span(gids_.size())) { + cells_.push_back(util::any_cast<lif_cell>(rec.get_cell_description(gids_[lid]))); } } @@ -24,7 +26,7 @@ cell_kind lif_cell_group::get_cell_kind() const { void lif_cell_group::advance(epoch ep, time_type dt, const event_lane_subrange& event_lanes) { PE(advance_lif); if (event_lanes.size() > 0) { - for (auto lid: util::make_span(0, gids_.size())) { + for (auto lid: util::make_span(gids_.size())) { // Advance each cell independently. advance_cell(ep.tfinal, dt, lid, event_lanes[lid]); } diff --git a/arbor/lif_cell_group.hpp b/arbor/lif_cell_group.hpp index d4582a8a..d81aaf3b 100644 --- a/arbor/lif_cell_group.hpp +++ b/arbor/lif_cell_group.hpp @@ -1,13 +1,14 @@ #pragma once -#include <algorithm> -#include <cell_group.hpp> -#include <event_queue.hpp> -#include <lif_cell_description.hpp> -#include "profile/profiler_macro.hpp" -#include <recipe.hpp> -#include <util/unique_any.hpp> + #include <vector> +#include <arbor/lif_cell.hpp> + +#include "cell_group.hpp" +#include "event_queue.hpp" +#include "profile/profiler_macro.hpp" +#include "recipe.hpp" + namespace arb { class lif_cell_group: public cell_group { @@ -42,7 +43,7 @@ private: std::vector<cell_gid_type> gids_; // Cells that belong to this group. - std::vector<lif_cell_description> cells_; + std::vector<lif_cell> cells_; // Spikes that are generated (not necessarily sorted). std::vector<spike> spikes_; diff --git a/arbor/cell.cpp b/arbor/mc_cell.cpp similarity index 51% rename from arbor/cell.cpp rename to arbor/mc_cell.cpp index 2058e78f..2184134c 100644 --- a/arbor/cell.cpp +++ b/arbor/mc_cell.cpp @@ -1,23 +1,28 @@ -#include <cell.hpp> -#include <morphology.hpp> -#include <tree.hpp> -#include <util/rangeutil.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/mc_segment.hpp> +#include <arbor/morphology.hpp> + +#include "util/rangeutil.hpp" namespace arb { -cell::cell() { +using value_type = mc_cell::value_type; +using index_type = mc_cell::index_type; +using size_type = mc_cell::size_type; + +mc_cell::mc_cell() { // insert a placeholder segment for the soma segments_.push_back(make_segment<placeholder_segment>()); parents_.push_back(0); } -void cell::assert_valid_segment(index_type i) const { +void mc_cell::assert_valid_segment(index_type i) const { if (i>=num_segments()) { throw std::out_of_range("no such segment"); } } -cell::size_type cell::num_segments() const { +size_type mc_cell::num_segments() const { return segments_.size(); } @@ -25,7 +30,7 @@ cell::size_type cell::num_segments() const { // note: I think that we have to enforce that the soma is the first // segment that is added // -soma_segment* cell::add_soma(value_type radius, point_type center) { +soma_segment* mc_cell::add_soma(value_type radius, point_type center) { if (has_soma()) { throw std::runtime_error("cell already has soma"); } @@ -33,7 +38,7 @@ soma_segment* cell::add_soma(value_type radius, point_type center) { return segments_[0]->as_soma(); } -cable_segment* cell::add_cable(cell::index_type parent, segment_ptr&& cable) { +cable_segment* mc_cell::add_cable(index_type parent, mc_segment_ptr&& cable) { if (!cable->as_cable()) { throw std::invalid_argument("segment is not a cable segment"); } @@ -48,45 +53,35 @@ cable_segment* cell::add_cable(cell::index_type parent, segment_ptr&& cable) { return segments_.back()->as_cable(); } -segment* cell::segment(index_type index) { +mc_segment* mc_cell::segment(index_type index) { assert_valid_segment(index); return segments_[index].get(); } -segment const* cell::segment(index_type index) const { +mc_segment const* mc_cell::segment(index_type index) const { assert_valid_segment(index); return segments_[index].get(); } -bool cell::has_soma() const { +bool mc_cell::has_soma() const { return !segment(0)->is_placeholder(); } -soma_segment* cell::soma() { +soma_segment* mc_cell::soma() { return has_soma()? segment(0)->as_soma(): nullptr; } -const soma_segment* cell::soma() const { +const soma_segment* mc_cell::soma() const { return has_soma()? segment(0)->as_soma(): nullptr; } -cable_segment* cell::cable(index_type index) { +cable_segment* mc_cell::cable(index_type index) { assert_valid_segment(index); auto cable = segment(index)->as_cable(); return cable? cable: throw std::runtime_error("segment is not a cable segment"); } -cell::value_type cell::volume() const { - return util::sum_by(segments_, - [](const segment_ptr& s) { return s->volume(); }); -} - -cell::value_type cell::area() const { - return util::sum_by(segments_, - [](const segment_ptr& s) { return s->area(); }); -} - -std::vector<cell::size_type> cell::compartment_counts() const { +std::vector<size_type> mc_cell::compartment_counts() const { std::vector<size_type> comp_count; comp_count.reserve(num_segments()); for (const auto& s: segments()) { @@ -95,67 +90,26 @@ std::vector<cell::size_type> cell::compartment_counts() const { return comp_count; } -cell::size_type cell::num_compartments() const { +size_type mc_cell::num_compartments() const { return util::sum_by(segments_, - [](const segment_ptr& s) { return s->num_compartments(); }); -} - -compartment_model cell::model() const { - compartment_model m; - - m.tree = tree(parents_); - auto counts = compartment_counts(); - m.parent_index = make_parent_index(m.tree, counts); - m.segment_index = algorithms::make_index(counts); - - return m; + [](const mc_segment_ptr& s) { return s->num_compartments(); }); } -void cell::add_stimulus(segment_location loc, i_clamp stim) { +void mc_cell::add_stimulus(segment_location loc, i_clamp stim) { (void)segment(loc.segment); // assert loc.segment in range stimuli_.push_back({loc, std::move(stim)}); } -void cell::add_detector(segment_location loc, double threshold) { +void mc_cell::add_detector(segment_location loc, double threshold) { spike_detectors_.push_back({loc, threshold}); } -// Rough and ready comparison of two cells. -// We don't use an operator== because equality of two cells is open to -// interpretation. For example, it is possible to have two viable representations -// of a cell: with and without location information for the cables. -// -// Checks that two cells have the same -// - number and type of segments -// - volume and area properties of each segment -// - number of compartments in each segment -bool cell_basic_equality(const cell& lhs, const cell& rhs) { - if (lhs.parents_ != rhs.parents_) { - return false; - } - - for (cell::index_type i=0; i<lhs.num_segments(); ++i) { - // a quick and dirty test - auto& l = *lhs.segment(i); - auto& r = *rhs.segment(i); - - if (l.kind() != r.kind()) return false; - if (l.area() != r.area()) return false; - if (l.volume() != r.volume()) return false; - if (l.as_cable()) { - if (l.as_cable()->num_compartments() != r.as_cable()->num_compartments()) { - return false; - } - } - } - return true; -} // Construct cell from flat morphology specification. -cell make_cell(const morphology& morph, bool compartments_from_discretization) { - using point3d = cell::point_type; - cell newcell; +mc_cell make_mc_cell(const morphology& morph, bool compartments_from_discretization) { + using point3d = mc_cell::point_type; + mc_cell newcell; if (!morph) { return newcell; @@ -178,7 +132,7 @@ cell make_cell(const morphology& morph, bool compartments_from_discretization) { default: ; } - std::vector<cell::value_type> radii; + std::vector<value_type> radii; std::vector<point3d> points; for (const section_point& p: section.points) { diff --git a/arbor/mc_cell_group.cpp b/arbor/mc_cell_group.cpp index 6988757e..b5e12cc2 100644 --- a/arbor/mc_cell_group.cpp +++ b/arbor/mc_cell_group.cpp @@ -4,11 +4,10 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> +#include <arbor/sampling.hpp> #include <arbor/spike.hpp> #include "backends/event.hpp" -#include "cell.hpp" -#include "cell_group.hpp" #include "cell_group.hpp" #include "event_binner.hpp" #include "event_queue.hpp" @@ -17,9 +16,10 @@ #include "profile/profiler_macro.hpp" #include "recipe.hpp" #include "sampler_map.hpp" -#include "sampling.hpp" #include "util/filter.hpp" +#include "util/maputil.hpp" #include "util/partition.hpp" +#include "util/span.hpp" namespace arb { @@ -30,7 +30,7 @@ mc_cell_group::mc_cell_group(std::vector<cell_gid_type> gids, const recipe& rec, set_binning_policy(binning_kind::none, 0); // Build lookup table for gid to local index. - for (auto i: util::make_span(0, gids_.size())) { + for (auto i: util::count_along(gids_)) { gid_index_map_[gids_[i]] = i; } @@ -83,7 +83,7 @@ void mc_cell_group::advance(epoch ep, time_type dt, const event_lane_subrange& e staged_events_.clear(); // skip event binning if empty lanes are passed if (event_lanes.size()) { - for (auto lid: util::make_span(0, gids_.size())) { + for (auto lid: util::count_along(gids_)) { auto& lane = event_lanes[lid]; for (auto e: lane) { if (e.time>=ep.tfinal) break; diff --git a/arbor/mc_cell_group.hpp b/arbor/mc_cell_group.hpp index 2609858b..463e59d0 100644 --- a/arbor/mc_cell_group.hpp +++ b/arbor/mc_cell_group.hpp @@ -8,10 +8,10 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> +#include <arbor/sampling.hpp> #include <arbor/spike.hpp> #include "backends/event.hpp" -#include "cell.hpp" #include "cell_group.hpp" #include "event_binner.hpp" #include "event_queue.hpp" @@ -19,12 +19,10 @@ #include "profile/profiler_macro.hpp" #include "recipe.hpp" #include "sampler_map.hpp" -#include "sampling.hpp" #include "util/double_buffer.hpp" #include "util/filter.hpp" #include "util/partition.hpp" #include "util/range.hpp" -#include "util/unique_any.hpp" namespace arb { diff --git a/arbor/mechcat.cpp b/arbor/mechcat.cpp index 11231771..5ce86884 100644 --- a/arbor/mechcat.cpp +++ b/arbor/mechcat.cpp @@ -4,9 +4,9 @@ #include <vector> #include <arbor/mechcat.hpp> +#include <arbor/util/make_unique.hpp> #include "util/maputil.hpp" -#include "util/make_unique.hpp" namespace arb { diff --git a/arbor/merge_events.cpp b/arbor/merge_events.cpp index fcd31dc3..4e5d8600 100644 --- a/arbor/merge_events.cpp +++ b/arbor/merge_events.cpp @@ -1,15 +1,15 @@ +#include <iostream> #include <set> #include <vector> -#include <backends.hpp> -#include <cell_group.hpp> -#include <cell_group_factory.hpp> -#include <domain_decomposition.hpp> -#include <merge_events.hpp> -#include <recipe.hpp> -#include <util/filter.hpp> -#include <util/span.hpp> -#include <util/unique_any.hpp> +#include "backends.hpp" +#include "cell_group.hpp" +#include "cell_group_factory.hpp" +#include "domain_decomposition.hpp" +#include "merge_events.hpp" +#include "recipe.hpp" +#include "util/filter.hpp" +#include "util/span.hpp" #include "profile/profiler_macro.hpp" namespace arb { @@ -53,12 +53,16 @@ tourney_tree::tourney_tree(std::vector<event_generator>& input): setup(0); } -void tourney_tree::print() const { - auto nxt=1u; - for (auto i=0u; i<nodes_; ++i) { - if (i==nxt-1) { nxt*=2; std::cout << "\n";} - std::cout << "{" << heap_[i].first << "," << heap_[i].second << "}\n"; +std::ostream& operator<<(std::ostream& out, const tourney_tree& tt) { + unsigned nxt = 1; + for (unsigned i = 0; i<tt.nodes_; ++i) { + if (i==nxt-1) { + nxt*=2; + out << "\n"; + } + out << "{" << tt.heap_[i].first << "," << tt.heap_[i].second << "}\n"; } + return out; } bool tourney_tree::empty() const { diff --git a/arbor/merge_events.hpp b/arbor/merge_events.hpp index eb0d2873..72c3918d 100644 --- a/arbor/merge_events.hpp +++ b/arbor/merge_events.hpp @@ -1,6 +1,7 @@ #pragma once #include <algorithm> +#include <iosfwd> #include <vector> #include <event_generator.hpp> @@ -56,7 +57,7 @@ namespace impl { bool empty(time_type t) const; postsynaptic_spike_event head() const; void pop(); - void print() const; + friend std::ostream& operator<<(std::ostream&, const tourney_tree&); private: void setup(unsigned i); diff --git a/arbor/morphology.cpp b/arbor/morphology.cpp index ea0a4581..5508f835 100644 --- a/arbor/morphology.cpp +++ b/arbor/morphology.cpp @@ -1,9 +1,9 @@ #include <cmath> #include <vector> -#include <math.hpp> +#include <arbor/morphology.hpp> -#include <morphology.hpp> +#include "math.hpp" namespace arb { diff --git a/arbor/partition_load_balance.cpp b/arbor/partition_load_balance.cpp index 9cff1bd2..062373de 100644 --- a/arbor/partition_load_balance.cpp +++ b/arbor/partition_load_balance.cpp @@ -4,6 +4,7 @@ #include "domain_decomposition.hpp" #include "hardware/node_info.hpp" #include "recipe.hpp" +#include "util/span.hpp" namespace arb { @@ -40,7 +41,7 @@ domain_decomposition partition_load_balance(const recipe& rec, std::vector<cell_gid_type> gid_divisions; auto gid_part = make_partition( - gid_divisions, transform_view(make_span(0, num_domains), dom_size)); + gid_divisions, transform_view(make_span(num_domains), dom_size)); // Local load balance diff --git a/arbor/recipe.hpp b/arbor/recipe.hpp index 1ce9453d..8d163c35 100644 --- a/arbor/recipe.hpp +++ b/arbor/recipe.hpp @@ -6,10 +6,9 @@ #include <stdexcept> #include <arbor/common_types.hpp> +#include <arbor/util/unique_any.hpp> -#include "cell.hpp" #include "event_generator.hpp" -#include "util/unique_any.hpp" namespace arb { diff --git a/arbor/sampler_map.hpp b/arbor/sampler_map.hpp index cd6a1576..08040015 100644 --- a/arbor/sampler_map.hpp +++ b/arbor/sampler_map.hpp @@ -10,8 +10,8 @@ #include <unordered_map> #include <arbor/common_types.hpp> +#include <arbor/sampling.hpp> -#include "sampling.hpp" #include "schedule.hpp" #include "util/deduce_return.hpp" #include "util/transform.hpp" diff --git a/arbor/simulation.cpp b/arbor/simulation.cpp index 0fbde656..5134e714 100644 --- a/arbor/simulation.cpp +++ b/arbor/simulation.cpp @@ -2,18 +2,17 @@ #include <set> #include <vector> -#include <backends.hpp> -#include <cell_group.hpp> -#include <cell_group_factory.hpp> -#include <domain_decomposition.hpp> -#include <merge_events.hpp> -#include <simulation.hpp> -#include <recipe.hpp> -#include <thread_private_spike_store.hpp> -#include <util/double_buffer.hpp> -#include <util/filter.hpp> -#include <util/span.hpp> -#include <util/unique_any.hpp> +#include "backends.hpp" +#include "cell_group.hpp" +#include "cell_group_factory.hpp" +#include "domain_decomposition.hpp" +#include "merge_events.hpp" +#include "simulation.hpp" +#include "recipe.hpp" +#include "thread_private_spike_store.hpp" +#include "util/double_buffer.hpp" +#include "util/filter.hpp" +#include "util/span.hpp" #include "profile/profiler_macro.hpp" namespace arb { diff --git a/arbor/simulation.hpp b/arbor/simulation.hpp index 9c178742..d5be946e 100644 --- a/arbor/simulation.hpp +++ b/arbor/simulation.hpp @@ -7,6 +7,7 @@ #include <arbor/common_types.hpp> #include <arbor/distributed_context.hpp> +#include <arbor/sampling.hpp> #include "backends.hpp" #include "cell_group.hpp" @@ -14,7 +15,6 @@ #include "domain_decomposition.hpp" #include "epoch.hpp" #include "recipe.hpp" -#include "sampling.hpp" #include "util/nop.hpp" #include "util/handle_set.hpp" diff --git a/arbor/spike_source_cell_group.cpp b/arbor/spike_source_cell_group.cpp index 0bef8303..d62ac2c2 100644 --- a/arbor/spike_source_cell_group.cpp +++ b/arbor/spike_source_cell_group.cpp @@ -1,11 +1,13 @@ #include <exception> -#include <cell_group.hpp> +#include <arbor/spike_source_cell.hpp> +#include <arbor/time_sequence.hpp> + +#include "cell_group.hpp" #include "profile/profiler_macro.hpp" -#include <recipe.hpp> -#include <spike_source_cell.hpp> -#include <spike_source_cell_group.hpp> -#include <time_sequence.hpp> +#include "recipe.hpp" +#include "spike_source_cell_group.hpp" +#include "util/span.hpp" namespace arb { @@ -31,7 +33,7 @@ cell_kind spike_source_cell_group::get_cell_kind() const { void spike_source_cell_group::advance(epoch ep, time_type dt, const event_lane_subrange& event_lanes) { PE(advance_sscell); - for (auto i: util::make_span(0, gids_.size())) { + for (auto i: util::count_along(gids_)) { auto& tseq = time_sequences_[i]; const auto gid = gids_[i]; diff --git a/arbor/spike_source_cell_group.hpp b/arbor/spike_source_cell_group.hpp index d4d52497..da714570 100644 --- a/arbor/spike_source_cell_group.hpp +++ b/arbor/spike_source_cell_group.hpp @@ -1,8 +1,9 @@ #pragma once -#include <cell_group.hpp> -#include <recipe.hpp> -#include <time_sequence.hpp> +#include <arbor/time_sequence.hpp> + +#include "cell_group.hpp" +#include "recipe.hpp" namespace arb { diff --git a/arbor/swcio.cpp b/arbor/swcio.cpp index 02f49f0d..2f93bef8 100644 --- a/arbor/swcio.cpp +++ b/arbor/swcio.cpp @@ -6,12 +6,11 @@ #include <unordered_set> #include <arbor/assert.hpp> +#include <arbor/morphology.hpp> +#include <arbor/point.hpp> -#include <algorithms.hpp> -#include <cell.hpp> -#include <morphology.hpp> -#include <point.hpp> -#include <swcio.hpp> +#include "algorithms.hpp" +#include "swcio.hpp" namespace arb { namespace io { diff --git a/arbor/swcio.hpp b/arbor/swcio.hpp index 84996293..15028118 100644 --- a/arbor/swcio.hpp +++ b/arbor/swcio.hpp @@ -9,10 +9,10 @@ #include <vector> #include <arbor/assert.hpp> +#include <arbor/morphology.hpp> +#include <arbor/point.hpp> -#include <algorithms.hpp> -#include <morphology.hpp> -#include <point.hpp> +#include "algorithms.hpp" namespace arb { namespace io { diff --git a/example/bench/recipe.cpp b/example/bench/recipe.cpp index 50787c08..e70e8060 100644 --- a/example/bench/recipe.cpp +++ b/example/bench/recipe.cpp @@ -1,9 +1,8 @@ #include <random> +#include <arbor/benchmark_cell.hpp> #include <arbor/common_types.hpp> - -#include <benchmark_cell.hpp> -#include <time_sequence.hpp> +#include <arbor/time_sequence.hpp> #include "recipe.hpp" diff --git a/example/brunel/brunel_miniapp.cpp b/example/brunel/brunel_miniapp.cpp index 6ddbebeb..bb2af814 100644 --- a/example/brunel/brunel_miniapp.cpp +++ b/example/brunel/brunel_miniapp.cpp @@ -8,9 +8,11 @@ #include <arbor/common_types.hpp> #include <arbor/distributed_context.hpp> +#include <arbor/lif_cell.hpp> #include <arbor/profile/meter_manager.hpp> #include <arbor/profile/profiler.hpp> #include <arbor/threadinfo.hpp> +#include <arbor/util/make_unique.hpp> #include <arbor/version.hpp> #include "json_meter.hpp" @@ -18,12 +20,10 @@ #include "with_mpi.hpp" #endif -#include "communication/communicator.hpp" #include "event_generator.hpp" #include "hardware/gpu.hpp" #include "hardware/node_info.hpp" #include "io/exporter_spike_file.hpp" -#include "lif_cell_description.hpp" #include "recipe.hpp" #include "simulation.hpp" #include "util/ioutil.hpp" @@ -110,7 +110,7 @@ public: } util::unique_any get_cell_description(cell_gid_type gid) const override { - auto cell = lif_cell_description(); + auto cell = lif_cell(); cell.tau_m = 10; cell.V_th = 10; cell.C_m = 20; diff --git a/example/generators/event_gen.cpp b/example/generators/event_gen.cpp index 3deb5ba0..5a21764d 100644 --- a/example/generators/event_gen.cpp +++ b/example/generators/event_gen.cpp @@ -14,14 +14,14 @@ #include <arbor/common_types.hpp> #include <arbor/distributed_context.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> -#include "cell.hpp" #include "event_generator.hpp" #include "hardware/node_info.hpp" #include "load_balance.hpp" #include "simulation.hpp" #include "recipe.hpp" -#include "simple_sampler.hpp" using arb::cell_gid_type; using arb::cell_lid_type; @@ -48,7 +48,7 @@ public: // capacitance: 0.01 F/m² [default] // synapses: 1 * expsyn arb::util::unique_any get_cell_description(cell_gid_type gid) const override { - arb::cell c; + arb::mc_cell c; c.add_soma(18.8/2.0); // convert 18.8 μm diameter to radius c.soma()->add_mechanism("pas"); diff --git a/example/miniapp/miniapp.cpp b/example/miniapp/miniapp.cpp index 9d90872d..6f43f54a 100644 --- a/example/miniapp/miniapp.cpp +++ b/example/miniapp/miniapp.cpp @@ -7,21 +7,21 @@ #include <arbor/common_types.hpp> #include <arbor/distributed_context.hpp> +#include <arbor/mc_cell.hpp> #include <arbor/profile/meter_manager.hpp> #include <arbor/profile/profiler.hpp> +#include <arbor/sampling.hpp> #include <arbor/threadinfo.hpp> +#include <arbor/util/any.hpp> #include <arbor/version.hpp> #include "communication/communicator.hpp" -#include "cell.hpp" #include "hardware/gpu.hpp" #include "hardware/node_info.hpp" #include "io/exporter_spike_file.hpp" #include "load_balance.hpp" #include "simulation.hpp" -#include "sampling.hpp" #include "schedule.hpp" -#include "util/any.hpp" #include "util/ioutil.hpp" #include "json_meter.hpp" @@ -250,7 +250,7 @@ void report_compartment_stats(const recipe& rec) { for (std::size_t i = 0; i<ncell; ++i) { std::size_t ncomp = 0; auto c = rec.get_cell_description(i); - if (auto ptr = any_cast<cell>(&c)) { + if (auto ptr = any_cast<mc_cell>(&c)) { ncomp = ptr->num_compartments(); } ncomp_total += ncomp; diff --git a/example/miniapp/miniapp_recipes.cpp b/example/miniapp/miniapp_recipes.cpp index b8ab4e14..dc250abc 100644 --- a/example/miniapp/miniapp_recipes.cpp +++ b/example/miniapp/miniapp_recipes.cpp @@ -4,12 +4,12 @@ #include <utility> #include <arbor/assert.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/morphology.hpp> +#include <arbor/spike_source_cell.hpp> +#include <arbor/time_sequence.hpp> -#include "cell.hpp" #include "event_generator.hpp" -#include "morphology.hpp" -#include "spike_source_cell.hpp" -#include "time_sequence.hpp" #include "io.hpp" #include "miniapp_recipes.hpp" @@ -21,14 +21,14 @@ namespace arb { // description for greater data reuse. template <typename RNG> -cell make_basic_cell( +mc_cell make_basic_cell( const morphology& morph, unsigned compartments_per_segment, unsigned num_synapses, const std::string& syn_type, RNG& rng) { - arb::cell cell = make_cell(morph, true); + mc_cell cell = make_mc_cell(morph, true); for (auto& segment: cell.segments()) { if (compartments_per_segment!=0) { diff --git a/example/miniapp/morphology_pool.cpp b/example/miniapp/morphology_pool.cpp index aeda5436..4d3937e4 100644 --- a/example/miniapp/morphology_pool.cpp +++ b/example/miniapp/morphology_pool.cpp @@ -2,9 +2,10 @@ #include <memory> #include <vector> -#include <morphology.hpp> -#include <swcio.hpp> -#include <util/path.hpp> +#include <arbor/morphology.hpp> + +#include "swcio.hpp" +#include "util/path.hpp" #include "morphology_pool.hpp" diff --git a/example/miniapp/morphology_pool.hpp b/example/miniapp/morphology_pool.hpp index 34fb01c8..a7b46230 100644 --- a/example/miniapp/morphology_pool.hpp +++ b/example/miniapp/morphology_pool.hpp @@ -8,8 +8,9 @@ #include <string> #include <vector> -#include <morphology.hpp> -#include <util/path.hpp> +#include <arbor/morphology.hpp> + +#include "util/path.hpp" namespace arb { diff --git a/example/miniapp/trace.hpp b/example/miniapp/trace.hpp index 23db694a..4cf2a29c 100644 --- a/example/miniapp/trace.hpp +++ b/example/miniapp/trace.hpp @@ -8,8 +8,7 @@ #include <vector> #include <arbor/common_types.hpp> - -#include "simple_sampler.hpp" +#include <arbor/simple_sampler.hpp> struct sample_trace { arb::cell_member_type probe_id; diff --git a/arbor/benchmark_cell.hpp b/include/arbor/benchmark_cell.hpp similarity index 93% rename from arbor/benchmark_cell.hpp rename to include/arbor/benchmark_cell.hpp index 6d3c928c..cbb32ba1 100644 --- a/arbor/benchmark_cell.hpp +++ b/include/arbor/benchmark_cell.hpp @@ -1,6 +1,6 @@ #pragma once -#include <time_sequence.hpp> +#include <arbor/time_sequence.hpp> namespace arb { diff --git a/arbor/constants.hpp b/include/arbor/constants.hpp similarity index 100% rename from arbor/constants.hpp rename to include/arbor/constants.hpp diff --git a/arbor/lif_cell_description.hpp b/include/arbor/lif_cell.hpp similarity index 94% rename from arbor/lif_cell_description.hpp rename to include/arbor/lif_cell.hpp index db5f4d50..e2af157a 100644 --- a/arbor/lif_cell_description.hpp +++ b/include/arbor/lif_cell.hpp @@ -3,7 +3,7 @@ namespace arb { // Model parameteres of leaky integrate and fire neuron model. -struct lif_cell_description { +struct lif_cell { // Neuronal parameters. double tau_m = 10; // Membrane potential decaying constant [ms]. double V_th = 10; // Firing threshold [mV]. diff --git a/arbor/cell.hpp b/include/arbor/mc_cell.hpp similarity index 85% rename from arbor/cell.hpp rename to include/arbor/mc_cell.hpp index 0354fd40..b9e4b101 100644 --- a/arbor/cell.hpp +++ b/include/arbor/mc_cell.hpp @@ -5,14 +5,12 @@ #include <vector> #include <arbor/common_types.hpp> -#include <arbor/mechcat.hpp> +#include <arbor/constants.hpp> #include <arbor/ion.hpp> +#include <arbor/mechcat.hpp> +#include <arbor/morphology.hpp> +#include <arbor/mc_segment.hpp> -#include "constants.hpp" -#include "morphology.hpp" -#include "segment.hpp" -#include "tree.hpp" -#include "util/rangeutil.hpp" namespace arb { @@ -60,7 +58,7 @@ struct cell_probe_address { // Global parameter type for cell descriptions. -struct cell_global_properties { +struct mc_cell_global_properties { const mechanism_catalogue* catalogue = &global_default_catalogue(); // If >0, check membrane voltage magnitude is less than limit @@ -86,17 +84,8 @@ struct cell_global_properties { double init_membrane_potential_mV = -65; // [mV] }; -/// Wrapper around compartment layout information derived from a high level cell -/// description. - -struct compartment_model { - arb::tree tree; - std::vector<tree::int_type> parent_index; - std::vector<tree::int_type> segment_index; -}; - /// high-level abstract representation of a cell and its segments -class cell { +class mc_cell { public: using index_type = cell_lid_type; using size_type = cell_local_size_type; @@ -119,10 +108,10 @@ public: }; /// Default constructor - cell(); + mc_cell(); /// Copy constructor - cell(const cell& other): + mc_cell(const mc_cell& other): parents_(other.parents_), stimuli_(other.stimuli_), synapses_(other.synapses_), @@ -136,7 +125,7 @@ public: } /// Move constructor - cell(cell&& other) = default; + mc_cell(mc_cell&& other) = default; /// Return the kind of cell, used for grouping into cell_groups cell_kind get_cell_kind() const { @@ -150,7 +139,7 @@ public: /// add a cable /// parent is the index of the parent segment for the cable section /// cable is the segment that will be moved into the cell - cable_segment* add_cable(index_type parent, segment_ptr&& cable); + cable_segment* add_cable(index_type parent, mc_segment_ptr&& cable); /// add a cable by constructing it in place /// parent is the index of the parent segment for the cable section @@ -163,8 +152,8 @@ public: bool has_soma() const; - class segment* segment(index_type index); - const class segment* segment(index_type index) const; + class mc_segment* segment(index_type index); + const class mc_segment* segment(index_type index) const; /// access pointer to the soma /// returns nullptr if the cell has no soma @@ -176,24 +165,16 @@ public: /// the cable index is not valid cable_segment* cable(index_type index); - /// the volume of the cell - value_type volume() const; - - /// the surface area of the cell - value_type area() const; - /// the total number of compartments over all segments size_type num_compartments() const; - std::vector<segment_ptr> const& segments() const { + std::vector<mc_segment_ptr> const& segments() const { return segments_; } /// return a vector with the compartment count for each segment in the cell std::vector<size_type> compartment_counts() const; - compartment_model model() const; - ////////////////// // stimuli ////////////////// @@ -240,7 +221,12 @@ public: // - volume and area properties of each segment // - number of compartments in each segment // (note: just used for testing: move to test code?) - friend bool cell_basic_equality(const cell&, const cell&); + friend bool cell_basic_equality(const mc_cell&, const mc_cell&); + + // Public view of parent indices vector. + const std::vector<index_type>& parents() const { + return parents_; + } private: void assert_valid_segment(index_type) const; @@ -249,7 +235,7 @@ private: std::vector<index_type> parents_; // the segments - std::vector<segment_ptr> segments_; + std::vector<mc_segment_ptr> segments_; // the stimuli std::vector<stimulus_instance> stimuli_; @@ -263,7 +249,7 @@ private: // create a cable by forwarding cable construction parameters provided by the user template <typename... Args> -cable_segment* cell::add_cable(cell::index_type parent, Args&&... args) +cable_segment* mc_cell::add_cable(mc_cell::index_type parent, Args&&... args) { // check for a valid parent id if(parent>=num_segments()) { @@ -281,6 +267,6 @@ cable_segment* cell::add_cable(cell::index_type parent, Args&&... args) // If compartments_from_discretization is true, set number of compartments in // each segment to be the number of piecewise linear sections in the corresponding // section of the morphologu. -cell make_cell(const morphology&, bool compartments_from_discretization=false); +mc_cell make_mc_cell(const morphology&, bool compartments_from_discretization=false); } // namespace arb diff --git a/arbor/segment.hpp b/include/arbor/mc_segment.hpp similarity index 74% rename from arbor/segment.hpp rename to include/arbor/mc_segment.hpp index 32a2a7f5..c28ec316 100644 --- a/arbor/segment.hpp +++ b/include/arbor/mc_segment.hpp @@ -1,21 +1,21 @@ #pragma once +#include <algorithm> #include <cmath> +#include <memory> +#include <numeric> #include <stdexcept> #include <string> #include <unordered_map> #include <vector> +#include <arbor/assert.hpp> #include <arbor/common_types.hpp> +#include <arbor/morphology.hpp> #include <arbor/mechinfo.hpp> - -#include "algorithms.hpp" -#include "compartment.hpp" -#include "math.hpp" -#include "morphology.hpp" -#include "point.hpp" -#include "util/make_unique.hpp" -#include "util/maputil.hpp" +#include <arbor/point.hpp> +#include <arbor/util/make_unique.hpp> +#include <arbor/util/optional.hpp> namespace arb { @@ -54,8 +54,11 @@ struct mechanism_desc { } double get(const std::string& key) const { - auto optv = util::value_by_key(param_, key); - return optv? *optv: throw std::out_of_range("no field "+key+" set"); + auto i = param_.find(key); + if (i==param_.end()) { + throw std::out_of_range("no field "+key+" set"); + } + return i->second; } const std::unordered_map<std::string, double>& values() const { @@ -74,14 +77,14 @@ class soma_segment; class cable_segment; // abstract base class for a cell segment -class segment { +class mc_segment { public: using value_type = double; using size_type = cell_local_size_type; using point_type = point<value_type>; // (Yet more motivation for a separate morphology description class!) - virtual std::unique_ptr<segment> clone() const = 0; + virtual std::unique_ptr<mc_segment> clone() const = 0; section_kind kind() const { return kind_; @@ -105,10 +108,7 @@ public: virtual size_type num_compartments() const = 0; virtual void set_compartments(size_type) = 0; - virtual value_type volume() const = 0; - virtual value_type area() const = 0; - - virtual ~segment() = default; + virtual ~mc_segment() = default; virtual cable_segment* as_cable() { @@ -164,31 +164,21 @@ public: value_type cm = 0.01; // capacitance [F/m^2] : 10 nF/mm^2 = 0.01 F/m^2 protected: - segment(section_kind kind): kind_(kind) {} + mc_segment(section_kind kind): kind_(kind) {} section_kind kind_; std::vector<mechanism_desc> mechanisms_; }; -class placeholder_segment : public segment { +class placeholder_segment : public mc_segment { public: - placeholder_segment(): segment(section_kind::none) {} + placeholder_segment(): mc_segment(section_kind::none) {} - std::unique_ptr<segment> clone() const override { + std::unique_ptr<mc_segment> clone() const override { // use default copy constructor return util::make_unique<placeholder_segment>(*this); } - value_type volume() const override - { - return std::numeric_limits<value_type>::quiet_NaN(); - } - - value_type area() const override - { - return std::numeric_limits<value_type>::quiet_NaN(); - } - bool is_placeholder() const override { return true; @@ -202,28 +192,18 @@ public: virtual void set_compartments(size_type) override {} }; -class soma_segment : public segment { +class soma_segment : public mc_segment { public: soma_segment() = delete; explicit soma_segment(value_type r, point_type c = point_type{}): - segment(section_kind::soma), radius_{r}, center_(c) {} + mc_segment(section_kind::soma), radius_{r}, center_(c) {} - std::unique_ptr<segment> clone() const override { + std::unique_ptr<mc_segment> clone() const override { // use default copy constructor return util::make_unique<soma_segment>(*this); } - value_type volume() const override - { - return math::volume_sphere(radius_); - } - - value_type area() const override - { - return math::area_sphere(radius_); - } - value_type radius() const { return radius_; @@ -259,9 +239,9 @@ private : point_type center_; }; -class cable_segment : public segment { +class cable_segment : public mc_segment { public: - using base = segment; + using base = mc_segment; using base::kind_; using base::value_type; using base::point_type; @@ -271,7 +251,7 @@ public: // constructors for a cable with no location information cable_segment(section_kind k, std::vector<value_type> r, std::vector<value_type> lens): - segment(k), radii_(std::move(r)), lengths_(std::move(lens)) + mc_segment(k), radii_(std::move(r)), lengths_(std::move(lens)) { arb_assert(kind_==section_kind::dendrite || kind_==section_kind::axon); } @@ -283,7 +263,7 @@ public: // constructor that lets the user describe the cable as a // seriew of radii and locations cable_segment(section_kind k, std::vector<value_type> r, std::vector<point_type> p): - segment(k), radii_(std::move(r)), locations_(std::move(p)) + mc_segment(k), radii_(std::move(r)), locations_(std::move(p)) { arb_assert(kind_==section_kind::dendrite || kind_==section_kind::axon); update_lengths(); @@ -302,32 +282,14 @@ public: cable_segment(k, {r1, r2}, {p1, p2}) {} - std::unique_ptr<segment> clone() const override { + std::unique_ptr<mc_segment> clone() const override { // use default copy constructor return util::make_unique<cable_segment>(*this); } - value_type volume() const override - { - auto sum = value_type{0}; - for (auto i=0u; i<num_sub_segments(); ++i) { - sum += math::volume_frustrum(lengths_[i], radii_[i], radii_[i+1]); - } - return sum; - } - - value_type area() const override - { - auto sum = value_type{0}; - for (auto i=0u; i<num_sub_segments(); ++i) { - sum += math::area_frustrum(lengths_[i], radii_[i], radii_[i+1]); - } - return sum; - } - value_type length() const { - return algorithms::sum(lengths_); + return std::accumulate(lengths_.begin(), lengths_.end(), value_type{}); } bool has_locations() const @@ -402,12 +364,6 @@ public: return rel*radii_[i] + (1.-rel)*radii_[i+1]; } - /// iterable range type for simple compartment representation - compartment_range<size_type, value_type> compartments() const - { - return make_compartment_range(num_compartments(), radii_.front(), radii_.back(), length()); - } - private: void update_lengths() { if (locations_.size()) { @@ -424,27 +380,14 @@ private: std::vector<point_type> locations_; }; -/// Unique pointer wrapper for abstract segment base class -using segment_ptr = std::unique_ptr<segment>; +using mc_segment_ptr = std::unique_ptr<mc_segment>; /// Helper for constructing segments in a segment_ptr unique pointer wrapper. /// Forwards the supplied arguments to construct a segment of type SegmentType. /// e.g. auto my_cable = make_segment<cable>(section_kind::dendrite, ... ); template <typename SegmentType, typename... Args> -segment_ptr make_segment(Args&&... args) { - return segment_ptr(new SegmentType(std::forward<Args>(args)...)); -} - -/// Divided compartment adaptors for cable segments - -template <typename DivCompClass> -DivCompClass div_compartments(const cable_segment* cable, unsigned ncomp) { - return DivCompClass(ncomp, cable->radii(), cable->lengths()); -} - -template <typename DivCompClass> -DivCompClass div_compartments(const cable_segment* cable) { - return DivCompClass(cable->num_compartments(), cable->radii(), cable->lengths()); +mc_segment_ptr make_segment(Args&&... args) { + return mc_segment_ptr(new SegmentType(std::forward<Args>(args)...)); } } // namespace arb diff --git a/arbor/morphology.hpp b/include/arbor/morphology.hpp similarity index 100% rename from arbor/morphology.hpp rename to include/arbor/morphology.hpp diff --git a/arbor/point.hpp b/include/arbor/point.hpp similarity index 100% rename from arbor/point.hpp rename to include/arbor/point.hpp diff --git a/arbor/sampling.hpp b/include/arbor/sampling.hpp similarity index 95% rename from arbor/sampling.hpp rename to include/arbor/sampling.hpp index 04337633..97a89cd4 100644 --- a/arbor/sampling.hpp +++ b/include/arbor/sampling.hpp @@ -4,8 +4,7 @@ #include <functional> #include <arbor/common_types.hpp> - -#include "util/any_ptr.hpp" +#include <arbor/util/any_ptr.hpp> namespace arb { diff --git a/arbor/simd/approx.hpp b/include/arbor/simd/approx.hpp similarity index 100% rename from arbor/simd/approx.hpp rename to include/arbor/simd/approx.hpp diff --git a/arbor/simd/avx.hpp b/include/arbor/simd/avx.hpp similarity index 99% rename from arbor/simd/avx.hpp rename to include/arbor/simd/avx.hpp index ae3dd27e..78a566f0 100644 --- a/arbor/simd/avx.hpp +++ b/include/arbor/simd/avx.hpp @@ -8,8 +8,8 @@ #include <cstdint> #include <immintrin.h> -#include <simd/approx.hpp> -#include <simd/implbase.hpp> +#include <arbor/simd/approx.hpp> +#include <arbor/simd/implbase.hpp> namespace arb { namespace simd { diff --git a/arbor/simd/avx512.hpp b/include/arbor/simd/avx512.hpp similarity index 99% rename from arbor/simd/avx512.hpp rename to include/arbor/simd/avx512.hpp index 6f123612..dd723c3f 100644 --- a/arbor/simd/avx512.hpp +++ b/include/arbor/simd/avx512.hpp @@ -8,8 +8,8 @@ #include <cstdint> #include <immintrin.h> -#include <simd/approx.hpp> -#include <simd/implbase.hpp> +#include <arbor/simd/approx.hpp> +#include <arbor/simd/implbase.hpp> namespace arb { namespace simd { diff --git a/arbor/simd/generic.hpp b/include/arbor/simd/generic.hpp similarity index 97% rename from arbor/simd/generic.hpp rename to include/arbor/simd/generic.hpp index e8ca5524..fecdb37f 100644 --- a/arbor/simd/generic.hpp +++ b/include/arbor/simd/generic.hpp @@ -4,7 +4,7 @@ #include <cstring> #include <cmath> -#include <simd/implbase.hpp> +#include <arbor/simd/implbase.hpp> namespace arb { namespace simd { diff --git a/arbor/simd/implbase.hpp b/include/arbor/simd/implbase.hpp similarity index 100% rename from arbor/simd/implbase.hpp rename to include/arbor/simd/implbase.hpp diff --git a/arbor/simd/native.hpp b/include/arbor/simd/native.hpp similarity index 100% rename from arbor/simd/native.hpp rename to include/arbor/simd/native.hpp diff --git a/arbor/simd/simd.hpp b/include/arbor/simd/simd.hpp similarity index 99% rename from arbor/simd/simd.hpp rename to include/arbor/simd/simd.hpp index b863a283..2bb0c0bb 100644 --- a/arbor/simd/simd.hpp +++ b/include/arbor/simd/simd.hpp @@ -4,9 +4,9 @@ #include <cstddef> #include <type_traits> -#include <simd/implbase.hpp> -#include <simd/generic.hpp> -#include <simd/native.hpp> +#include <arbor/simd/implbase.hpp> +#include <arbor/simd/generic.hpp> +#include <arbor/simd/native.hpp> namespace arb { namespace simd { diff --git a/arbor/simd/simd_io.hpp b/include/arbor/simd/simd_io.hpp similarity index 94% rename from arbor/simd/simd_io.hpp rename to include/arbor/simd/simd_io.hpp index 3cc4c841..96ead475 100644 --- a/arbor/simd/simd_io.hpp +++ b/include/arbor/simd/simd_io.hpp @@ -4,7 +4,7 @@ #include <iostream> -#include <simd/simd.hpp> +#include <arbor/simd/simd.hpp> namespace arb { namespace simd { diff --git a/arbor/simple_sampler.hpp b/include/arbor/simple_sampler.hpp similarity index 53% rename from arbor/simple_sampler.hpp rename to include/arbor/simple_sampler.hpp index 8d85ab80..480f59cd 100644 --- a/arbor/simple_sampler.hpp +++ b/include/arbor/simple_sampler.hpp @@ -5,15 +5,13 @@ * trace data from a cell probe, with some metadata. */ +#include <stdexcept> +#include <type_traits> #include <vector> #include <arbor/common_types.hpp> - -#include "sampling.hpp" -#include "util/any_ptr.hpp" -#include "util/deduce_return.hpp" -#include "util/span.hpp" -#include "util/transform.hpp" +#include <arbor/sampling.hpp> +#include <arbor/util/any_ptr.hpp> namespace arb { @@ -26,34 +24,13 @@ struct trace_entry { template <typename V> using trace_data = std::vector<trace_entry<V>>; -// NB: work-around for lack of function return type deduction -// in C++11; can't use lambda within DEDUCED_RETURN_TYPE. - -namespace impl { - template <typename V> - inline float time(const trace_entry<V>& x) { return x.t; } - - template <typename V> - inline const V& value(const trace_entry<V>& x) { return x.v; } -} - -template <typename V> -inline auto times(const trace_data<V>& trace) DEDUCED_RETURN_TYPE( - util::transform_view(trace, impl::time<V>) -) - -template <typename V> -inline auto values(const trace_data<V>& trace) DEDUCED_RETURN_TYPE( - util::transform_view(trace, impl::value<V>) -) - -template <typename V, typename = util::enable_if_trivially_copyable_t<V>> +template <typename V, typename = typename std::enable_if<std::is_trivially_copyable<V>::value>::type> class simple_sampler { public: explicit simple_sampler(trace_data<V>& trace): trace_(trace) {} void operator()(cell_member_type probe_id, probe_tag tag, std::size_t n, const sample_record* recs) { - for (auto i: util::make_span(0, n)) { + for (std::size_t i = 0; i<n; ++i) { if (auto p = util::any_cast<const V*>(recs[i].data)) { trace_.push_back({recs[i].time, *p}); } diff --git a/arbor/spike_source_cell.hpp b/include/arbor/spike_source_cell.hpp similarity index 87% rename from arbor/spike_source_cell.hpp rename to include/arbor/spike_source_cell.hpp index 489d1300..74b66e5b 100644 --- a/arbor/spike_source_cell.hpp +++ b/include/arbor/spike_source_cell.hpp @@ -1,6 +1,6 @@ #pragma once -#include <time_sequence.hpp> +#include <arbor/time_sequence.hpp> namespace arb { diff --git a/arbor/time_sequence.hpp b/include/arbor/time_sequence.hpp similarity index 96% rename from arbor/time_sequence.hpp rename to include/arbor/time_sequence.hpp index d9845599..5b0fb9ef 100644 --- a/arbor/time_sequence.hpp +++ b/include/arbor/time_sequence.hpp @@ -3,11 +3,10 @@ #include <algorithm> #include <memory> #include <random> +#include <type_traits> #include <arbor/common_types.hpp> -#include "event_queue.hpp" -#include "util/meta.hpp" #include "util/rangeutil.hpp" namespace arb { @@ -33,9 +32,10 @@ public: template < typename Impl, - typename = typename util::enable_if_t< + typename = typename std::enable_if< !std::is_same<typename std::decay<Impl>::type, - time_seq>::value>> + time_seq>::value>::type + > time_seq(Impl&& impl): impl_(new wrap<Impl>(std::forward<Impl>(impl))) {} @@ -123,8 +123,8 @@ struct vector_time_seq { seq_(std::move(seq)) { // Ensure that the time values are sorted. - if(!std::is_sorted(seq_.begin(), seq_.end())) { - util::sort(seq_); + if (!std::is_sorted(seq_.begin(), seq_.end())) { + std::sort(seq_.begin(), seq_.end()); } reset(); } diff --git a/arbor/util/any.hpp b/include/arbor/util/any.hpp similarity index 94% rename from arbor/util/any.hpp rename to include/arbor/util/any.hpp index 1bc1e587..1854f06d 100644 --- a/arbor/util/any.hpp +++ b/include/arbor/util/any.hpp @@ -4,8 +4,6 @@ #include <typeinfo> #include <type_traits> -#include <util/meta.hpp> - // Partial implementation of std::any from C++17 standard. // http://en.cppreference.com/w/cpp/utility/any // @@ -40,10 +38,10 @@ public: template < typename T, - typename = typename util::enable_if_t<!std::is_same<util::decay_t<T>, any>::value> + typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, any>::value>::type > any(T&& other) { - using contained_type = util::decay_t<T>; + using contained_type = typename std::decay<T>::type; static_assert(std::is_copy_constructible<contained_type>::value, "Type of contained object stored in any must satisfy the CopyConstructible requirements."); @@ -62,10 +60,10 @@ public: template < typename T, - typename = typename util::enable_if_t<!std::is_same<util::decay_t<T>, any>::value> + typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, any>::value>::type > any& operator=(T&& other) { - using contained_type = util::decay_t<T>; + using contained_type = typename std::decay<T>::type; static_assert(std::is_copy_constructible<contained_type>::value, "Type of contained object stored in any must satisfy the CopyConstructible requirements."); diff --git a/arbor/util/any_ptr.hpp b/include/arbor/util/any_ptr.hpp similarity index 100% rename from arbor/util/any_ptr.hpp rename to include/arbor/util/any_ptr.hpp diff --git a/arbor/util/make_unique.hpp b/include/arbor/util/make_unique.hpp similarity index 74% rename from arbor/util/make_unique.hpp rename to include/arbor/util/make_unique.hpp index 6b345c12..af0b80b0 100644 --- a/arbor/util/make_unique.hpp +++ b/include/arbor/util/make_unique.hpp @@ -5,8 +5,8 @@ namespace arb { namespace util { -// just because we aren't using C++14, doesn't mean we shouldn't go -// without make_unique +// TODO: Remove when migrate to C++14 + template <typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args) ...)); diff --git a/arbor/util/unique_any.hpp b/include/arbor/util/unique_any.hpp similarity index 91% rename from arbor/util/unique_any.hpp rename to include/arbor/util/unique_any.hpp index 5091cc56..cae9edbe 100644 --- a/arbor/util/unique_any.hpp +++ b/include/arbor/util/unique_any.hpp @@ -4,8 +4,7 @@ #include <typeinfo> #include <type_traits> -#include <util/any.hpp> -#include <util/meta.hpp> +#include <arbor/util/any.hpp> // A non copyable variant of util::any. // The two main use cases for such a container are @@ -57,11 +56,10 @@ public: template < typename T, - typename = typename util::enable_if_t<!std::is_same<util::decay_t<T>, unique_any>::value> + typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, unique_any>::value>::type > unique_any(T&& other) { - using contained_type = util::decay_t<T>; - state_.reset(new model<contained_type>(std::forward<T>(other))); + state_.reset(new model<contained_type<T>>(std::forward<T>(other))); } unique_any& operator=(unique_any&& other) noexcept { @@ -71,11 +69,10 @@ public: template < typename T, - typename = typename util::enable_if_t<!std::is_same<util::decay_t<T>, unique_any>::value> + typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, unique_any>::value>::type > unique_any& operator=(T&& other) { - using contained_type = util::decay_t<T>; - state_.reset(new model<contained_type>(std::forward<T>(other))); + state_.reset(new model<contained_type<T>>(std::forward<T>(other))); return *this; } @@ -96,6 +93,9 @@ public: } private: + template <typename T> + using contained_type = typename std::decay<T>::type; + struct interface { virtual ~interface() = default; virtual const std::type_info& type() = 0; diff --git a/lmorpho/lmorpho.cpp b/lmorpho/lmorpho.cpp index 960981a1..b4f5492b 100644 --- a/lmorpho/lmorpho.cpp +++ b/lmorpho/lmorpho.cpp @@ -6,9 +6,9 @@ #include <vector> #include <tinyopt.hpp> +#include <arbor/morphology.hpp> #include <arbor/util/optional.hpp> -#include "morphology.hpp" #include "morphio.hpp" #include "lsystem.hpp" #include "lsys_models.hpp" diff --git a/lmorpho/lsystem.cpp b/lmorpho/lsystem.cpp index a4baddd8..feddc70c 100644 --- a/lmorpho/lsystem.cpp +++ b/lmorpho/lsystem.cpp @@ -4,8 +4,9 @@ #include <stack> #include <vector> -#include <math.hpp> -#include <morphology.hpp> +#include <arbor/morphology.hpp> + +#include "math.hpp" #include "lsystem.hpp" diff --git a/lmorpho/lsystem.hpp b/lmorpho/lsystem.hpp index 1feb6f0f..55e5beda 100644 --- a/lmorpho/lsystem.hpp +++ b/lmorpho/lsystem.hpp @@ -2,7 +2,7 @@ #include <random> -#include <morphology.hpp> +#include <arbor/morphology.hpp> struct lsys_param; diff --git a/lmorpho/morphio.cpp b/lmorpho/morphio.cpp index 9c354729..ee319dda 100644 --- a/lmorpho/morphio.cpp +++ b/lmorpho/morphio.cpp @@ -4,9 +4,10 @@ #include <string> #include <vector> -#include <morphology.hpp> -#include <swcio.hpp> -#include <util/strprintf.hpp> +#include <arbor/morphology.hpp> + +#include "swcio.hpp" +#include "util/strprintf.hpp" #include "morphio.hpp" diff --git a/lmorpho/morphio.hpp b/lmorpho/morphio.hpp index 0cc4f703..3d31dab7 100644 --- a/lmorpho/morphio.hpp +++ b/lmorpho/morphio.hpp @@ -4,7 +4,7 @@ #include <iostream> #include <vector> -#include <morphology.hpp> +#include <arbor/morphology.hpp> // Manage access to a single file, std::cout, or an indexed // sequence of files. diff --git a/modcc/printer/cprinter.cpp b/modcc/printer/cprinter.cpp index d9ba01ac..6a0cc330 100644 --- a/modcc/printer/cprinter.cpp +++ b/modcc/printer/cprinter.cpp @@ -141,7 +141,7 @@ std::string emit_cpp_source(const Module& module_, const printer_options& opt) { out << "#include <" << arb_header_prefix() << "profile/profiler.hpp>\n"; if (with_simd) { - out << "#include <" << arb_private_header_prefix() << "simd/simd.hpp>\n"; + out << "#include <" << arb_header_prefix() << "simd/simd.hpp>\n"; } out << diff --git a/test/common_cells.hpp b/test/common_cells.hpp index 06ac14f3..3ced9dcb 100644 --- a/test/common_cells.hpp +++ b/test/common_cells.hpp @@ -1,11 +1,10 @@ #include <cmath> +#include <arbor/mc_cell.hpp> +#include <arbor/mc_segment.hpp> #include <arbor/mechinfo.hpp> -#include "cell.hpp" #include "recipe.hpp" -#include "segment.hpp" -#include "math.hpp" namespace arb { @@ -22,8 +21,8 @@ namespace arb { * soma centre, t=[10 ms, 110 ms), 0.1 nA */ -inline cell make_cell_soma_only(bool with_stim = true) { - cell c; +inline mc_cell make_cell_soma_only(bool with_stim = true) { + mc_cell c; auto soma = c.add_soma(18.8/2.0); soma->add_mechanism("hh"); @@ -56,8 +55,8 @@ inline cell make_cell_soma_only(bool with_stim = true) { * end of dendrite, t=[5 ms, 85 ms), 0.3 nA */ -inline cell make_cell_ball_and_stick(bool with_stim = true) { - cell c; +inline mc_cell make_cell_ball_and_stick(bool with_stim = true) { + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("hh"); @@ -100,8 +99,8 @@ inline cell make_cell_ball_and_stick(bool with_stim = true) { * end of dendrite, t=[5 ms, 85 ms), 0.3 nA */ -inline cell make_cell_ball_and_taper(bool with_stim = true) { - cell c; +inline mc_cell make_cell_ball_and_taper(bool with_stim = true) { + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("hh"); @@ -142,14 +141,14 @@ inline cell make_cell_ball_and_taper(bool with_stim = true) { * end of dendrite, t=[5 ms, 85 ms), 0.3 nA */ -inline cell make_cell_ball_and_squiggle(bool with_stim = true) { - cell c; +inline mc_cell make_cell_ball_and_squiggle(bool with_stim = true) { + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("hh"); - std::vector<cell::value_type> radii; - std::vector<cell::point_type> points; + std::vector<mc_cell::value_type> radii; + std::vector<mc_cell::point_type> points; double length = 100.0; int npoints = 200; @@ -203,8 +202,8 @@ inline cell make_cell_ball_and_squiggle(bool with_stim = true) { * end of second terminal branch, t=[40 ms, 50 ms), -0.2 nA */ -inline cell make_cell_ball_and_3stick(bool with_stim = true) { - cell c; +inline mc_cell make_cell_ball_and_3stick(bool with_stim = true) { + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("hh"); @@ -248,8 +247,8 @@ inline cell make_cell_ball_and_3stick(bool with_stim = true) { * work-around for some existing fvm modelling issues. */ -inline cell make_cell_simple_cable(bool with_stim = true) { - cell c; +inline mc_cell make_cell_simple_cable(bool with_stim = true) { + mc_cell c; c.add_soma(0); c.add_cable(0, section_kind::dendrite, 0.5, 0.5, 1000); @@ -275,7 +274,7 @@ inline cell make_cell_simple_cable(bool with_stim = true) { if (with_stim) { // stimulus in the middle of our zero-volume 'soma' // corresponds to proximal end of cable. - c.add_stimulus({0,0.5}, {0., math::infinity<>(), I}); + c.add_stimulus({0,0.5}, {0., INFINITY, I}); } return c; } diff --git a/test/simple_recipes.hpp b/test/simple_recipes.hpp index 9830dee0..531c66d8 100644 --- a/test/simple_recipes.hpp +++ b/test/simple_recipes.hpp @@ -5,7 +5,8 @@ #include <unordered_map> #include <vector> -#include <cell.hpp> +#include <arbor/mc_cell.hpp> + #include <event_generator.hpp> #include <recipe.hpp> @@ -52,7 +53,7 @@ public: protected: std::unordered_map<cell_gid_type, std::vector<probe_info>> probes_; - cell_global_properties cell_gprop_; + mc_cell_global_properties cell_gprop_; mechanism_catalogue catalogue_; }; @@ -98,7 +99,7 @@ public: } } - explicit cable1d_recipe(const cell& c) { + explicit cable1d_recipe(const mc_cell& c) { cells_.reserve(1); cells_.emplace_back(c); } @@ -115,11 +116,11 @@ public: } util::unique_any get_cell_description(cell_gid_type i) const override { - return util::make_unique_any<cell>(cells_[i]); + return util::make_unique_any<mc_cell>(cells_[i]); } protected: - std::vector<cell> cells_; + std::vector<mc_cell> cells_; }; diff --git a/test/ubench/mech_vec.cpp b/test/ubench/mech_vec.cpp index 58c1643b..6f61d726 100644 --- a/test/ubench/mech_vec.cpp +++ b/test/ubench/mech_vec.cpp @@ -2,10 +2,13 @@ // // Start with pas (passive dendrite) mechanism +#include <fstream> + +#include <arbor/mc_cell.hpp> + #include <backends/multicore/fvm.hpp> #include <benchmark/benchmark.h> #include <fvm_lowered_cell_impl.hpp> -#include <fstream> using namespace arb; @@ -36,7 +39,7 @@ public: } virtual util::unique_any get_cell_description(cell_gid_type gid) const override { - cell c; + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("pas"); @@ -75,7 +78,7 @@ public: } virtual util::unique_any get_cell_description(cell_gid_type gid) const override { - cell c; + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("pas"); @@ -107,7 +110,7 @@ public: } virtual util::unique_any get_cell_description(cell_gid_type gid) const override { - cell c; + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("pas"); @@ -141,7 +144,7 @@ public: } virtual util::unique_any get_cell_description(cell_gid_type gid) const override { - cell c; + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("hh"); @@ -173,7 +176,7 @@ public: } virtual util::unique_any get_cell_description(cell_gid_type gid) const override { - cell c; + mc_cell c; auto soma = c.add_soma(12.6157/2.0); soma->add_mechanism("pas"); diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 094e03fd..887ffe53 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -26,7 +26,6 @@ set(unit_sources test_any.cpp test_backend.cpp test_double_buffer.cpp - test_cell.cpp test_compartments.cpp test_counter.cpp test_cycle.cpp @@ -45,6 +44,7 @@ set(unit_sources test_mask_stream.cpp test_math.cpp test_matrix.cpp + test_mc_cell.cpp test_mechanisms.cpp test_mechcat.cpp test_merge_events.cpp diff --git a/test/unit/test_any.cpp b/test/unit/test_any.cpp index cce483f6..03dd829a 100644 --- a/test/unit/test_any.cpp +++ b/test/unit/test_any.cpp @@ -1,14 +1,12 @@ -//#include <iostream> #include <type_traits> +#include <typeinfo> + +#include <arbor/util/any.hpp> +#include <arbor/util/any_ptr.hpp> #include "../gtest.h" #include "common.hpp" -#include <util/any.hpp> -#include <util/any_ptr.hpp> - -#include <typeinfo> - using namespace arb; using namespace testing::string_literals; diff --git a/test/unit/test_compartments.cpp b/test/unit/test_compartments.cpp index ac4503eb..9d5c711f 100644 --- a/test/unit/test_compartments.cpp +++ b/test/unit/test_compartments.cpp @@ -3,69 +3,18 @@ #include "../gtest.h" -#include <algorithms.hpp> -#include <compartment.hpp> - -#include <math.hpp> -#include <util/span.hpp> -#include <util/transform.hpp> +#include "algorithms.hpp" +#include "fvm_compartment.hpp" +#include "math.hpp" +#include "util/span.hpp" +#include "util/transform.hpp" using namespace arb; -using namespace arb::algorithms; using namespace arb::math; -using namespace arb::util; - -// not much to test here: just test that values passed into the constructor -// are correctly stored in members -TEST(compartments, compartment) -{ - { - arb::compartment c(100, 1.2, 2.1, 2.2); - EXPECT_EQ(c.index, 100u); - EXPECT_EQ(c.length, 1.2); - EXPECT_EQ(c.radius.first, 2.1); - EXPECT_EQ(c.radius.second, 2.2); - - auto c2 = c; - EXPECT_EQ(c2.index, 100u); - EXPECT_EQ(c2.length, 1.2); - EXPECT_EQ(c2.radius.first, 2.1); - EXPECT_EQ(c2.radius.second, 2.2); - } - - { - arb::compartment c{100, 1, 2, 3}; - EXPECT_EQ(c.index, 100u); - EXPECT_EQ(c.length, 1.); - EXPECT_EQ(c.radius.first, 2.); - EXPECT_EQ(c.radius.second, 3.); - } -} - -TEST(compartments, make_compartment_range) -{ - using namespace arb; - auto rng = make_compartment_range(10, 1.0, 2.0, 10.); - - EXPECT_EQ((*rng.begin()).index, 0u); - EXPECT_EQ((*rng.end()).index, 10u); - EXPECT_NE(rng.begin(), rng.end()); - - unsigned count = 0; - for (auto c : rng) { - EXPECT_EQ(c.index, count); - auto er = 1.0 + double(count)/10.; - EXPECT_DOUBLE_EQ(c.radius.first, er); - EXPECT_DOUBLE_EQ(c.radius.second, er+0.1); - EXPECT_EQ(c.length, 1.0); - ++count; - } - EXPECT_EQ(count, 10u); - // test case of zero length range - auto rng_empty = make_compartment_range(0, 1.0, 1.0, 0.); - EXPECT_EQ(rng_empty.begin(), rng_empty.end()); -} +using arb::util::make_span; +using arb::util::transform_view; +using arb::algorithms::sum; // Divided compartments // (FVM-friendly compartment data) @@ -81,12 +30,12 @@ struct pw_cable_data { double length() const { return sum(lengths); } double area() const { - return sum(transform_view(make_span(0, N), + return sum(transform_view(make_span(N), [&](unsigned i) { return area_frustrum(lengths[i], radii[i], radii[i+1]); })); } double volume() const { - return sum(transform_view(make_span(0, N), + return sum(transform_view(make_span(N), [&](unsigned i) { return volume_frustrum(lengths[i], radii[i], radii[i+1]); })); } }; @@ -128,8 +77,6 @@ void expect_equal_divs(const div_compartment& da, const div_compartment& db) { } TEST(compartments, div_ends) { - using namespace math; - { div_compartment_by_ends divcomps{1, cable_one.radii, cable_one.lengths}; @@ -183,8 +130,6 @@ TEST(compartments, div_ends) { } TEST(compartments, div_sample) { - using namespace math; - // expect by_ends and sampler to give same results on linear cable { constexpr unsigned ncomp = 7; @@ -223,10 +168,10 @@ TEST(compartments, div_sample) { unsigned ncomp = m*nbase; div_compartment_sampler divs{ncomp, cable_jumble.radii, cable_jumble.lengths}; - double area = sum(transform_view(make_span(0, ncomp), + double area = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).area(); })); - double volume = sum(transform_view(make_span(0, ncomp), + double volume = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).volume(); })); double e2 = std::min(area, area_expected)*ncomp*eps; @@ -247,10 +192,10 @@ TEST(compartments, div_sample) { unsigned ncomp = m*nbase+1u; div_compartment_sampler divs{ncomp, cable_jumble.radii, cable_jumble.lengths}; - double area = sum(transform_view(make_span(0, ncomp), + double area = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).area(); })); - double volume = sum(transform_view(make_span(0, ncomp), + double volume = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).volume(); })); SCOPED_TRACE("cable_jumble ncomp "+std::to_string(ncomp)); @@ -267,8 +212,6 @@ TEST(compartments, div_sample) { } TEST(compartments, div_integrator) { - using namespace math; - // expect integrator and sampler to give same results on linear cable { constexpr unsigned ncomp = 7; @@ -296,10 +239,10 @@ TEST(compartments, div_integrator) { for (unsigned ncomp: make_span(1u, 23u)) { div_compartment_integrator divs{ncomp, cable_jumble.radii, cable_jumble.lengths}; - double area = sum(transform_view(make_span(0, ncomp), + double area = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).area(); })); - double volume = sum(transform_view(make_span(0, ncomp), + double volume = sum(transform_view(make_span(ncomp), [&](unsigned i) { return divs(i).volume(); })); double e2 = std::min(area, area_expected)*ncomp*eps; diff --git a/test/unit/test_domain_decomposition.cpp b/test/unit/test_domain_decomposition.cpp index 0dae331c..16dd8785 100644 --- a/test/unit/test_domain_decomposition.cpp +++ b/test/unit/test_domain_decomposition.cpp @@ -8,10 +8,12 @@ #include "domain_decomposition.hpp" #include "hardware/node_info.hpp" #include "load_balance.hpp" +#include "util/span.hpp" #include "../simple_recipes.hpp" using namespace arb; +using arb::util::make_span; namespace { // Dummy recipes types for testing. @@ -63,7 +65,7 @@ TEST(domain_decomposition, homogenous_population) EXPECT_EQ(D.num_local_cells, num_cells); EXPECT_EQ(D.groups.size(), num_cells); - auto gids = util::make_span(0, num_cells); + auto gids = make_span(num_cells); for (auto gid: gids) { EXPECT_EQ(0, D.gid_domain(gid)); } @@ -89,7 +91,7 @@ TEST(domain_decomposition, homogenous_population) EXPECT_EQ(D.num_local_cells, num_cells); EXPECT_EQ(D.groups.size(), 1u); - auto gids = util::make_span(0, num_cells); + auto gids = make_span(num_cells); for (auto gid: gids) { EXPECT_EQ(0, D.gid_domain(gid)); } @@ -124,14 +126,14 @@ TEST(domain_decomposition, heterogenous_population) EXPECT_EQ(D.num_local_cells, num_cells); EXPECT_EQ(D.groups.size(), num_cells); - auto gids = util::make_span(0, num_cells); + auto gids = make_span(num_cells); for (auto gid: gids) { EXPECT_EQ(0, D.gid_domain(gid)); } // Each cell group contains 1 cell of kind cable1d_neuron // Each group should also be tagged for cpu execution - auto grps = util::make_span(0, num_cells); + auto grps = make_span(num_cells); std::map<cell_kind, std::set<cell_gid_type>> kind_lists; for (auto i: grps) { auto& grp = D.groups[i]; @@ -164,7 +166,7 @@ TEST(domain_decomposition, heterogenous_population) auto expected_groups = num_cells/2+1; EXPECT_EQ(D.groups.size(), expected_groups); - auto grps = util::make_span(0, expected_groups); + auto grps = make_span(expected_groups); unsigned ncells = 0; // iterate over each group and test its properties for (auto i: grps) { diff --git a/test/unit/test_fvm_layout.cpp b/test/unit/test_fvm_layout.cpp index d5a96bb5..2389e9f6 100644 --- a/test/unit/test_fvm_layout.cpp +++ b/test/unit/test_fvm_layout.cpp @@ -2,8 +2,8 @@ #include <arbor/util/optional.hpp> #include <arbor/mechcat.hpp> +#include <arbor/mc_cell.hpp> -#include "cell.hpp" #include "fvm_layout.hpp" #include "math.hpp" #include "util/maputil.hpp" @@ -20,80 +20,116 @@ using util::make_span; using util::count_along; using util::value_by_key; -std::vector<cell> two_cell_system() { - std::vector<cell> cells; - - // Cell 0: simple ball and stick (see common_cells.hpp) - cells.push_back(make_cell_ball_and_stick()); - - // Cell 1: ball and 3-stick, but with uneven dendrite - // length and heterogeneous electrical properties: - // - // Bulk resistivity: 90 Ω·cm - // capacitance: - // soma: 0.01 F/m² [default] - // segment 1: 0.017 F/m² - // segment 2: 0.013 F/m² - // segment 3: 0.018 F/m² - // - // Soma diameter: 14 µm - // Some mechanisms: HH (default params) - // - // Segment 1 diameter: 1 µm - // Segment 1 length: 200 µm - // - // Segment 2 diameter: 0.8 µm - // Segment 2 length: 300 µm - // - // Segment 3 diameter: 0.7 µm - // Segment 3 length: 180 µm - // - // Dendrite mechanisms: passive (default params). - // Stimulus at end of segment 2, amplitude 0.45. - // Stimulus at end of segment 3, amplitude -0.2. - // - // All dendrite segments with 4 compartments. - - cell c2; - segment* s; - - s = c2.add_soma(14./2); - s->add_mechanism("hh"); - - s = c2.add_cable(0, section_kind::dendrite, 1.0/2, 1.0/2, 200); - s->cm = 0.017; - - s = c2.add_cable(1, section_kind::dendrite, 0.8/2, 0.8/2, 300); - s->cm = 0.013; - - s = c2.add_cable(1, section_kind::dendrite, 0.7/2, 0.7/2, 180); - s->cm = 0.018; +namespace { + double area(const mc_segment* s) { + if (auto soma = s->as_soma()) { + return math::area_sphere(soma->radius()); + } + else if (auto cable = s->as_cable()) { + unsigned nc = cable->num_sub_segments(); + double a = 0; + for (unsigned i = 0; i<nc; ++i) { + a += math::area_frustrum(cable->lengths()[i], cable->radii()[i], cable->radii()[i+1]); + } + return a; + } + else { + return 0; + } + } - c2.add_stimulus({2,1}, {5., 80., 0.45}); - c2.add_stimulus({3,1}, {40., 10.,-0.2}); + double volume(const mc_segment* s) { + if (auto soma = s->as_soma()) { + return math::volume_sphere(soma->radius()); + } + else if (auto cable = s->as_cable()) { + unsigned nc = cable->num_sub_segments(); + double v = 0; + for (unsigned i = 0; i<nc; ++i) { + v += math::volume_frustrum(cable->lengths()[i], cable->radii()[i], cable->radii()[i+1]); + } + return v; + } + else { + return 0; + } + } - for (auto& seg: c2.segments()) { - seg->rL = 90.; - if (seg->is_dendrite()) { - seg->add_mechanism("pas"); - seg->set_compartments(4); + std::vector<mc_cell> two_cell_system() { + std::vector<mc_cell> cells; + + // Cell 0: simple ball and stick (see common_cells.hpp) + cells.push_back(make_cell_ball_and_stick()); + + // Cell 1: ball and 3-stick, but with uneven dendrite + // length and heterogeneous electrical properties: + // + // Bulk resistivity: 90 Ω·cm + // capacitance: + // soma: 0.01 F/m² [default] + // segment 1: 0.017 F/m² + // segment 2: 0.013 F/m² + // segment 3: 0.018 F/m² + // + // Soma diameter: 14 µm + // Some mechanisms: HH (default params) + // + // Segment 1 diameter: 1 µm + // Segment 1 length: 200 µm + // + // Segment 2 diameter: 0.8 µm + // Segment 2 length: 300 µm + // + // Segment 3 diameter: 0.7 µm + // Segment 3 length: 180 µm + // + // Dendrite mechanisms: passive (default params). + // Stimulus at end of segment 2, amplitude 0.45. + // Stimulus at end of segment 3, amplitude -0.2. + // + // All dendrite segments with 4 compartments. + + mc_cell c2; + mc_segment* s; + + s = c2.add_soma(14./2); + s->add_mechanism("hh"); + + s = c2.add_cable(0, section_kind::dendrite, 1.0/2, 1.0/2, 200); + s->cm = 0.017; + + s = c2.add_cable(1, section_kind::dendrite, 0.8/2, 0.8/2, 300); + s->cm = 0.013; + + s = c2.add_cable(1, section_kind::dendrite, 0.7/2, 0.7/2, 180); + s->cm = 0.018; + + c2.add_stimulus({2,1}, {5., 80., 0.45}); + c2.add_stimulus({3,1}, {40., 10.,-0.2}); + + for (auto& seg: c2.segments()) { + seg->rL = 90.; + if (seg->is_dendrite()) { + seg->add_mechanism("pas"); + seg->set_compartments(4); + } } + cells.push_back(std::move(c2)); + return cells; } - cells.push_back(std::move(c2)); - return cells; -} -void check_two_cell_system(std::vector<cell>& cells) { - ASSERT_EQ(2u, cells[0].num_segments()); - ASSERT_EQ(cells[0].segment(1)->num_compartments(), 4u); - ASSERT_EQ(cells[1].num_segments(), 4u); - ASSERT_EQ(cells[1].segment(1)->num_compartments(), 4u); - ASSERT_EQ(cells[1].segment(2)->num_compartments(), 4u); - ASSERT_EQ(cells[1].segment(3)->num_compartments(), 4u); -} + void check_two_cell_system(std::vector<mc_cell>& cells) { + ASSERT_EQ(2u, cells[0].num_segments()); + ASSERT_EQ(cells[0].segment(1)->num_compartments(), 4u); + ASSERT_EQ(cells[1].num_segments(), 4u); + ASSERT_EQ(cells[1].segment(1)->num_compartments(), 4u); + ASSERT_EQ(cells[1].segment(2)->num_compartments(), 4u); + ASSERT_EQ(cells[1].segment(3)->num_compartments(), 4u); + } +} // namespace TEST(fvm_layout, topology) { - std::vector<cell> cells = two_cell_system(); + std::vector<mc_cell> cells = two_cell_system(); check_two_cell_system(cells); fvm_discretization D = fvm_discretize(cells); @@ -173,7 +209,7 @@ TEST(fvm_layout, topology) { } TEST(fvm_layout, area) { - std::vector<cell> cells = two_cell_system(); + std::vector<mc_cell> cells = two_cell_system(); check_two_cell_system(cells); fvm_discretization D = fvm_discretize(cells); @@ -184,7 +220,7 @@ TEST(fvm_layout, area) { std::vector<double> A; for (auto ci: make_span(D.ncell)) { for (auto si: make_span(cells[ci].num_segments())) { - A.push_back(cells[ci].segment(si)->area()); + A.push_back(area(cells[ci].segment(si))); } } @@ -230,12 +266,12 @@ TEST(fvm_layout, area) { EXPECT_FLOAT_EQ(c, D.cv_capacitance[5]); // Confirm face conductance within a constant diameter - // segment equals a/h·1/rL where a is the cross sectional + // equals a/h·1/rL where a is the cross sectional // area, and h is the compartment length (given the // regular discretization). cable_segment* cable = cells[1].segment(2)->as_cable(); - double a = cable->volume()/cable->length(); + double a = volume(cable)/cable->length(); EXPECT_FLOAT_EQ(math::pi<double>()*0.8*0.8/4, a); double h = cable->length()/4; @@ -246,7 +282,7 @@ TEST(fvm_layout, area) { } TEST(fvm_layout, mech_index) { - std::vector<cell> cells = two_cell_system(); + std::vector<mc_cell> cells = two_cell_system(); check_two_cell_system(cells); // Add four synapses of two varieties across the cells. @@ -271,7 +307,7 @@ TEST(fvm_layout, mech_index) { EXPECT_EQ(mechanismKind::density, hh_config.kind); EXPECT_EQ(ivec({0,5}), hh_config.cv); - fvec norm_area({cells[0].soma()->area()/D.cv_area[0], cells[1].soma()->area()/D.cv_area[5]}); + fvec norm_area({area(cells[0].soma())/D.cv_area[0], area(cells[1].soma())/D.cv_area[5]}); EXPECT_TRUE(testing::seq_almost_eq<double>(norm_area, hh_config.norm_area)); // Three expsyn synapses, two 0.4 along segment 1, and one 0.4 along segment 5. @@ -295,7 +331,7 @@ TEST(fvm_layout, mech_index) { } TEST(fvm_layout, synapse_targets) { - std::vector<cell> cells = two_cell_system(); + std::vector<mc_cell> cells = two_cell_system(); // Add synapses with different parameter values so that we can // ensure: 1) CVs for each synapse mechanism are sorted while @@ -404,8 +440,8 @@ TEST(fvm_layout, density_norm_area) { // // Use divided compartment view on segments to compute area contributions. - std::vector<cell> cells(1); - cell& c = cells[0]; + std::vector<mc_cell> cells(1); + mc_cell& c = cells[0]; auto soma = c.add_soma(12.6157/2.0); c.add_cable(0, section_kind::dendrite, 0.5, 0.5, 100); @@ -423,7 +459,7 @@ TEST(fvm_layout, density_norm_area) { double seg3_gl = .0004; for (int i = 0; i<4; ++i) { - segment& seg = *segs[i]; + mc_segment& seg = *segs[i]; seg.set_compartments(3); mechanism_desc hh("hh"); @@ -447,10 +483,13 @@ TEST(fvm_layout, density_norm_area) { std::vector<double> expected_gkbar(ncv, dflt_gkbar); std::vector<double> expected_gl(ncv, dflt_gl); - double soma_area = soma->area(); - auto seg1_divs = div_compartments<div_compartment_by_ends>(segs[1]->as_cable()); - auto seg2_divs = div_compartments<div_compartment_by_ends>(segs[2]->as_cable()); - auto seg3_divs = div_compartments<div_compartment_by_ends>(segs[3]->as_cable()); + auto div_by_ends = [](const cable_segment* cable) { + return div_compartment_by_ends(cable->num_compartments(), cable->radii(), cable->lengths()); + }; + double soma_area = area(soma); + auto seg1_divs = div_by_ends(segs[1]->as_cable()); + auto seg2_divs = div_by_ends(segs[2]->as_cable()); + auto seg3_divs = div_by_ends(segs[3]->as_cable()); // CV 0: mix of soma and left of segment 1 expected_gl[0] = wmean(soma_area, dflt_gl, seg1_divs(0).left.area, seg1_gl); @@ -531,7 +570,7 @@ TEST(fvm_layout, ion_weights) { // the same as a 100µm dendrite, which makes it easier to describe the // expected weights. - auto construct_cell = [](cell& c) { + auto construct_cell = [](mc_cell& c) { c.add_soma(5); c.add_cable(0, section_kind::dendrite, 0.5, 0.5, 100); @@ -558,8 +597,8 @@ TEST(fvm_layout, ion_weights) { }; for (auto run: count_along(mech_segs)) { - std::vector<cell> cells(1); - cell& c = cells[0]; + std::vector<mc_cell> cells(1); + mc_cell& c = cells[0]; construct_cell(c); for (auto i: mech_segs[run]) { diff --git a/test/unit/test_fvm_lowered.cpp b/test/unit/test_fvm_lowered.cpp index c30bf57d..1a23165b 100644 --- a/test/unit/test_fvm_lowered.cpp +++ b/test/unit/test_fvm_lowered.cpp @@ -5,11 +5,13 @@ #include <arbor/common_types.hpp> #include <arbor/distributed_context.hpp> #include <arbor/fvm_types.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/mc_segment.hpp> +#include <arbor/sampling.hpp> #include "algorithms.hpp" #include "backends/multicore/fvm.hpp" #include "backends/multicore/mechanism.hpp" -#include "cell.hpp" #include "fvm_lowered_cell.hpp" #include "fvm_lowered_cell_impl.hpp" #include "load_balance.hpp" @@ -17,9 +19,7 @@ #include "simulation.hpp" #include "recipe.hpp" #include "sampler_map.hpp" -#include "sampling.hpp" #include "schedule.hpp" -#include "segment.hpp" #include "util/meta.hpp" #include "util/maputil.hpp" #include "util/rangeutil.hpp" @@ -87,7 +87,7 @@ TEST(fvm_lowered, matrix_init) algorithms::generic_is_positive ispos; algorithms::generic_is_negative isneg; - arb::cell cell = make_cell_ball_and_stick(); + mc_cell cell = make_cell_ball_and_stick(); ASSERT_EQ(2u, cell.num_segments()); cell.segment(1)->set_compartments(10); @@ -119,7 +119,7 @@ TEST(fvm_lowered, matrix_init) TEST(fvm_lowered, target_handles) { using namespace arb; - arb::cell cells[] = { + mc_cell cells[] = { make_cell_ball_and_stick(), make_cell_ball_and_3stick() }; @@ -178,7 +178,7 @@ TEST(fvm_lowered, stimulus) { // amplitude | 0.3 | 0.1 // CV | 4 | 0 - std::vector<cell> cells; + std::vector<mc_cell> cells; cells.push_back(make_cell_ball_and_stick(false)); cells[0].add_stimulus({1,1}, {5., 80., 0.3}); @@ -253,9 +253,9 @@ TEST(fvm_lowered, derived_mechs) { // // 3. Cell with both test_kin1 and custom_kin1. - std::vector<cell> cells(3); + std::vector<mc_cell> cells(3); for (int i = 0; i<3; ++i) { - cell& c = cells[i]; + mc_cell& c = cells[i]; c.add_soma(6.0); c.add_cable(0, section_kind::dendrite, 0.5, 0.5, 100); @@ -376,7 +376,7 @@ TEST(fvm_lowered, weighted_write_ion) { // the same as a 100µm dendrite, which makes it easier to describe the // expected weights. - cell c; + mc_cell c; c.add_soma(5); c.add_cable(0, section_kind::dendrite, 0.5, 0.5, 100); diff --git a/test/unit/test_lif_cell_group.cpp b/test/unit/test_lif_cell_group.cpp index 385ce7c7..40bc2c38 100644 --- a/test/unit/test_lif_cell_group.cpp +++ b/test/unit/test_lif_cell_group.cpp @@ -1,16 +1,15 @@ #include "../gtest.h" #include <arbor/distributed_context.hpp> +#include <arbor/lif_cell.hpp> #include <arbor/threadinfo.hpp> +#include <arbor/spike_source_cell.hpp> -#include <cell_group_factory.hpp> -#include <fstream> -#include <lif_cell_description.hpp> -#include <lif_cell_group.hpp> -#include <load_balance.hpp> -#include <simulation.hpp> -#include <spike_source_cell.hpp> -#include <recipe.hpp> +#include "cell_group_factory.hpp" +#include "lif_cell_group.hpp" +#include "load_balance.hpp" +#include "simulation.hpp" +#include "recipe.hpp" using namespace arb; // Simple ring network of LIF neurons. @@ -65,7 +64,7 @@ public: return spike_source_cell{vector_time_seq({0.f})}; } // LIF cell. - return lif_cell_description(); + return lif_cell(); } cell_size_type num_sources(cell_gid_type) const override { @@ -118,7 +117,7 @@ public: } util::unique_any get_cell_description(cell_gid_type gid) const override { - return lif_cell_description(); + return lif_cell(); } cell_size_type num_sources(cell_gid_type) const override { diff --git a/test/unit/test_cell.cpp b/test/unit/test_mc_cell.cpp similarity index 80% rename from test/unit/test_cell.cpp rename to test/unit/test_mc_cell.cpp index fee64731..98e1b5e3 100644 --- a/test/unit/test_cell.cpp +++ b/test/unit/test_mc_cell.cpp @@ -1,13 +1,17 @@ #include "../gtest.h" -#include "cell.hpp" +#include <arbor/mc_cell.hpp> -TEST(cell, soma) -{ +#include "math.hpp" +#include "tree.hpp" + +using namespace arb; + +TEST(mc_cell, soma) { // test that insertion of a soma works // define with no centre point { - arb::cell c; + mc_cell c; auto soma_radius = 2.1; EXPECT_EQ(c.has_soma(), false); @@ -22,7 +26,7 @@ TEST(cell, soma) // test that insertion of a soma works // define with centre point @ (0,0,1) { - arb::cell c; + mc_cell c; auto soma_radius = 3.2; EXPECT_EQ(c.has_soma(), false); @@ -38,12 +42,10 @@ TEST(cell, soma) } } -TEST(cell, add_segment) -{ - using namespace arb; +TEST(mc_cell, add_segment) { // add a pre-defined segment { - cell c; + mc_cell c; auto soma_radius = 2.1; auto cable_radius = 0.1; @@ -64,7 +66,7 @@ TEST(cell, add_segment) // add segment on the fly { - cell c; + mc_cell c; auto soma_radius = 2.1; auto cable_radius = 0.1; @@ -81,7 +83,7 @@ TEST(cell, add_segment) EXPECT_EQ(c.num_segments(), 2u); } { - cell c; + mc_cell c; auto soma_radius = 2.1; auto cable_radius = 0.1; @@ -101,10 +103,7 @@ TEST(cell, add_segment) } } -TEST(cell, multiple_cables) -{ - using namespace arb; - +TEST(mc_cell, multiple_cables) { // generate a cylindrical cable segment of length 1/pi and radius 1 // volume = 1 // area = 2 @@ -114,7 +113,7 @@ TEST(cell, multiple_cables) // add a pre-defined segment { - cell c; + mc_cell c; auto soma_radius = std::pow(3./(4.*math::pi<double>()), 1./3.); @@ -138,15 +137,9 @@ TEST(cell, multiple_cables) c.add_cable(1, seg(section_kind::dendrite)); EXPECT_EQ(c.num_segments(), 5u); - // each of the 5 segments has volume 1 by design - EXPECT_EQ(c.volume(), 5.); - // each of the 4 cables has volume 2., and the soma has an awkward area - // that isn't a round number - EXPECT_EQ(c.area(), 8. + math::area_sphere(soma_radius)); // construct the graph - const auto model = c.model(); - auto const& con = model.tree; + tree con(c.parents()); auto no_parent = tree::no_parent; EXPECT_EQ(con.num_segments(), 5u); @@ -164,11 +157,8 @@ TEST(cell, multiple_cables) } } -TEST(cell, unbranched_chain) -{ - using namespace arb; - - cell c; +TEST(mc_cell, unbranched_chain) { + mc_cell c; auto soma_radius = std::pow(3./(4.*math::pi<double>()), 1./3.); @@ -186,32 +176,24 @@ TEST(cell, unbranched_chain) c.add_cable(1, make_segment<cable_segment>(section_kind::dendrite, 1.0, 1.0, 1./math::pi<double>())); EXPECT_EQ(c.num_segments(), 3u); - // each of the 3 segments has volume 1 by design - EXPECT_EQ(c.volume(), 3.); - // each of the 2 cables has volume 2., and the soma has an awkward area - // that isn't a round number - EXPECT_EQ(c.area(), 4. + math::area_sphere(soma_radius)); // construct the graph - const auto tree = c.model().tree; + tree con(c.parents()); auto no_parent = tree::no_parent; - EXPECT_EQ(tree.num_segments(), 3u); - EXPECT_EQ(tree.parent(0), no_parent); - EXPECT_EQ(tree.parent(1), 0u); - EXPECT_EQ(tree.parent(2), 1u); - EXPECT_EQ(tree.num_children(0), 1u); - EXPECT_EQ(tree.num_children(1), 1u); - EXPECT_EQ(tree.num_children(2), 0u); + EXPECT_EQ(con.num_segments(), 3u); + EXPECT_EQ(con.parent(0), no_parent); + EXPECT_EQ(con.parent(1), 0u); + EXPECT_EQ(con.parent(2), 1u); + EXPECT_EQ(con.num_children(0), 1u); + EXPECT_EQ(con.num_children(1), 1u); + EXPECT_EQ(con.num_children(2), 0u); } -TEST(cell, clone) -{ - using namespace arb; - +TEST(mc_cell, clone) { // make simple cell with multiple segments - cell c; + mc_cell c; c.add_soma(2.1); c.add_cable(0, section_kind::dendrite, 0.3, 0.2, 10); c.segment(1)->set_compartments(3); @@ -224,7 +206,7 @@ TEST(cell, clone) // make clone - cell d(c); + mc_cell d(c); // check equality @@ -260,11 +242,7 @@ TEST(cell, clone) EXPECT_EQ(c.segment(2)->num_compartments(), d.segment(2)->num_compartments()); } -TEST(cell, get_kind) -{ - using namespace arb; - - // make a MC cell - cell c; - EXPECT_EQ( cell_kind::cable1d_neuron, c.get_cell_kind()); +TEST(mc_cell, get_kind) { + mc_cell c; + EXPECT_EQ(cell_kind::cable1d_neuron, c.get_cell_kind()); } diff --git a/test/unit/test_mc_cell_group.cpp b/test/unit/test_mc_cell_group.cpp index 0a0c7d1d..4aaf42eb 100644 --- a/test/unit/test_mc_cell_group.cpp +++ b/test/unit/test_mc_cell_group.cpp @@ -19,7 +19,7 @@ namespace { return make_fvm_lowered_cell(backend_kind::multicore); } - cell make_cell() { + mc_cell make_cell() { auto c = make_cell_ball_and_stick(); c.add_detector({0, 0}, 0); @@ -52,7 +52,7 @@ TEST(mc_cell_group, test) { TEST(mc_cell_group, sources) { // Make twenty cells, with an extra detector on gids 0, 3 and 17 // to make things more interesting. - std::vector<cell> cells; + std::vector<mc_cell> cells; for (int i=0; i<20; ++i) { cells.push_back(make_cell()); diff --git a/test/unit/test_mc_cell_group_gpu.cpp b/test/unit/test_mc_cell_group_gpu.cpp index 8b357510..f3662484 100644 --- a/test/unit/test_mc_cell_group_gpu.cpp +++ b/test/unit/test_mc_cell_group_gpu.cpp @@ -17,7 +17,7 @@ namespace { return make_fvm_lowered_cell(backend_kind::gpu); } - cell make_cell() { + mc_cell make_cell() { auto c = make_cell_ball_and_stick(); c.add_detector({0, 0}, 0); diff --git a/test/unit/test_mechinfo.cpp b/test/unit/test_mechinfo.cpp index b5995d11..e5f63588 100644 --- a/test/unit/test_mechinfo.cpp +++ b/test/unit/test_mechinfo.cpp @@ -2,7 +2,7 @@ #include <string> #include <vector> -#include <cell.hpp> +#include <arbor/mc_cell.hpp> #include "../gtest.h" diff --git a/test/unit/test_partition_by_constraint.cpp b/test/unit/test_partition_by_constraint.cpp index 14945327..733bb941 100644 --- a/test/unit/test_partition_by_constraint.cpp +++ b/test/unit/test_partition_by_constraint.cpp @@ -6,10 +6,10 @@ #include <vector> #include <arbor/common_types.hpp> +#include <arbor/simd/simd.hpp> -#include <simd/simd.hpp> -#include <backends/multicore/multicore_common.hpp> -#include <backends/multicore/partition_by_constraint.hpp> +#include "backends/multicore/multicore_common.hpp" +#include "backends/multicore/partition_by_constraint.hpp" using namespace arb; using iarray = multicore::iarray; diff --git a/test/unit/test_point.cpp b/test/unit/test_point.cpp index 2edb08ed..872ec6dd 100644 --- a/test/unit/test_point.cpp +++ b/test/unit/test_point.cpp @@ -3,7 +3,7 @@ #include "../gtest.h" -#include "point.hpp" +#include <arbor/point.hpp> using namespace arb; diff --git a/test/unit/test_probe.cpp b/test/unit/test_probe.cpp index 6064a02b..b22df63b 100644 --- a/test/unit/test_probe.cpp +++ b/test/unit/test_probe.cpp @@ -1,12 +1,12 @@ #include "../gtest.h" #include <arbor/common_types.hpp> +#include <arbor/mc_cell.hpp> -#include <backends/event.hpp> -#include <backends/multicore/fvm.hpp> -#include <cell.hpp> -#include <fvm_lowered_cell_impl.hpp> -#include <util/rangeutil.hpp> +#include "backends/event.hpp" +#include "backends/multicore/fvm.hpp" +#include "fvm_lowered_cell_impl.hpp" +#include "util/rangeutil.hpp" #include "common.hpp" #include "../common_cells.hpp" @@ -19,7 +19,7 @@ using shared_state = multicore::backend::shared_state; ACCESS_BIND(std::unique_ptr<shared_state> fvm_cell::*, fvm_state_ptr, &fvm_cell::state_); TEST(probe, fvm_lowered_cell) { - cell bs = make_cell_ball_and_stick(false); + mc_cell bs = make_cell_ball_and_stick(false); i_clamp stim(0, 100, 0.3); bs.add_stimulus({1, 1}, stim); diff --git a/test/unit/test_segment.cpp b/test/unit/test_segment.cpp index fc984ee4..ed6022e8 100644 --- a/test/unit/test_segment.cpp +++ b/test/unit/test_segment.cpp @@ -1,47 +1,33 @@ -#include <limits> +#include <vector> #include "../gtest.h" -#include "segment.hpp" +#include <arbor/mc_segment.hpp> -TEST(segments, soma) -{ +#include "math.hpp" + +using namespace arb; + +TEST(mc_segment, kinfs) { using namespace arb; using arb::math::pi; { auto s = make_segment<soma_segment>(1.0); - - EXPECT_EQ(s->volume(), pi<double>()*4./3.); - EXPECT_EQ(s->area(), pi<double>()*4.); EXPECT_EQ(s->kind(), section_kind::soma); } { auto s = make_segment<soma_segment>(1.0, point<double>(0., 1., 2.)); - - EXPECT_EQ(s->volume(), pi<double>()*4./3.); - EXPECT_EQ(s->area(), pi<double>()*4.); EXPECT_EQ(s->kind(), section_kind::soma); } -} -TEST(segments, cable) -{ - using namespace arb; - using arb::math::pi; - - // take advantage of fact that a cable segment with constant radius 1 and - // length 1 has volume=1. and area=2 - auto length = 1./pi<double>(); - auto radius = 1.; + double length = 1./pi<double>(); + double radius = 1.; // single cylindrical frustrum { auto s = make_segment<cable_segment>(section_kind::dendrite, radius, radius, length); - - EXPECT_EQ(s->volume(), 1.0); - EXPECT_EQ(s->area(), 2.0); EXPECT_EQ(s->kind(), section_kind::dendrite); } @@ -54,16 +40,8 @@ TEST(segments, cable) std::vector<double>{length, length, length} ); - EXPECT_EQ(s->volume(), 3.0); - EXPECT_EQ(s->area(), 6.0); EXPECT_EQ(s->kind(), section_kind::axon); } -} - -TEST(segments, cable_positions) -{ - using namespace arb; - using arb::math::pi; // single frustrum of length 1 and radii 1 and 2 // the centre of each end are at the origin (0,0,0) and (0,1,0) @@ -75,8 +53,6 @@ TEST(segments, cable_positions) point<double>(0,0,0), point<double>(0,1,0) ); - EXPECT_EQ(s->volume(), math::volume_frustrum(1., 1., 2.)); - EXPECT_EQ(s->area(), math::area_frustrum (1., 1., 2.)); EXPECT_EQ(s->kind(), section_kind::dendrite); } @@ -90,8 +66,6 @@ TEST(segments, cable_positions) std::vector<point<double>>{ {0,0,0}, {0,0.5,0}, {0,1,0} } ); - EXPECT_EQ(s->volume(), math::volume_frustrum(1., 1., 2.)); - EXPECT_EQ(s->area(), math::area_frustrum(1., 1., 2.)); EXPECT_EQ(s->kind(), section_kind::axon); } } diff --git a/test/unit/test_simd.cpp b/test/unit/test_simd.cpp index dcb102a1..c266b2b5 100644 --- a/test/unit/test_simd.cpp +++ b/test/unit/test_simd.cpp @@ -5,8 +5,8 @@ #include <random> #include <unordered_set> -#include <simd/simd.hpp> -#include <simd/avx.hpp> +#include <arbor/simd/simd.hpp> +#include <arbor/simd/avx.hpp> #include "common.hpp" diff --git a/test/unit/test_spike_source.cpp b/test/unit/test_spike_source.cpp index 28a327ab..b877a64a 100644 --- a/test/unit/test_spike_source.cpp +++ b/test/unit/test_spike_source.cpp @@ -1,9 +1,10 @@ #include "../gtest.h" -#include <spike_source_cell.hpp> -#include <spike_source_cell_group.hpp> -#include <time_sequence.hpp> -#include <util/unique_any.hpp> +#include <arbor/spike_source_cell.hpp> +#include <arbor/time_sequence.hpp> +#include <arbor/util/unique_any.hpp> + +#include "spike_source_cell_group.hpp" #include "../simple_recipes.hpp" diff --git a/test/unit/test_swcio.cpp b/test/unit/test_swcio.cpp index c27318b7..85ad98d6 100644 --- a/test/unit/test_swcio.cpp +++ b/test/unit/test_swcio.cpp @@ -7,9 +7,11 @@ #include <type_traits> #include <vector> +#include <arbor/mc_cell.hpp> +#include <arbor/morphology.hpp> + #include "../gtest.h" -#include "cell.hpp" #include "swcio.hpp" // Path to data directory can be overriden at compile time. @@ -469,7 +471,7 @@ TEST(swc_io, cell_construction) { // swc -> morphology auto morph = io::swc_as_morphology(io::parse_swc_file(is)); - cell cell = make_cell(morph, true); + mc_cell cell = make_mc_cell(morph, true); EXPECT_TRUE(cell.has_soma()); EXPECT_EQ(4u, cell.num_segments()); @@ -518,11 +520,38 @@ TEST(swc_io, cell_construction) { cell.cable(3)->radius(0)); } +void expect_morph_eq(const morphology& a, const morphology& b) { + EXPECT_EQ(a.soma.r, b.soma.r); + EXPECT_EQ(a.sections.size(), b.sections.size()); + + for (unsigned i = 0; i<a.sections.size(); ++i) { + const section_geometry& r = a.sections[i]; + const section_geometry& s = b.sections[i]; + + EXPECT_EQ(r.points.size(), s.points.size()); + unsigned n = r.points.size(); + if (n>1) { + auto r0 = r.points[0]; + auto s0 = s.points[0]; + EXPECT_EQ(r0.r, s0.r); + + // TODO: check lengths for each line segment instead. + EXPECT_DOUBLE_EQ(r.length, s.length); + + for (unsigned i = 1; i<n; ++i) { + auto r1 = r.points[i]; + auto s1 = s.points[i]; + + EXPECT_EQ(r1.r, s1.r); + } + } + } +} + // check that simple ball and stick model with one dendrite attached to a soma // which is used in the validation tests can be loaded from file and matches // the one generated with the C++ interface -TEST(swc_parser, from_file_ball_and_stick) -{ +TEST(swc_parser, from_file_ball_and_stick) { std::string datadir{DATADIR}; auto fname = datadir + "/ball_and_stick.swc"; std::ifstream fid(fname); @@ -531,17 +560,14 @@ TEST(swc_parser, from_file_ball_and_stick) return; } - // read the file into a cell object - auto bas_cell = make_cell(io::swc_as_morphology(io::parse_swc_file(fid))); + // read the file as morhpology + auto bas_morph = io::swc_as_morphology(io::parse_swc_file(fid)); - // verify that the correct number of nodes was read - EXPECT_EQ(2u, bas_cell.num_segments()); - EXPECT_EQ(2u, bas_cell.num_compartments()); + // compare with expected morphology + morphology expected; - // make an equivalent cell via C++ interface - cell local_cell; - local_cell.add_soma(6.30785); - local_cell.add_cable(0, section_kind::dendrite, 0.5, 0.5, 200); + expected.soma = {0., 0., 0., 6.30785}; + expected.add_section({{6.30785, 0., 0., 0.5}, {206.30785, 0., 0., 0.5}}, 0u, section_kind::dendrite); - EXPECT_TRUE(cell_basic_equality(local_cell, bas_cell)); + expect_morph_eq(expected, bas_morph); } diff --git a/test/unit/test_synapses.cpp b/test/unit/test_synapses.cpp index 08a14221..0c5464e6 100644 --- a/test/unit/test_synapses.cpp +++ b/test/unit/test_synapses.cpp @@ -4,15 +4,15 @@ #include <tuple> #include <vector> -#include <arbor/util/optional.hpp> +#include <arbor/constants.hpp> #include <arbor/mechcat.hpp> +#include <arbor/util/optional.hpp> +#include <arbor/mc_cell.hpp> -#include <cell.hpp> -#include <constants.hpp> -#include <backends/multicore/fvm.hpp> -#include <backends/multicore/mechanism.hpp> -#include <util/maputil.hpp> -#include <util/range.hpp> +#include "backends/multicore/fvm.hpp" +#include "backends/multicore/mechanism.hpp" +#include "util/maputil.hpp" +#include "util/range.hpp" #include "common.hpp" @@ -41,7 +41,7 @@ ACCESS_BIND(value_type* multicore::mechanism::*, vec_i_ptr, &multicore::mechanis TEST(synapses, add_to_cell) { using namespace arb; - ::arb::cell cell; + mc_cell cell; // Soma with diameter 12.6157 um and HH channel auto soma = cell.add_soma(12.6157/2.0); diff --git a/test/unit/test_time_seq.cpp b/test/unit/test_time_seq.cpp index f5031513..dcb87b4d 100644 --- a/test/unit/test_time_seq.cpp +++ b/test/unit/test_time_seq.cpp @@ -3,8 +3,10 @@ #include <vector> -#include <time_sequence.hpp> -#include <util/rangeutil.hpp> +#include <arbor/time_sequence.hpp> + +#include "event_queue.hpp" +#include "util/rangeutil.hpp" using namespace arb; using pse = postsynaptic_spike_event; diff --git a/test/unit/test_unique_any.cpp b/test/unit/test_unique_any.cpp index 0104619a..038d4341 100644 --- a/test/unit/test_unique_any.cpp +++ b/test/unit/test_unique_any.cpp @@ -1,8 +1,9 @@ #include <iostream> -#include <util/rangeutil.hpp> -#include <util/span.hpp> -#include <util/unique_any.hpp> +#include <arbor/util/unique_any.hpp> + +#include "util/rangeutil.hpp" +#include "util/span.hpp" #include "../gtest.h" #include "common.hpp" diff --git a/test/validation/convergence_test.hpp b/test/validation/convergence_test.hpp index 8ee744c2..c4de6033 100644 --- a/test/validation/convergence_test.hpp +++ b/test/validation/convergence_test.hpp @@ -4,13 +4,13 @@ #include <nlohmann/json.hpp> -#include <simulation.hpp> -#include <schedule.hpp> -#include <sampling.hpp> -#include <simple_sampler.hpp> -#include <util/filter.hpp> -#include <util/rangeutil.hpp> +#include <arbor/sampling.hpp> +#include <arbor/simple_sampler.hpp> +#include "simulation.hpp" +#include "schedule.hpp" +#include "util/filter.hpp" +#include "util/rangeutil.hpp" #include "../gtest.h" @@ -141,7 +141,7 @@ public: * Extract time points to exclude from current stimulus end-points. */ -inline std::vector<float> stimulus_ends(const cell& c) { +inline std::vector<float> stimulus_ends(const mc_cell& c) { std::vector<float> ts; for (const auto& stimulus: c.stimuli()) { diff --git a/test/validation/trace_analysis.cpp b/test/validation/trace_analysis.cpp index 5e0268c3..6a9cd813 100644 --- a/test/validation/trace_analysis.cpp +++ b/test/validation/trace_analysis.cpp @@ -7,11 +7,11 @@ #include "../gtest.h" #include <arbor/util/optional.hpp> +#include <arbor/simple_sampler.hpp> -#include <math.hpp> -#include <simple_sampler.hpp> -#include <util/partition.hpp> -#include <util/rangeutil.hpp> +#include "math.hpp" +#include "util/partition.hpp" +#include "util/rangeutil.hpp" #include "trace_analysis.hpp" diff --git a/test/validation/trace_analysis.hpp b/test/validation/trace_analysis.hpp index 26f2823b..167952cb 100644 --- a/test/validation/trace_analysis.hpp +++ b/test/validation/trace_analysis.hpp @@ -4,17 +4,41 @@ #include "../gtest.h" +#include <arbor/simple_sampler.hpp> #include <arbor/util/optional.hpp> -#include <simple_sampler.hpp> -#include <math.hpp> -#include <util/path.hpp> -#include <util/rangeutil.hpp> +#include "math.hpp" +#include "util/path.hpp" +#include "util/deduce_return.hpp" +#include "util/rangeutil.hpp" namespace arb { /* Trace data comparison */ +// Extract time or value data from trace. + +namespace impl { + // NB: work-around for lack of function return type deduction + // in C++11; can't use lambda within DEDUCED_RETURN_TYPE. + + template <typename V> + inline float time(const trace_entry<V>& x) { return x.t; } + + template <typename V> + inline const V& value(const trace_entry<V>& x) { return x.v; } +} + +template <typename V> +inline auto times(const trace_data<V>& trace) DEDUCED_RETURN_TYPE( + util::transform_view(trace, impl::time<V>) +) + +template <typename V> +inline auto values(const trace_data<V>& trace) DEDUCED_RETURN_TYPE( + util::transform_view(trace, impl::value<V>) +) + // Compute max |v_i - f(t_i)| where (t, v) is the // first trace `u` and f is the piece-wise linear interpolant // of the second trace `r`. diff --git a/test/validation/validate_ball_and_stick.cpp b/test/validation/validate_ball_and_stick.cpp index e2b6a39d..2520321b 100644 --- a/test/validation/validate_ball_and_stick.cpp +++ b/test/validation/validate_ball_and_stick.cpp @@ -1,18 +1,18 @@ #include <iostream> -#include <arbor/common_types.hpp> #include <nlohmann/json.hpp> -#include <cell.hpp> -#include <load_balance.hpp> -#include <hardware/node_info.hpp> -#include <hardware/gpu.hpp> -#include <simulation.hpp> -#include <recipe.hpp> -#include <segment.hpp> -#include <simple_sampler.hpp> -#include <util/meta.hpp> -#include <util/path.hpp> +#include <arbor/common_types.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> + +#include "load_balance.hpp" +#include "hardware/node_info.hpp" +#include "hardware/gpu.hpp" +#include "simulation.hpp" +#include "recipe.hpp" +#include "util/meta.hpp" +#include "util/path.hpp" #include "../common_cells.hpp" #include "../simple_recipes.hpp" @@ -34,7 +34,7 @@ void run_ncomp_convergence_test( const char* model_name, const util::path& ref_data_path, backend_kind backend, - const cell& c, + const mc_cell& c, ProbePointSeq& probe_points, float t_end=100.f) { @@ -90,7 +90,7 @@ void run_ncomp_convergence_test( void validate_ball_and_stick(arb::backend_kind backend) { using namespace arb; - cell c = make_cell_ball_and_stick(); + mc_cell c = make_cell_ball_and_stick(); probe_point points[] = { {"soma.mid", {0u, 0.5}}, {"dend.mid", {1u, 0.5}}, @@ -108,7 +108,7 @@ void validate_ball_and_stick(arb::backend_kind backend) { void validate_ball_and_taper(arb::backend_kind backend) { using namespace arb; - cell c = make_cell_ball_and_taper(); + mc_cell c = make_cell_ball_and_taper(); probe_point points[] = { {"soma.mid", {0u, 0.5}}, {"taper.mid", {1u, 0.5}}, @@ -126,7 +126,7 @@ void validate_ball_and_taper(arb::backend_kind backend) { void validate_ball_and_3stick(arb::backend_kind backend) { using namespace arb; - cell c = make_cell_ball_and_3stick(); + mc_cell c = make_cell_ball_and_3stick(); probe_point points[] = { {"soma.mid", {0u, 0.5}}, {"dend1.mid", {1u, 0.5}}, @@ -148,7 +148,7 @@ void validate_ball_and_3stick(arb::backend_kind backend) { void validate_rallpack1(arb::backend_kind backend) { using namespace arb; - cell c = make_cell_simple_cable(); + mc_cell c = make_cell_simple_cable(); probe_point points[] = { {"cable.x0.0", {1u, 0.0}}, {"cable.x0.3", {1u, 0.3}}, @@ -167,7 +167,7 @@ void validate_rallpack1(arb::backend_kind backend) { void validate_ball_and_squiggle(arb::backend_kind backend) { using namespace arb; - cell c = make_cell_ball_and_squiggle(); + mc_cell c = make_cell_ball_and_squiggle(); probe_point points[] = { {"soma.mid", {0u, 0.5}}, {"dend.mid", {1u, 0.5}}, diff --git a/test/validation/validate_compartment_policy.cpp b/test/validation/validate_compartment_policy.cpp index d0543384..a2ead6c4 100644 --- a/test/validation/validate_compartment_policy.cpp +++ b/test/validation/validate_compartment_policy.cpp @@ -4,11 +4,11 @@ #include <nlohmann/json.hpp> #include <arbor/common_types.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> -#include <cell.hpp> #include <simulation.hpp> #include <recipe.hpp> -#include <simple_sampler.hpp> #include <util/rangeutil.hpp> #include "../gtest.h" diff --git a/test/validation/validate_kinetic.cpp b/test/validation/validate_kinetic.cpp index 54fc750b..063df632 100644 --- a/test/validation/validate_kinetic.cpp +++ b/test/validation/validate_kinetic.cpp @@ -1,16 +1,18 @@ #include "../gtest.h" +#include <string> + #include <nlohmann/json.hpp> #include <arbor/common_types.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> -#include <cell.hpp> #include <hardware/node_info.hpp> #include <hardware/gpu.hpp> #include <load_balance.hpp> #include <simulation.hpp> #include <recipe.hpp> -#include <simple_sampler.hpp> #include <util/rangeutil.hpp> #include "../common_cells.hpp" @@ -22,7 +24,7 @@ void run_kinetic_dt( arb::backend_kind backend, - arb::cell& c, + arb::mc_cell& c, arb::cell_probe_address probe, float t_end, nlohmann::json meta, @@ -71,7 +73,7 @@ void validate_kinetic_kin1(arb::backend_kind backend) { using namespace arb; // 20 µm diameter soma with single mechanism, current probe - cell c; + mc_cell c; auto soma = c.add_soma(10); soma->add_mechanism("test_kin1"); cell_probe_address probe{{0, 0.5}, cell_probe_address::membrane_current}; @@ -89,7 +91,7 @@ void validate_kinetic_kinlva(arb::backend_kind backend) { using namespace arb; // 20 µm diameter soma with single mechanism, current probe - cell c; + mc_cell c; auto soma = c.add_soma(10); c.add_stimulus({0,0.5}, {20., 130., -0.025}); soma->add_mechanism("test_kinlva"); diff --git a/test/validation/validate_soma.cpp b/test/validation/validate_soma.cpp index 2beb50bc..e912c6b5 100644 --- a/test/validation/validate_soma.cpp +++ b/test/validation/validate_soma.cpp @@ -1,14 +1,14 @@ #include <nlohmann/json.hpp> #include <arbor/common_types.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> -#include <cell.hpp> #include <hardware/gpu.hpp> #include <hardware/node_info.hpp> #include <load_balance.hpp> #include <simulation.hpp> #include <recipe.hpp> -#include <simple_sampler.hpp> #include <util/rangeutil.hpp> #include "../common_cells.hpp" @@ -25,7 +25,7 @@ using namespace arb; void validate_soma(backend_kind backend) { float sample_dt = g_trace_io.sample_dt(); - cell c = make_cell_soma_only(); + mc_cell c = make_cell_soma_only(); cable1d_recipe rec{c}; rec.add_probe(0, 0, cell_probe_address{{0, 0.5}, cell_probe_address::membrane_voltage}); diff --git a/test/validation/validate_synapses.cpp b/test/validation/validate_synapses.cpp index 2d0aeab8..01c237d8 100644 --- a/test/validation/validate_synapses.cpp +++ b/test/validation/validate_synapses.cpp @@ -1,14 +1,14 @@ #include <nlohmann/json.hpp> -#include <cell.hpp> -#include <cell_group.hpp> -#include <hardware/node_info.hpp> -#include <hardware/gpu.hpp> -#include <load_balance.hpp> -#include <simulation.hpp> -#include <recipe.hpp> -#include <simple_sampler.hpp> -#include <util/path.hpp> +#include <arbor/mc_cell.hpp> +#include <arbor/simple_sampler.hpp> + +#include "hardware/node_info.hpp" +#include "hardware/gpu.hpp" +#include "load_balance.hpp" +#include "simulation.hpp" +#include "recipe.hpp" +#include "util/path.hpp" #include "../gtest.h" @@ -37,7 +37,7 @@ void run_synapse_test( {"backend_kind", to_string(backend)} }; - cell c = make_cell_ball_and_stick(false); // no stimuli + mc_cell c = make_cell_ball_and_stick(false); // no stimuli mechanism_desc syn_default(syn_type); c.add_synapse({1, 0.5}, syn_default); diff --git a/test/validation/validation_data.cpp b/test/validation/validation_data.cpp index 5426a57b..2722c909 100644 --- a/test/validation/validation_data.cpp +++ b/test/validation/validation_data.cpp @@ -6,9 +6,11 @@ #include <nlohmann/json.hpp> -#include <simple_sampler.hpp> -#include <util/path.hpp> +#include <arbor/simple_sampler.hpp> +#include "util/path.hpp" + +#include "trace_analysis.hpp" #include "validation_data.hpp" namespace arb { diff --git a/test/validation/validation_data.hpp b/test/validation/validation_data.hpp index 84056ebb..1317738f 100644 --- a/test/validation/validation_data.hpp +++ b/test/validation/validation_data.hpp @@ -7,8 +7,9 @@ #include <nlohmann/json.hpp> -#include <simple_sampler.hpp> -#include <util/path.hpp> +#include <arbor/simple_sampler.hpp> + +#include "util/path.hpp" namespace arb { -- GitLab