How the Cable Cell is made¶
This is a short tour through the inner workings of a cable cell intended for new Arbor developers. Cable cells are not the sole cell type supported in Arbor, but both the most common and most complex kind.
This is the introduction from which more detailed descriptions will branch out. As such, we will start with a simple cable cell simulation and how the user input is turned into an executable object.
Terminology¶
In Arbor’s codebase some prefixes are used as a low-key namespacing
arb_
:: Mech ABI types, in general use through out Arbor, egarb_mechanism_type
.fvm_
:: Concerning use by the Finite Volume Method (FVM), egfvm_lowered_cell
.mc_
:: Related to Multi-Compartment (Cells), identical to cable cells the difference is purely historical, egcable_cell_group
.
Setting up a Cable Cell simulation¶
Arbor constructs a runnable simulation from three ingredients:
recipe
:: a queryable structure that collects cells, connections, gap junctions, etc.context
:: a hardware configuration, summarising threads, GPU, and MPI resources to be used.domain_decomposition
:: Distribution of cells over thecontext
, made fromcontext
andrecipe
.
The interesting part here is the recipe
, which is used to lazily produce the
data required by the simulation
and domain_decomposition
. A simple example
might be this model of a single cell
struct recipe: public arb::recipe {
recipe(const arb::morphology& m, const arb::decor& d): cell{m, d} {}
arb::cell_size_type num_cells() const override { return 1; }
std::vector<arb::probe_info> get_probes(arb::cell_gid_type) const override { return {}; }
arb::cell_kind get_cell_kind(arb::cell_gid_type) const override { return arb::cell_kind::cable; }
std::any get_global_properties(arb::cell_kind) const override { return gprop; }
arb::util::unique_any get_cell_description(arb::cell_gid_type) const override { return cell; }
arb::cable_cell cell
arb::cable_cell_global_properties gprop;
};
As you can see, data is produced on request by feeding the recipe a
cell_gid_type
. Finally, we need to have a morphology
and a decor
to
generate a cable_cell
. Please refer to the documentation on how to construct
these objects. For now, it is sufficient to note that a cable_cell
is a
description of a cell, consisting of a cell geometry and a mapping of
sub-geometries to properties, rather an object that can be simulated. At this point
ion channels are described by a structure (name, [(parameter, value)])
.
Main integration loop¶
Now we are in a state to simulate a cell group by calling
simulation::run(t_end, dt)
.
The integration in Arbor proceeds in epochs with a length less than half a time constant \(T_{min}\), which is the maximum time over which cell groups can evolve independently. The length \(T_{min}\) is derived as the minimum over all axonal/synaptic delays. This works since we know that an event at time \(t\) can have an effect at time \(t + T_{min}\) at the soonest. The factor of one half stems from double-buffering to overlap communication and computation. So, Arbor collects all events in an epoch and transmits them in bulk, see Communication for details.
Integration in Arbor is then split into three parts:
apply effect of events to mechanisms Event Handling
evolve mechanisms and apply currents Mechanisms
solve voltage equations, see Solver
Integration proceeds as far as possible without needing to process an event, but at most with the given time step dt.