diff --git a/doc/concepts/benchmark_cell.rst b/doc/concepts/benchmark_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..7fd13efb8bc6a22314a361587db2863fc9d05afe --- /dev/null +++ b/doc/concepts/benchmark_cell.rst @@ -0,0 +1,25 @@ +.. _benchcell: + +Benchmark cells +=============== + +The description of a LIF cell is used to control the leaky integrate-and-fire dynamics: + + * Resting potential. + * Reset potential. + * Initial value of membrane potential. + * Membrane potential decaying constant. + * Membrane capacitance. + * Firing threshold. + * Refractory period. + +The morphology of a LIF cell is automatically modelled as a single :term:`compartment <control volume>`; each cell has one built-in +**source** and one built-in **target** which do not need to be explicitly added in the cell description. +LIF cells do not support adding additional **sources** or **targets** to the description. They do not support +**gap junctions**. They do not support adding density or point mechanisms. + +API +--- + +* :ref:`Python <pybenchcell>` +* :ref:`C++ <cppbenchcell>` diff --git a/doc/concepts/cable_cell.rst b/doc/concepts/cable_cell.rst index 3048a0458ceb9f3311935c6da160ee9d6895b900..e81e218d8e40185adf2ba1ca53d10e82e07f7d1c 100644 --- a/doc/concepts/cable_cell.rst +++ b/doc/concepts/cable_cell.rst @@ -39,6 +39,14 @@ Once constructed, the cable cell can be queried for specific information about t * 3 decors (1 for each of purkinje, granule and pyramidal). * 1 label dictionary that defines the region types. +.. toctree:: + :maxdepth: 2 + + morphology + labels + mechanisms + decor + probe_sample API --- diff --git a/doc/concepts/cell.rst b/doc/concepts/cell.rst index 8cb79eac9dc0626177f383d1264017ca3d03ee80..174d628173b91e6b6974de450d6213f0395bf3ba 100644 --- a/doc/concepts/cell.rst +++ b/doc/concepts/cell.rst @@ -38,8 +38,6 @@ The :gen:`gid` of a cell is used to determine its cell :ref:`kind <modelcellkind target or gap junction site is used to form :ref:`connections <modelconnections>` and :ref:`gap junctions <modelgapjunctions>` in the recipe. - - .. _modelcellkind: Cell kind @@ -107,64 +105,19 @@ It details everything needed to build a cell. The degree of detail differs accor 1. **Cable Cells** - The description of a cable cell can include all the following: - - * :ref:`Morphology <morph>`: composed of a branching tree of one-dimensional line segments. - Strictly speaking, Arbor represents a morphology as an *acyclic directed graph*, with the soma at - the root. - * Discretisation: specifies how to split the morphology into discrete components for the simulation. - * Initial membrane voltage. - * Initial axial resistivity. - * Initial membrane capacitance. - * Initial temperature. - * Initial ion internal and external concentrations. - * Initial ion reversal potential. - * Stimuli: such as current clamps; placed on specific :term:`locations <locset>` on the cell. - * :ref:`Density mechanisms <mechanisms-density>`: commonly used to describe ion-channel dynamics across - :term:`regions <region>` of the cell. - * :ref:`Ion reversal potential mechanisms <mechanisms-revpot>`: used to control the reversal potentials of - ions across regions of the cell. - * Synapses: implemented using :ref:`point mechanisms <mechanisms-point>` on specific locations of the cell; - typically act as **targets** of :ref:`connections <modelconnections>` in the recipe. - * Detectors: used to generate spiking events on specific locations on the cell when the voltage - increases above a certain threshold; typically act as **sources** of :ref:`connections <modelconnections>`. - * Gap junction sites: placed on a specific location on a cell and used to electrically couple the cell to - another gap junction site on another cell by forming a :ref:`gap junction <modelgapjunctions>`. - - Most Arbor users will want to use the cable cell because it is the only cell kind that supports complex - morphologies and user-defined mechanisms. See the cable cell's :ref:`dedicated page <cablecell>` for more info. - And visit the :ref:`C++ <cppcablecell>` and :ref:`Python <pycablecell>` APIs to learn how to programmatically - provide the cable cell description in Arbor. + See :ref:`cablecell`. 2. **LIF Cells** - The description of a LIF cell is used to control the leaky integrate-and-fire dynamics: - - * Resting potential. - * Reset potential. - * Initial value of membrane potential. - * Membrane potential decaying constant. - * Membrane capacitance. - * Firing threshold. - * Refractory period. - - The morphology of a LIF cell is automatically modelled as a single :term:`compartment <control volume>`; each cell has one built-in - **source** and one built-in **target** which do not need to be explicitly added in the cell description. - LIF cells do not support adding additional **sources** or **targets** to the description. They do not support - **gap junctions**. They do not support adding density or point mechanisms. + See :ref:`lifcell`. 3. **Spiking cells** - The description of a spiking cell controls the spiking schedule of the cell. Its morphology is - automatically modelled as a single :term:`compartment <control volume>`; each cell has one built-in **source** which does not need to - be explicitly added in the cell description, and no **targets**. Spiking cells do not support adding additional - **sources** or **targets**. They do not support **gap junctions**. They do not support adding density or - point mechanisms. + See :ref:`spikecell`. 4. **Benchmark Cells** - The description of a benchmark cell is used to determine the spiking schedule of the cell and manipulate its - performance efficiency. This cell is mainly used by developers. + See :ref:`benchcell`. API --- diff --git a/doc/concepts/index.rst b/doc/concepts/index.rst index a19204392d5ae0814fbb427aacfc97193c39435c..b182428091b06f6ac4735b0f853b149dbf51d030 100644 --- a/doc/concepts/index.rst +++ b/doc/concepts/index.rst @@ -1,7 +1,7 @@ .. _modelintro: -Concepts -======== +Concepts overview +================= To learn how to use Arbor, it is helpful to understand some of its concepts. Arbor's design aims to enable scalability through abstraction. @@ -34,24 +34,3 @@ of the model over the locally available computational resources. In order to visualize the result of detected spikes a spike recorder can be used, and to analyse Arbor's performance a meter manager is available. - -.. toctree:: - :maxdepth: 2 - :caption: From recipe to simulation: - - recipe - cell - interconnectivity - hardware - domdec - simulation - -.. toctree:: - :maxdepth: 2 - :caption: The cable cell: - - cable_cell - morphology - labels - mechanisms - decor diff --git a/doc/concepts/lif_cell.rst b/doc/concepts/lif_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..f6447cd262209b0ddaad8055a85a2a0201d38135 --- /dev/null +++ b/doc/concepts/lif_cell.rst @@ -0,0 +1,25 @@ +.. _lifcell: + +LIF cells +=========== + +The description of a LIF cell is used to control the leaky integrate-and-fire dynamics: + + * Resting potential. + * Reset potential. + * Initial value of membrane potential. + * Membrane potential decaying constant. + * Membrane capacitance. + * Firing threshold. + * Refractory period. + +The morphology of a LIF cell is automatically modelled as a single :term:`compartment <control volume>`; each cell has one built-in +**source** and one built-in **target** which do not need to be explicitly added in the cell description. +LIF cells do not support adding additional **sources** or **targets** to the description. They do not support +**gap junctions**. They do not support adding density or point mechanisms. + +API +--- + +* :ref:`Python <pylifcell>` +* :ref:`C++ <cpplifcell>` diff --git a/doc/concepts/morphology.rst b/doc/concepts/morphology.rst index c0bef602605a62fb1fde0e37b07070027f38589b..cf5b6758a2e7eec8ac86be045507377568477b50 100644 --- a/doc/concepts/morphology.rst +++ b/doc/concepts/morphology.rst @@ -612,132 +612,12 @@ Arbor supports morphologies described using the SWC file format and the NeuroML SWC ~~~ -Arbor supports reading morphologies described using the -`SWC <http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html>`_ file format. - -SWC files may contain comments, which are stored as metadata. And a blank line anywhere in the file is -interpreted as end of data. - -The description of the morphology is encoded as a list of samples with an id, -an `x,y,z` location in space, a radius, a tag and a parent id. Arbor parses these samples, performs some checks, -then generates a morphology according to one of three possible interpretations. - -The SWC file format specifications are not very detailed, which has lead different simulators to interpret -SWC files in different ways, especially when it comes to the soma. Arbor has its own an interpretation that -is powerful and simple to understand at the same time. However, we have also developed functions that will -interpret SWC files similarly to how the NEURON simulator would, and how the Allen Institute would. - -Despite the differences between the interpretations, there is a common set of checks that are always performed -to validate an SWC file: - -* Check that there are no duplicate ids. -* Check that the parent id of a sample is less than the id of the sample. -* Check that the parent id of a sample refers to an existing sample. - -In addition, all interpretations agree that a *segment* is (in the common case) constructed between a sample and -its parent and inherits the tag of the sample; and if more than 1 sample have the same parent, the parent sample -is interpreted as a fork point in the morphology, and acts as the proximal point to a new branch for each of its -"child" samples. There a couple of exceptions to these rules which are listed below. - -Arbor interpretation: -""""""""""""""""""""" -In addition to the previously listed checks, the arbor interpretation explicitly disallows SWC files where the soma is -described by a single sample. It constructs the soma from 2 or more samples, forming 1 or more segments. A *segment* is -always constructed between a sample and its parent. This means that there are no gaps in the resulting morphology. - -Arbor has no magic rules or transformations for the soma. It can be a single branch or multiple branches; segments -of a different tag can connect to its distal end, proximal end or anywhere in the middle. For example, to create a -morphology with a single segment soma; a single segment axon connected to one end of the soma; and a single segment -dendrite connected to the other end of the soma, the following swc file can be used: - - -.. literalinclude :: example.swc - :language: python - :linenos: - -Samples 1 and 2 will form the soma; samples 1 and 3 will form the axon, connected to the soma at the proximal end; -samples 2 and 4 will form the dendrite, connected to the soma at the distal end. The morphology will look something -like this: - -.. figure:: ../gen-images/swc_morph.svg - :width: 400 - :align: center - - -Allen interpretation: -""""""""""""""""""""" -In addition to the previously mentioned checks, the Allen interpretation expects a single-sample soma to be the first -sample of the file and to be interpreted as a spherical soma. Arbor represents the spherical soma as a cylinder with -length and diameter equal to the diameter of the sample representing the sphere. - -This interpretation also expects that samples have the same tag as their parent samples, with the exception of samples -that have the soma sample as a parent. In this case, when a sample's parent is the soma, no *segment* is created -between the 2 samples; instead there is a gap in the morphology (represented electrically as a zero-resistance wire). -Samples with the soma as a parent start new segments, that connect to the distal end of the soma if they are dendrites, -or to the proximal end of the soma if they are axons or apical dendrites. Only axons, dendrites and apical dendrites -(tags 2, 3 and 4 respectively) are allowed in this interpretation, in addition to the spherical soma. - -Finally the Allen institute interpretation of SWC files centres the morphology around the soma at the origin (0, 0, 0) -and all samples are translated in space towards the origin. - -NEURON interpretation: -"""""""""""""""""""""" -The NEURON interpretation was obtained by experimenting with the ``Import3d_SWC_read`` function. We came up with the -following set of rules that govern NEURON's SWC behavior and enforced them in arbor's NEURON-complaint SWC -interpreter: - -* SWC files must contain a soma sample and it must to be the first sample. -* A soma is represented by a series of n≥1 unbranched, serially listed samples. -* A soma is constructed as a single cylinder with diameter equal to the piecewise average diameter of all the - segments forming the soma. -* A single-sample soma at is constructed as a cylinder with length=diameter. -* If a non-soma sample is to have a soma sample as its parent, it must have the most distal sample of the soma - as the parent. -* Every non-soma sample that has a soma sample as its parent, attaches to the created soma cylinder at its midpoint. -* If a non-soma sample has a soma sample as its parent, no segment is created between the sample and its parent, - instead that sample is the proximal point of a new segment, and there is a gap in the morphology (represented - electrically as a zero-resistance wire) -* To create a segment with a certain tag, that is to be attached to the soma, we need at least 2 samples with that - tag. +See :ref:`formatswc` NeuroML ~~~~~~~ -Arbor offers limited support for models described in `NeuroML version 2 <https://neuroml.org/neuromlv2>`_. -This is not built by default (see :ref:`NeuroML support <install-neuroml>` for instructions on how -to build arbor with NeuroML). - -Once support is enabled, Arbor is able to parse and check the validity of morphologies described in NeuroML files, -and present the encoded data to the user. This is more than a simple a `segment tree`. - -NeuroML can encode in the same file multiple top-level morphologies, as well as cells: - -.. code:: XML - - <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"> - <morphology id="m1"> - <segment id="seg-0"> - <proximal x="1" y="1" z="1" diameter="1"/> - <distal x="2" y="2" z="2" diameter="2"/> - </segment> - <segmentGroup id="group-0"> - <member segment="1"/> - </segmentGroup> - </morphology> - <morphology id="m2"/> - <cell id="c1" morphology="m1"/> - <cell id="c2"> - <morphology id="m3"/> - </cell> - </neuroml> - -The above NeuroML description defines 2 top-level morphologies ``m1`` and ``m2`` (empty); a cell ``c1`` that uses -morphology ``m1``; and a cell ``c2`` that uses an internally defined (empty) morphology ``m3``. - -Arbor can query the cells and morphologies using their ids and return all the associated morphological data for each. -The morphological data includes the actual morphology as well as the named segments and groups of the morphology. -For example, the above ``m1`` morphology has one named segment ``seg-0`` and one named group ``group-0`` that are -both represented using Arbor's :ref:`region expressions <labels-expressions>`. +See :ref:`formatneuroml` .. _morph-cv-policies: diff --git a/doc/concepts/probe_sample.rst b/doc/concepts/probe_sample.rst new file mode 100644 index 0000000000000000000000000000000000000000..2dd2632556660f4a673463f26aaf7fb369d0f001 --- /dev/null +++ b/doc/concepts/probe_sample.rst @@ -0,0 +1,13 @@ +.. _probesample: + +Cable cell probing and sampling +=============================== + +.. TODO:: + WIP! + +API +--- + +* :ref:`Python <pycablecell-probesample>` +* :ref:`C++ <cppcablecell-probesample>` diff --git a/doc/concepts/spike_source_cell.rst b/doc/concepts/spike_source_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..c7eca6079fe836d3d1372dff8de4056d6e426ff0 --- /dev/null +++ b/doc/concepts/spike_source_cell.rst @@ -0,0 +1,13 @@ +.. _spikecell: + +Spike source cells +================== + +The description of a benchmark cell is used to determine the spiking schedule of the cell and manipulate its +performance efficiency. This cell is mainly used by developers. + +API +--- + +* :ref:`Python <pyspikecell>` +* :ref:`C++ <cppspikecell>` diff --git a/doc/cpp/cable_cell.rst b/doc/cpp/cable_cell.rst index c8915434e41f814c3cb200a461aafae4238bff63..f0618b6b99eacf2a46b7f1838c1171bf4c0db736 100644 --- a/doc/cpp/cable_cell.rst +++ b/doc/cpp/cable_cell.rst @@ -265,317 +265,8 @@ Overriding properties locally TODO: using ``paint`` to specify electrical properties on subsections of the morphology. +.. toctree:: + :maxdepth: 1 -.. _cppcablecell--probes: - -Cable cell probes ------------------ - -Various properties of a a cable cell can be sampled via one of the cable cell -specific probe address described below. They fall into two classes: scalar -probes are associated with a single real value, such as a membrane voltage -or mechanism state value at a particular location; vector probes return -multiple values corresponding to a quantity sampled over a whole cell. - -The sample data associated with a cable cell probe will either be a ``double`` -for scalar probes, or a ``cable_sample_range`` describing a half-open range -of ``double`` values: - -.. code:: - - using cable_sample_range = std::pair<const double*, const double*> - -The probe metadata passed to the sampler will be a const pointer to: - -* ``mlocation`` for most scalar probes; - -* ``cable_probe_point_info`` for point mechanism state queries; - -* ``mcable_list`` for most vector queries; - -* ``std::vector<cable_probe_point_info>`` for cell-wide point mechanism state queries. - -The type ``cable_probe_point_info`` holds metadata for a single target on a cell: - -.. code:: - - struct cable_probe_point_info { - // Target number of point process instance on cell. - cell_lid_type target; - - // Number of combined instances at this site. - unsigned multiplicity; - - // Point on cell morphology where instance is placed. - mlocation loc; - }; - -Note that the ``multiplicity`` will always be 1 if synapse coalescing is -disabled. - -Cable cell probes that contingently do not correspond to a valid measurable -quantity are ignored: samplers attached to them will receive no values. -Mechanism state queries however will throw a ``cable_cell_error`` exception -at simulation initialization if the requested state variable does not exist -on the mechanism. - -Cable cell probe addresses that are described by a ``locset`` may generate more -than one concrete probe: there will be one per location in the locset that is -satisfiable. Sampler callback functions can distinguish between different -probes with the same address and id by examining their index and/or -probe-specific metadata found in the ``probe_metadata`` parameter. - -Membrane voltage -^^^^^^^^^^^^^^^^ - -.. code:: - - struct cable_probe_membrane_voltage { - locset locations; - }; - -Queries cell membrane potential at each site in ``locations``. - -* Sample value: ``double``. Membrane potential in millivolts. - -* Metadata: ``mlocation``. Location of probe. - - -.. code:: - - struct cable_probe_membrane_voltage_cell {}; - -Queries cell membrane potential across whole cell. - -* Sample value: ``cable_sample_range``. Each value is the - average membrane potential in millivolts across an unbranched - component of the cell, as determined by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - -Axial current -^^^^^^^^^^^^^ - -.. code:: - - struct cable_probe_axial_current { - locset locations; - }; - -Estimate intracellular current at each site in ``locations``, -in the distal direction. - -* Sample value: ``double``. Current in nanoamperes. - -* Metadata: ``mlocation``. Location as of probe. - - -Transmembrane current -^^^^^^^^^^^^^^^^^^^^^ - -.. code:: - - struct cable_probe_ion_current_density { - locset locations; - std::string ion; - }; - -Membrane current density attributed to a particular ion at -each site in ``locations``. - -* Sample value: ``double``. Current density in amperes per square metre. - -* Metadata: ``mlocation``. Location of probe. - - -.. code:: - - struct cable_probe_ion_current_cell { - std::string ion; - }; - -Membrane current attributed to a particular ion across components of the cell. - -* Sample value: ``cable_sample_range``. Each value is the current in - nanoamperes across an unbranched component of the cell, as determined - by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - -.. code:: - - struct cable_probe_total_ion_current_density { - locset locations; - }; - -Membrane current density at given locations _excluding_ capacitive currents. - -* Sample value: ``double``. Current density in amperes per square metre. - -* Metadata: ``mlocation``. Location of probe. - - -.. code:: - - struct cable_probe_total_ion_current_cell {}; - -Membrane current _excluding_ capacitive currents across components of the cell. - -* Sample value: ``cable_sample_range``. Each value is the current in - nanoamperes across an unbranched component of the cell, as determined - by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - -.. code:: - - struct cable_probe_total_current_cell {}; - -Total membrance current across components of the cell. - -* Sample value: ``cable_sample_range``. Each value is the current in - nanoamperes across an unbranched component of the cell, as determined - by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - -Ion concentration -^^^^^^^^^^^^^^^^^ - -.. code:: - - struct cable_probe_ion_int_concentration { - locset locations; - std::string ion; - }; - -Ionic internal concentration of ion at each site in ``locations``. - -* Sample value: ``double``. Ion concentration in millimoles per litre. - -* Metadata: ``mlocation``. Location of probe. - - -.. code:: - - struct cable_probe_ion_int_concentration_cell { - std::string ion; - }; - -Ionic external concentration of ion across components of the cell. - -* Sample value: ``cable_sample_range``. Each value is the concentration in - millimoles per lire across an unbranched component of the cell, as determined - by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - -.. code:: - - struct cable_probe_ion_ext_concentration { - mlocation location; - std::string ion; - }; - -Ionic external concentration of ion at each site in ``locations``. - -* Sample value: ``double``. Ion concentration in millimoles per litre. - -* Metadata: ``mlocation``. Location of probe. - - -.. code:: - - struct cable_probe_ion_ext_concentration_cell { - std::string ion; - }; - -Ionic external concentration of ion across components of the cell. - -* Sample value: ``cable_sample_range``. Each value is the concentration in - millimoles per lire across an unbranched component of the cell, as determined - by the discretisation. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - - -Mechanism state -^^^^^^^^^^^^^^^ - -.. code:: - - struct cable_probe_density_state { - locset locations; - std::string mechanism; - std::string state; - }; - - -Value of state variable in a density mechanism in each site in ``locations``. -If the mechanism is not defined at a particular site, that site is ignored. - -* Sample value: ``double``. State variable value. - -* Metadata: ``mlocation``. Location as given in the probe address. - - -.. code:: - - struct cable_probe_density_state_cell { - std::string mechanism; - std::string state; - }; - -Value of state variable in a density mechanism across components of the cell. - -* Sample value: ``cable_sample_range``. State variable values from the - mechanism across unbranched components of the cell, as determined - by the discretisation and mechanism extent. - -* Metadata: ``mcable_list``. Each cable in the cable list describes - the unbranched component for the corresponding sample value. - - -.. code:: - - struct cable_probe_point_state { - cell_lid_type target; - std::string mechanism; - std::string state; - }; - -Value of state variable in a point mechanism associated with the given target. -If the mechanism is not associated with this target, the probe is ignored. - -* Sample value: ``double``. State variable value. - -* Metadata: ``cable_probe_point_info``. Target number, multiplicity and location. - - -.. code:: - - struct cable_probe_point_state_cell { - std::string mechanism; - std::string state; - }; - -Value of state variable in a point mechanism for each of the targets in the cell -with which it is associated. - -* Sample value: ``cable_sample_range``. State variable values at each associated - target. - -* Metadata: ``std::vector<cable_probe_point_info>``. Target metadata for each - associated target. - + morphology + probe_sample diff --git a/doc/cpp/hardware.rst b/doc/cpp/hardware.rst index 3686a83f042c2c1a7b0326556cdf3de424b7ea3b..bf0dbf6ac69603c86f20d2644836364d2f88a5ff 100644 --- a/doc/cpp/hardware.rst +++ b/doc/cpp/hardware.rst @@ -391,3 +391,341 @@ system where support for GPU and MPI support are conditional. return 0; } + +.. _cppdistcontext: + +Distributed context +------------------- + +To support running on systems from laptops and workstations to large distributed +HPC clusters, Arbor uses *distributed contexts* to: + + * Describe the distributed computer system that a simulation is to be + distributed over and run on. + * Perform collective operations over the distributed system, such as gather + and synchronization. + * Query information about the distributed system, such as the number of + distributed processes and the index/rank of the calling process. + +The global context used to run a simulation is determined at run time, not at compile time. +This means that if Arbor is compiled with support for MPI enabled, then at run time the +user can choose between using a non-distributed (local) context, or an distributed MPI +context. + +An execution context is created by a user before building and running a simulation. +This context is then used to perform domain decomposition and initialize the simulation +(see :ref:`cppsimulation` for more about the simulation building workflow). +In the example below, a context that uses MPI is used to run a distributed simulation: + +The public API does not directly expose :cpp:class:`arb::distributed_context` or any of its +implementations. +By default :cpp:class:`arb::context` uses only local "on-node" resources. To use an MPI +communicator for distributed communication, it can be initialised with the communicator: + +.. container:: example-code + + .. code-block:: cpp + + arb::proc_allocation resources; + my_recipe recipe; + + // Create a context that uses the local resources enumerated in resources, + // and that uses the standard MPI communicator MPI_COMM_WORLD for + // distributed communication. + arb::context context = arb::make_context(resources, MPI_COMM_WORLD); + + // Partition model over the distributed system. + arb::domain_decomposition decomp = arb::partition_load_balance(recipe, context); + + // Instantiate the simulation over the distributed system. + arb::simulation sim(recipe, decomp, context); + + // Run the simulation for 100ms over the distributed system. + sim.run(100, 0.01); + +In the back end :cpp:class:`arb::distributed_context` defines the interface for distributed contexts, +for which two implementations are provided: :cpp:class:`arb::local_context` and :cpp:class:`arb::mpi_context`. +Distributed contexts are wrapped in shared pointers: + +.. cpp:type:: distributed_context_handle = std::shared_ptr<distributed_context> + +A distributed context can then be generated using helper functions :cpp:func:`arb::make_local_context` and +:cpp:func:`arb::make_mpi_context`: + +.. container:: example-code + + .. code-block:: cpp + + // Create a context that uses only local resources (is non-distributed). + auto dist_ctx arb::make_local_context(); + + // Create an MPI context that uses the standard MPI_COMM_WORLD communicator. + auto dist_ctx = arb::make_mpi_context(MPI_COMM_WORLD); + + +Class documentation +^^^^^^^^^^^^^^^^^^^ + +.. cpp:namespace:: arb + +.. cpp:class:: distributed_context + + Defines the interface used by Arbor to query and perform collective + operations on distributed systems. + + Uses value-semantic type erasure. The main benefit of this approach is that + classes that implement the interface can use duck typing instead of + deriving from :cpp:class:`distributed_context`. + + **Constructor:** + + .. cpp:function:: distributed_context() + + Default constructor initializes the context as a :cpp:class:`local_context`. + + .. cpp:function:: distributed_context(distributed_context&& other) + + Move constructor. + + .. cpp:function:: distributed_context& operator=(distributed_context&& other) + + Copy from rvalue. + + .. cpp:function:: template <typename Impl> distributed_context(Impl&& impl) + + Initialize with an implementation that satisfies the interface. + + **Interface:** + + .. cpp:function:: int id() const + + Each distributed process has a unique integer identifier, where the identifiers + are numbered contiguously in the half open range [0, size). + (for example ``MPI_Rank``). + + .. cpp:function:: int size() const + + The number of distributed processes (for example ``MPI_Size``). + + .. cpp:function:: void barrier() const + + A synchronization barrier where all distributed processes wait until every + process has reached the barrier (for example ``MPI_Barrier``). + + .. cpp:function:: std::string name() const + + The name of the context implementation. For example, if using MPI returns ``"MPI"``. + + .. cpp:function:: std::vector<std::string> gather(std::string value, int root) const + + Overload for gathering a string from each domain into a vector + of strings on domain :cpp:any:`root`. + + .. cpp:function:: T min(T value) const + + Reduction operation over all processes. + + The type ``T`` is one of ``float``, ``double``, ``int``, + ``std::uint32_t``, ``std::uint64_t``. + + .. cpp:function:: T max(T value) const + + Reduction operation over all processes. + + The type ``T`` is one of ``float``, ``double``, ``int``, + ``std::uint32_t``, ``std::uint64_t``. + + .. cpp:function:: T sum(T value) const + + Reduction operation over all processes. + + The type ``T`` is one of ``float``, ``double``, ``int``, + ``std::uint32_t``, ``std::uint64_t``. + + .. cpp:function:: std::vector<T> gather(T value, int root) const + + Gather operation. Returns a vector with one entry for each process. + + The type ``T`` is one of ``float``, ``double``, ``int``, + ``std::uint32_t``, ``std::uint64_t``, ``std::string``. + +.. cpp:class:: local_context + + Implements the :cpp:class:`arb::distributed_context` interface for + non-distributed computation. + + This is the default :cpp:class:`arb::distributed_context`, and should be used + when running on laptop or workstation systems with one NUMA domain. + + .. Note:: + :cpp:class:`arb::local_context` provides the simplest possible distributed context, + with only one process, and where all reduction operations are the identity operator. + + **Constructor:** + + .. cpp:function:: local_context() + + Default constructor. + +.. cpp:function:: distributed_context_handle make_local_context() + + Convenience function that returns a handle to a local context. + +.. cpp:class:: mpi_context + + Implements the :cpp:class:`arb::distributed_context` interface for + distributed computation using the MPI message passing library. + + **Constructor:** + + .. cpp:function:: mpi_context(MPI_Comm comm) + + Create a context that will uses the MPI communicator :cpp:any:`comm`. + +.. cpp:function:: distributed_context_handle make_mpi_context(MPI_Comm comm) + + Convenience function that returns a handle to a :cpp:class:`arb::mpi_context` + that uses the MPI communicator comm. + + + + +.. _cppdryrun: + +.. Note:: + This is a developer feature for benchmarking, and is not useful for scientific use cases. + +Dry-run mode +------------ + +Dry-run mode is used to mimic the performance of running an MPI distributed simulation +without having access to an HPC cluster or even MPI support. It is verifiable against an MPI +run with the same parameters. In dry-run mode, we describe the model on a single domain and +translate it to however many domains we want to mimic. This allows us to know the exact +behavior of the entire system by only running the simulation on a single node. +To support dry-run mode we use the following classes: + +.. cpp:namespace:: arb + +.. cpp:class:: dry_run_context + + Implements the :cpp:class:`arb::distributed_context` interface for a fake distributed + simulation. + + .. cpp:member:: unsigned num_ranks_ + + Number of domains we are mimicking. + + .. cpp:member:: unsigned num_cells_per_tile_ + + Number of cells assigned to each domain. + + + **Constructor:** + + .. cpp:function:: dry_run_context_impl(unsigned num_ranks, unsigned num_cells_per_tile) + + Creates the dry run context and sets up the information needed to fake communication + between domains. + + **Interface:** + + .. cpp:function:: int id() const + + Always 0. We are only performing the simulation on the local domain which will be root. + + .. cpp:function:: int size() const + + Equal to :cpp:member:`num_ranks_`. + + .. cpp:function:: std::string name() const + + Returns ``"dry_run"``. + + .. cpp:function:: std::vector<std::string> gather(std::string value, int root) const + + Duplicates the vector of strings from local domain, :cpp:member:`num_ranks_` times. + Returns the concatenated vector. + + .. cpp:function:: gathered_vector<arb::spike> gather_spikes(const std::vector<arb::spike>& local_spikes) const + + The vector of :cpp:any:`local_spikes` represents the spikes obtained from running a + simulation of :cpp:member:`num_cells_per_tile_` on the local domain. + The returned vector should contain the spikes obtained from all domains in the dry-run. + The spikes from the non-simulated domains are obtained by copying :cpp:any:`local_spikes` + and modifying the gids of each spike to refer to the corresponding gids on each domain. + The obtained vectors of spikes from each domain are concatenated along with the original + :cpp:any:`local_spikes` and returned. + + .. cpp:function:: distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) + + Convenience function that returns a handle to a :cpp:class:`dry_run_context`. + +.. cpp:class:: tile: public recipe + + .. Note:: + While this class inherits from :cpp:class:`arb::recipe`, it breaks one of its implicit + rules: it allows connection from gids greater than the total number of cells in a recipe, + :cpp:any:`ncells`. + + :cpp:class:`arb::tile` describes the model on a single domain containing :cpp:expr:`num_cells = + num_cells_per_tile` cells, which is to be duplicated over :cpp:any:`num_ranks` + domains in dry-run mode. It contains information about :cpp:any:`num_ranks` which is provided + by the following function: + + .. cpp:function:: cell_size_type num_tiles() const + + Most of the overloaded functions in :cpp:class:`arb::tile` describe a recipe on the local + domain, as if it was the only domain in the simulation, except for the following two + functions that accept :cpp:any:`gid` arguments in the half open interval + ``[0, num_cells*num_tiles)``: + + .. cpp:function:: std::vector<cell_connection> connections_on(cell_gid_type gid) const + + .. cpp:function:: std::vector<event_generator> event_generators(cell_gid_type gid) const + +.. cpp:class:: symmetric_recipe: public recipe + + A symmetric_recipe mimics having a model containing :cpp:var:`num_tiles()` + instances of :cpp:class:`arb::tile` in a simulation of one tile per domain. + + .. cpp:member:: std::unique_ptr<tile> tiled_recipe_ + + `symmetric_recipe` owns a unique pointer to a :cpp:class:`arb::tile`, and uses + :cpp:member:`tiled_recipe_` to query information about the tiles on the local + and mimicked domains. + + Most functions in `symmetric_recipe` only need to call the underlying functions + of `tiled_recipe_` for the corresponding gid in the simulated domain. This is + done with a simple modulo operation. For example: + + .. code-block:: cpp + + cell_kind get_cell_kind(cell_gid_type i) const override { + return tiled_recipe_->get_cell_kind(i % tiled_recipe_->num_cells()); + } + + The exception is again the following 2 functions: + + .. cpp:function:: std::vector<cell_connection> connections_on(cell_gid_type i) const + + Calls + + .. code-block:: cpp + + tiled_recipe_.connections_on(i % tiled_recipe_->num_cells()) + + But the obtained connections have to be translated to refer to the correct + gids corresponding to the correct domain. + + .. cpp:function:: std::vector<event_generator> event_generators(cell_gid_type i) const + + Calls + + .. code-block:: cpp + + tiled_recipe_.event_generators(i) + + Calls on the domain gid without the modulo operation, because the function has a + knowledge of the entire network. + diff --git a/doc/cpp/index.rst b/doc/cpp/index.rst index f57dc4186e9e5d573a5402794acef3c92fecae07..bd97b673ee7f18e6068665aeaef770d6fdf3ffbe 100644 --- a/doc/cpp/index.rst +++ b/doc/cpp/index.rst @@ -22,6 +22,4 @@ A :cpp:type:`arb::recipe` describes a model, and a :cpp:type:`arb::simulation` i domdec simulation profiler - neuroml cable_cell - morphology diff --git a/doc/internals/sampling_api.rst b/doc/cpp/probe_sample.rst similarity index 57% rename from doc/internals/sampling_api.rst rename to doc/cpp/probe_sample.rst index df34db517b4d2ceedc6b097a49fbe7fc14cb19ae..7ca2d0b822e35bb54d0cdcf54755801dfa23180f 100644 --- a/doc/internals/sampling_api.rst +++ b/doc/cpp/probe_sample.rst @@ -1,7 +1,326 @@ +.. _cppcablecell-probesample: + +Cable cell probing and sampling +=============================== + +.. _cppcablecell-probes: + +Cable cell probes +----------------- + +Various properties of a a cable cell can be sampled via one of the cable cell +specific probe address described below. They fall into two classes: scalar +probes are associated with a single real value, such as a membrane voltage +or mechanism state value at a particular location; vector probes return +multiple values corresponding to a quantity sampled over a whole cell. + +The sample data associated with a cable cell probe will either be a ``double`` +for scalar probes, or a ``cable_sample_range`` describing a half-open range +of ``double`` values: + +.. code:: + + using cable_sample_range = std::pair<const double*, const double*> + +The probe metadata passed to the sampler will be a const pointer to: + +* ``mlocation`` for most scalar probes; + +* ``cable_probe_point_info`` for point mechanism state queries; + +* ``mcable_list`` for most vector queries; + +* ``std::vector<cable_probe_point_info>`` for cell-wide point mechanism state queries. + +The type ``cable_probe_point_info`` holds metadata for a single target on a cell: + +.. code:: + + struct cable_probe_point_info { + // Target number of point process instance on cell. + cell_lid_type target; + + // Number of combined instances at this site. + unsigned multiplicity; + + // Point on cell morphology where instance is placed. + mlocation loc; + }; + +Note that the ``multiplicity`` will always be 1 if synapse coalescing is +disabled. + +Cable cell probes that contingently do not correspond to a valid measurable +quantity are ignored: samplers attached to them will receive no values. +Mechanism state queries however will throw a ``cable_cell_error`` exception +at simulation initialization if the requested state variable does not exist +on the mechanism. + +Cable cell probe addresses that are described by a ``locset`` may generate more +than one concrete probe: there will be one per location in the locset that is +satisfiable. Sampler callback functions can distinguish between different +probes with the same address and id by examining their index and/or +probe-specific metadata found in the ``probe_metadata`` parameter. + +Membrane voltage +^^^^^^^^^^^^^^^^ + +.. code:: + + struct cable_probe_membrane_voltage { + locset locations; + }; + +Queries cell membrane potential at each site in ``locations``. + +* Sample value: ``double``. Membrane potential in millivolts. + +* Metadata: ``mlocation``. Location of probe. + + +.. code:: + + struct cable_probe_membrane_voltage_cell {}; + +Queries cell membrane potential across whole cell. + +* Sample value: ``cable_sample_range``. Each value is the + average membrane potential in millivolts across an unbranched + component of the cell, as determined by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + +Axial current +^^^^^^^^^^^^^ + +.. code:: + + struct cable_probe_axial_current { + locset locations; + }; + +Estimate intracellular current at each site in ``locations``, +in the distal direction. + +* Sample value: ``double``. Current in nanoamperes. + +* Metadata: ``mlocation``. Location as of probe. + + +Transmembrane current +^^^^^^^^^^^^^^^^^^^^^ + +.. code:: + + struct cable_probe_ion_current_density { + locset locations; + std::string ion; + }; + +Membrane current density attributed to a particular ion at +each site in ``locations``. + +* Sample value: ``double``. Current density in amperes per square metre. + +* Metadata: ``mlocation``. Location of probe. + + +.. code:: + + struct cable_probe_ion_current_cell { + std::string ion; + }; + +Membrane current attributed to a particular ion across components of the cell. + +* Sample value: ``cable_sample_range``. Each value is the current in + nanoamperes across an unbranched component of the cell, as determined + by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + +.. code:: + + struct cable_probe_total_ion_current_density { + locset locations; + }; + +Membrane current density at given locations _excluding_ capacitive currents. + +* Sample value: ``double``. Current density in amperes per square metre. + +* Metadata: ``mlocation``. Location of probe. + + +.. code:: + + struct cable_probe_total_ion_current_cell {}; + +Membrane current _excluding_ capacitive currents across components of the cell. + +* Sample value: ``cable_sample_range``. Each value is the current in + nanoamperes across an unbranched component of the cell, as determined + by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + +.. code:: + + struct cable_probe_total_current_cell {}; + +Total membrance current across components of the cell. + +* Sample value: ``cable_sample_range``. Each value is the current in + nanoamperes across an unbranched component of the cell, as determined + by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + +Ion concentration +^^^^^^^^^^^^^^^^^ + +.. code:: + + struct cable_probe_ion_int_concentration { + locset locations; + std::string ion; + }; + +Ionic internal concentration of ion at each site in ``locations``. + +* Sample value: ``double``. Ion concentration in millimoles per litre. + +* Metadata: ``mlocation``. Location of probe. + + +.. code:: + + struct cable_probe_ion_int_concentration_cell { + std::string ion; + }; + +Ionic external concentration of ion across components of the cell. + +* Sample value: ``cable_sample_range``. Each value is the concentration in + millimoles per lire across an unbranched component of the cell, as determined + by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + +.. code:: + + struct cable_probe_ion_ext_concentration { + mlocation location; + std::string ion; + }; + +Ionic external concentration of ion at each site in ``locations``. + +* Sample value: ``double``. Ion concentration in millimoles per litre. + +* Metadata: ``mlocation``. Location of probe. + + +.. code:: + + struct cable_probe_ion_ext_concentration_cell { + std::string ion; + }; + +Ionic external concentration of ion across components of the cell. + +* Sample value: ``cable_sample_range``. Each value is the concentration in + millimoles per lire across an unbranched component of the cell, as determined + by the discretisation. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + + +Mechanism state +^^^^^^^^^^^^^^^ + +.. code:: + + struct cable_probe_density_state { + locset locations; + std::string mechanism; + std::string state; + }; + + +Value of state variable in a density mechanism in each site in ``locations``. +If the mechanism is not defined at a particular site, that site is ignored. + +* Sample value: ``double``. State variable value. + +* Metadata: ``mlocation``. Location as given in the probe address. + + +.. code:: + + struct cable_probe_density_state_cell { + std::string mechanism; + std::string state; + }; + +Value of state variable in a density mechanism across components of the cell. + +* Sample value: ``cable_sample_range``. State variable values from the + mechanism across unbranched components of the cell, as determined + by the discretisation and mechanism extent. + +* Metadata: ``mcable_list``. Each cable in the cable list describes + the unbranched component for the corresponding sample value. + + +.. code:: + + struct cable_probe_point_state { + cell_lid_type target; + std::string mechanism; + std::string state; + }; + +Value of state variable in a point mechanism associated with the given target. +If the mechanism is not associated with this target, the probe is ignored. + +* Sample value: ``double``. State variable value. + +* Metadata: ``cable_probe_point_info``. Target number, multiplicity and location. + + +.. code:: + + struct cable_probe_point_state_cell { + std::string mechanism; + std::string state; + }; + +Value of state variable in a point mechanism for each of the targets in the cell +with which it is associated. + +* Sample value: ``cable_sample_range``. State variable values at each associated + target. + +* Metadata: ``std::vector<cable_probe_point_info>``. Target metadata for each + associated target. + + .. _sampling_api: Sampling API -============ +------------ The new API replaces the flexible but irreducibly inefficient scheme where the next sample time for a sampling was determined by the @@ -9,7 +328,7 @@ return value of the sampler callback. Definitions ------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ probe A location or component of a cell that is available for monitoring. @@ -26,7 +345,7 @@ schedule Probes ------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Probes are specified in the recipe objects that are used to initialize a simulation; the specification of the item or value that is subjected to a @@ -71,7 +390,7 @@ the same id by their probe index (see below). Samplers and sample records ---------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data collected from probes (according to a schedule described below) will be passed to a sampler function or function object: @@ -154,7 +473,7 @@ may differ in type from probe to probe. Model and cell group interface ------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Polling rates, policies and sampler functions are set through the ``simulation`` interface, after construction from a recipe. @@ -235,7 +554,7 @@ if they support probes at all. Schedules ---------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Schedules represent a non-negative, monotonically increasing sequence of time points, and are used to specify the sampling schedule in any @@ -294,7 +613,7 @@ The ``schedule`` class and its implementations are found in ``schedule.hpp``. Helper classes for probe/sampler management -------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``simulation`` and ``mc_cell_group`` classes use classes defined in ``scheduler_map.hpp`` to simplify the management of sampler--probe associations @@ -306,7 +625,7 @@ accessors. Batched sampling in ``mc_cell_group`` -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``fvm_multicell`` implementations for CPU and GPU simulation of multi-compartment cable neurons perform sampling in a batched manner: when their integration is @@ -328,7 +647,3 @@ call the *sampler* callback once for probe in *probe set*, with *n* sample value In addition to the ``lax`` sampling policy, ``mc_cell_group`` supports the ``exact`` policy. Integration steps will be shortened such that any sample times associated with an ``exact`` policy can be satisfied precisely. - - - - diff --git a/doc/concepts/example.swc b/doc/fileformat/example.swc similarity index 100% rename from doc/concepts/example.swc rename to doc/fileformat/example.swc diff --git a/doc/fileformat/index.rst b/doc/fileformat/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..f92b352bbda471ddb9506857b7aa73200e10ed86 --- /dev/null +++ b/doc/fileformat/index.rst @@ -0,0 +1,14 @@ +.. _format-overview: + +File formats +============ + +Arbor supports the following file formats. + +.. toctree:: + :maxdepth: 1 + + swc + nmodl + neuroml + diff --git a/doc/cpp/neuroml.rst b/doc/fileformat/neuroml.rst similarity index 77% rename from doc/cpp/neuroml.rst rename to doc/fileformat/neuroml.rst index 290e74b2e698444640b08b742ccc5c72d6221097..f027f978412dad10f5a5a5328f097615ef9d588b 100644 --- a/doc/cpp/neuroml.rst +++ b/doc/fileformat/neuroml.rst @@ -1,4 +1,4 @@ -.. _cppneuroml: +.. _formatneuroml: NeuroML support =============== @@ -19,7 +19,6 @@ as a link library. All classes and functions provided by the ``arborio`` library are provided in the ``arborio`` namespace. - Libxml2 interface ----------------- @@ -43,6 +42,45 @@ in ``arborio/with_xml.hpp``: NeuroML 2 morphology support ---------------------------- +Arbor offers limited support for models described in `NeuroML version 2 <https://neuroml.org/neuromlv2>`_. +This is not built by default (see :ref:`NeuroML support <install-neuroml>` for instructions on how +to build arbor with NeuroML). + +Once support is enabled, Arbor is able to parse and check the validity of morphologies described in NeuroML files, +and present the encoded data to the user. This is more than a simple a `segment tree`. + +NeuroML can encode in the same file multiple top-level morphologies, as well as cells: + +.. code:: XML + + <neuroml xmlns="http://www.neuroml.org/schema/neuroml2"> + <morphology id="m1"> + <segment id="seg-0"> + <proximal x="1" y="1" z="1" diameter="1"/> + <distal x="2" y="2" z="2" diameter="2"/> + </segment> + <segmentGroup id="group-0"> + <member segment="1"/> + </segmentGroup> + </morphology> + <morphology id="m2"/> + <cell id="c1" morphology="m1"/> + <cell id="c2"> + <morphology id="m3"/> + </cell> + </neuroml> + +The above NeuroML description defines 2 top-level morphologies ``m1`` and ``m2`` (empty); a cell ``c1`` that uses +morphology ``m1``; and a cell ``c2`` that uses an internally defined (empty) morphology ``m3``. + +Arbor can query the cells and morphologies using their ids and return all the associated morphological data for each. +The morphological data includes the actual morphology as well as the named segments and groups of the morphology. +For example, the above ``m1`` morphology has one named segment ``seg-0`` and one named group ``group-0`` that are +both represented using Arbor's :ref:`region expressions <labels-expressions>`. + +C++ +^^^ + NeuroML documents are represented by the ``arborio::neuroml`` class, which in turn provides methods for the identification and translation of morphology data. ``neuroml`` objects are moveable and move-assignable, but not copyable. @@ -151,3 +189,4 @@ which is intended to identify the problematic construct within the document. A segment or segment group ultimately refers to itself via ``parent`` or ``include`` elements respectively. + diff --git a/doc/internals/nmodl.rst b/doc/fileformat/nmodl.rst similarity index 99% rename from doc/internals/nmodl.rst rename to doc/fileformat/nmodl.rst index 4757a8484b67366c875467ab600db98636223a69..bce1d3ff2c9e7bcdc04449cb9e6f518b0e7abddf 100644 --- a/doc/internals/nmodl.rst +++ b/doc/fileformat/nmodl.rst @@ -1,4 +1,4 @@ -.. _nmodl: +.. _formatnmodl: NMODL ====== @@ -97,4 +97,4 @@ Arbor-specific features POST_EVENT(t) { g = g + (0.1*t) - } \ No newline at end of file + } diff --git a/doc/fileformat/swc.rst b/doc/fileformat/swc.rst new file mode 100644 index 0000000000000000000000000000000000000000..09d3affa12dd4a29caf259cf23e3f62d1f4dbea1 --- /dev/null +++ b/doc/fileformat/swc.rst @@ -0,0 +1,93 @@ +.. _formatswc: + +SWC +~~~ + +Arbor supports reading morphologies described using the +`SWC <http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html>`_ file format. + +SWC files may contain comments, which are stored as metadata. And a blank line anywhere in the file is +interpreted as end of data. + +The description of the morphology is encoded as a list of samples with an id, +an `x,y,z` location in space, a radius, a tag and a parent id. Arbor parses these samples, performs some checks, +then generates a morphology according to one of three possible interpretations. + +The SWC file format specifications are not very detailed, which has lead different simulators to interpret +SWC files in different ways, especially when it comes to the soma. Arbor has its own an interpretation that +is powerful and simple to understand at the same time. However, we have also developed functions that will +interpret SWC files similarly to how the NEURON simulator would, and how the Allen Institute would. + +Despite the differences between the interpretations, there is a common set of checks that are always performed +to validate an SWC file: + +* Check that there are no duplicate ids. +* Check that the parent id of a sample is less than the id of the sample. +* Check that the parent id of a sample refers to an existing sample. + +In addition, all interpretations agree that a *segment* is (in the common case) constructed between a sample and +its parent and inherits the tag of the sample; and if more than 1 sample have the same parent, the parent sample +is interpreted as a fork point in the morphology, and acts as the proximal point to a new branch for each of its +"child" samples. There a couple of exceptions to these rules which are listed below. + +Arbor interpretation: +""""""""""""""""""""" +In addition to the previously listed checks, the arbor interpretation explicitly disallows SWC files where the soma is +described by a single sample. It constructs the soma from 2 or more samples, forming 1 or more segments. A *segment* is +always constructed between a sample and its parent. This means that there are no gaps in the resulting morphology. + +Arbor has no magic rules or transformations for the soma. It can be a single branch or multiple branches; segments +of a different tag can connect to its distal end, proximal end or anywhere in the middle. For example, to create a +morphology with a single segment soma; a single segment axon connected to one end of the soma; and a single segment +dendrite connected to the other end of the soma, the following swc file can be used: + + +.. literalinclude :: example.swc + :language: python + :linenos: + +Samples 1 and 2 will form the soma; samples 1 and 3 will form the axon, connected to the soma at the proximal end; +samples 2 and 4 will form the dendrite, connected to the soma at the distal end. The morphology will look something +like this: + +.. figure:: ../gen-images/swc_morph.svg + :width: 400 + :align: center + + +Allen interpretation: +""""""""""""""""""""" +In addition to the previously mentioned checks, the Allen interpretation expects a single-sample soma to be the first +sample of the file and to be interpreted as a spherical soma. Arbor represents the spherical soma as a cylinder with +length and diameter equal to the diameter of the sample representing the sphere. + +This interpretation also expects that samples have the same tag as their parent samples, with the exception of samples +that have the soma sample as a parent. In this case, when a sample's parent is the soma, no *segment* is created +between the 2 samples; instead there is a gap in the morphology (represented electrically as a zero-resistance wire). +Samples with the soma as a parent start new segments, that connect to the distal end of the soma if they are dendrites, +or to the proximal end of the soma if they are axons or apical dendrites. Only axons, dendrites and apical dendrites +(tags 2, 3 and 4 respectively) are allowed in this interpretation, in addition to the spherical soma. + +Finally the Allen institute interpretation of SWC files centres the morphology around the soma at the origin (0, 0, 0) +and all samples are translated in space towards the origin. + +NEURON interpretation: +"""""""""""""""""""""" +The NEURON interpretation was obtained by experimenting with the ``Import3d_SWC_read`` function. We came up with the +following set of rules that govern NEURON's SWC behavior and enforced them in arbor's NEURON-complaint SWC +interpreter: + +* SWC files must contain a soma sample and it must to be the first sample. +* A soma is represented by a series of n≥1 unbranched, serially listed samples. +* A soma is constructed as a single cylinder with diameter equal to the piecewise average diameter of all the + segments forming the soma. +* A single-sample soma at is constructed as a cylinder with length=diameter. +* If a non-soma sample is to have a soma sample as its parent, it must have the most distal sample of the soma + as the parent. +* Every non-soma sample that has a soma sample as its parent, attaches to the created soma cylinder at its midpoint. +* If a non-soma sample has a soma sample as its parent, no segment is created between the sample and its parent, + instead that sample is the proximal point of a new segment, and there is a gap in the morphology (represented + electrically as a zero-resistance wire) +* To create a segment with a certain tag, that is to be attached to the soma, we need at least 2 samples with that + tag. + diff --git a/doc/hpc/distributed_context.rst b/doc/hpc/distributed_context.rst deleted file mode 100644 index 5c49a2ebc617a6e52fd72a8cdc3a82387d21d0b1..0000000000000000000000000000000000000000 --- a/doc/hpc/distributed_context.rst +++ /dev/null @@ -1,195 +0,0 @@ -.. _cppdistcontext: - -Distributed context -=================== - -To support running on systems from laptops and workstations to large distributed -HPC clusters, Arbor uses *distributed contexts* to: - - * Describe the distributed computer system that a simulation is to be - distributed over and run on. - * Perform collective operations over the distributed system, such as gather - and synchronization. - * Query information about the distributed system, such as the number of - distributed processes and the index/rank of the calling process. - -The global context used to run a simulation is determined at run time, not at compile time. -This means that if Arbor is compiled with support for MPI enabled, then at run time the -user can choose between using a non-distributed (local) context, or an distributed MPI -context. - -An execution context is created by a user before building and running a simulation. -This context is then used to perform domain decomposition and initialize the simulation -(see :ref:`cppsimulation` for more about the simulation building workflow). -In the example below, a context that uses MPI is used to run a distributed simulation: - -The public API does not directly expose :cpp:class:`arb::distributed_context` or any of its -implementations. -By default :cpp:class:`arb::context` uses only local "on-node" resources. To use an MPI -communicator for distributed communication, it can be initialised with the communicator: - -.. container:: example-code - - .. code-block:: cpp - - arb::proc_allocation resources; - my_recipe recipe; - - // Create a context that uses the local resources enumerated in resources, - // and that uses the standard MPI communicator MPI_COMM_WORLD for - // distributed communication. - arb::context context = arb::make_context(resources, MPI_COMM_WORLD); - - // Partition model over the distributed system. - arb::domain_decomposition decomp = arb::partition_load_balance(recipe, context); - - // Instantiate the simulation over the distributed system. - arb::simulation sim(recipe, decomp, context); - - // Run the simulation for 100ms over the distributed system. - sim.run(100, 0.01); - -In the back end :cpp:class:`arb::distributed_context` defines the interface for distributed contexts, -for which two implementations are provided: :cpp:class:`arb::local_context` and :cpp:class:`arb::mpi_context`. -Distributed contexts are wrapped in shared pointers: - -.. cpp:type:: distributed_context_handle = std::shared_ptr<distributed_context> - -A distributed context can then be generated using helper functions :cpp:func:`arb::make_local_context` and -:cpp:func:`arb::make_mpi_context`: - -.. container:: example-code - - .. code-block:: cpp - - // Create a context that uses only local resources (is non-distributed). - auto dist_ctx arb::make_local_context(); - - // Create an MPI context that uses the standard MPI_COMM_WORLD communicator. - auto dist_ctx = arb::make_mpi_context(MPI_COMM_WORLD); - - -Class documentation -------------------- - -.. cpp:namespace:: arb - -.. cpp:class:: distributed_context - - Defines the interface used by Arbor to query and perform collective - operations on distributed systems. - - Uses value-semantic type erasure. The main benefit of this approach is that - classes that implement the interface can use duck typing instead of - deriving from :cpp:class:`distributed_context`. - - **Constructor:** - - .. cpp:function:: distributed_context() - - Default constructor initializes the context as a :cpp:class:`local_context`. - - .. cpp:function:: distributed_context(distributed_context&& other) - - Move constructor. - - .. cpp:function:: distributed_context& operator=(distributed_context&& other) - - Copy from rvalue. - - .. cpp:function:: template <typename Impl> distributed_context(Impl&& impl) - - Initialize with an implementation that satisfies the interface. - - **Interface:** - - .. cpp:function:: int id() const - - Each distributed process has a unique integer identifier, where the identifiers - are numbered contiguously in the half open range [0, size). - (for example ``MPI_Rank``). - - .. cpp:function:: int size() const - - The number of distributed processes (for example ``MPI_Size``). - - .. cpp:function:: void barrier() const - - A synchronization barrier where all distributed processes wait until every - process has reached the barrier (for example ``MPI_Barrier``). - - .. cpp:function:: std::string name() const - - The name of the context implementation. For example, if using MPI returns ``"MPI"``. - - .. cpp:function:: std::vector<std::string> gather(std::string value, int root) const - - Overload for gathering a string from each domain into a vector - of strings on domain :cpp:any:`root`. - - .. cpp:function:: T min(T value) const - - Reduction operation over all processes. - - The type ``T`` is one of ``float``, ``double``, ``int``, - ``std::uint32_t``, ``std::uint64_t``. - - .. cpp:function:: T max(T value) const - - Reduction operation over all processes. - - The type ``T`` is one of ``float``, ``double``, ``int``, - ``std::uint32_t``, ``std::uint64_t``. - - .. cpp:function:: T sum(T value) const - - Reduction operation over all processes. - - The type ``T`` is one of ``float``, ``double``, ``int``, - ``std::uint32_t``, ``std::uint64_t``. - - .. cpp:function:: std::vector<T> gather(T value, int root) const - - Gather operation. Returns a vector with one entry for each process. - - The type ``T`` is one of ``float``, ``double``, ``int``, - ``std::uint32_t``, ``std::uint64_t``, ``std::string``. - -.. cpp:class:: local_context - - Implements the :cpp:class:`arb::distributed_context` interface for - non-distributed computation. - - This is the default :cpp:class:`arb::distributed_context`, and should be used - when running on laptop or workstation systems with one NUMA domain. - - .. Note:: - :cpp:class:`arb::local_context` provides the simplest possible distributed context, - with only one process, and where all reduction operations are the identity operator. - - **Constructor:** - - .. cpp:function:: local_context() - - Default constructor. - -.. cpp:function:: distributed_context_handle make_local_context() - - Convenience function that returns a handle to a local context. - -.. cpp:class:: mpi_context - - Implements the :cpp:class:`arb::distributed_context` interface for - distributed computation using the MPI message passing library. - - **Constructor:** - - .. cpp:function:: mpi_context(MPI_Comm comm) - - Create a context that will uses the MPI communicator :cpp:any:`comm`. - -.. cpp:function:: distributed_context_handle make_mpi_context(MPI_Comm comm) - - Convenience function that returns a handle to a :cpp:class:`arb::mpi_context` - that uses the MPI communicator comm. - diff --git a/doc/hpc/dry_run.rst b/doc/hpc/dry_run.rst deleted file mode 100644 index 1a557ec01adc1c9000178c3e75790e1df6aaec02..0000000000000000000000000000000000000000 --- a/doc/hpc/dry_run.rst +++ /dev/null @@ -1,143 +0,0 @@ -.. _cppdryrun: - -.. Note:: - This is a developer feature for benchmarking, and is not useful for scientific use cases. - -Dry-run mode -=================== - -Dry-run mode is used to mimic the performance of running an MPI distributed simulation -without having access to an HPC cluster or even MPI support. It is verifiable against an MPI -run with the same parameters. In dry-run mode, we describe the model on a single domain and -translate it to however many domains we want to mimic. This allows us to know the exact -behavior of the entire system by only running the simulation on a single node. -To support dry-run mode we use the following classes: - -.. cpp:namespace:: arb - -.. cpp:class:: dry_run_context - - Implements the :cpp:class:`arb::distributed_context` interface for a fake distributed - simulation. - - .. cpp:member:: unsigned num_ranks_ - - Number of domains we are mimicking. - - .. cpp:member:: unsigned num_cells_per_tile_ - - Number of cells assigned to each domain. - - - **Constructor:** - - .. cpp:function:: dry_run_context_impl(unsigned num_ranks, unsigned num_cells_per_tile) - - Creates the dry run context and sets up the information needed to fake communication - between domains. - - **Interface:** - - .. cpp:function:: int id() const - - Always 0. We are only performing the simulation on the local domain which will be root. - - .. cpp:function:: int size() const - - Equal to :cpp:member:`num_ranks_`. - - .. cpp:function:: std::string name() const - - Returns ``"dry_run"``. - - .. cpp:function:: std::vector<std::string> gather(std::string value, int root) const - - Duplicates the vector of strings from local domain, :cpp:member:`num_ranks_` times. - Returns the concatenated vector. - - .. cpp:function:: gathered_vector<arb::spike> gather_spikes(const std::vector<arb::spike>& local_spikes) const - - The vector of :cpp:any:`local_spikes` represents the spikes obtained from running a - simulation of :cpp:member:`num_cells_per_tile_` on the local domain. - The returned vector should contain the spikes obtained from all domains in the dry-run. - The spikes from the non-simulated domains are obtained by copying :cpp:any:`local_spikes` - and modifying the gids of each spike to refer to the corresponding gids on each domain. - The obtained vectors of spikes from each domain are concatenated along with the original - :cpp:any:`local_spikes` and returned. - - .. cpp:function:: distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) - - Convenience function that returns a handle to a :cpp:class:`dry_run_context`. - -.. cpp:class:: tile: public recipe - - .. Note:: - While this class inherits from :cpp:class:`arb::recipe`, it breaks one of its implicit - rules: it allows connection from gids greater than the total number of cells in a recipe, - :cpp:any:`ncells`. - - :cpp:class:`arb::tile` describes the model on a single domain containing :cpp:expr:`num_cells = - num_cells_per_tile` cells, which is to be duplicated over :cpp:any:`num_ranks` - domains in dry-run mode. It contains information about :cpp:any:`num_ranks` which is provided - by the following function: - - .. cpp:function:: cell_size_type num_tiles() const - - Most of the overloaded functions in :cpp:class:`arb::tile` describe a recipe on the local - domain, as if it was the only domain in the simulation, except for the following two - functions that accept :cpp:any:`gid` arguments in the half open interval - ``[0, num_cells*num_tiles)``: - - .. cpp:function:: std::vector<cell_connection> connections_on(cell_gid_type gid) const - - .. cpp:function:: std::vector<event_generator> event_generators(cell_gid_type gid) const - -.. cpp:class:: symmetric_recipe: public recipe - - A symmetric_recipe mimics having a model containing :cpp:var:`num_tiles()` - instances of :cpp:class:`arb::tile` in a simulation of one tile per domain. - - .. cpp:member:: std::unique_ptr<tile> tiled_recipe_ - - `symmetric_recipe` owns a unique pointer to a :cpp:class:`arb::tile`, and uses - :cpp:member:`tiled_recipe_` to query information about the tiles on the local - and mimicked domains. - - Most functions in `symmetric_recipe` only need to call the underlying functions - of `tiled_recipe_` for the corresponding gid in the simulated domain. This is - done with a simple modulo operation. For example: - - .. code-block:: cpp - - cell_kind get_cell_kind(cell_gid_type i) const override { - return tiled_recipe_->get_cell_kind(i % tiled_recipe_->num_cells()); - } - - The exception is again the following 2 functions: - - .. cpp:function:: std::vector<cell_connection> connections_on(cell_gid_type i) const - - Calls - - .. code-block:: cpp - - tiled_recipe_.connections_on(i % tiled_recipe_->num_cells()) - - But the obtained connections have to be translated to refer to the correct - gids corresponding to the correct domain. - - .. cpp:function:: std::vector<event_generator> event_generators(cell_gid_type i) const - - Calls - - .. code-block:: cpp - - tiled_recipe_.event_generators(i) - - Calls on the domain gid without the modulo operation, because the function has a - knowledge of the entire network. - - - - - diff --git a/doc/hpc/index.rst b/doc/hpc/index.rst deleted file mode 100644 index dd39d7d521259d8fe024a7c09e3eaf3ae7a3db92..0000000000000000000000000000000000000000 --- a/doc/hpc/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _hpc-overview: - -HPC -=== - -.. toctree:: - :caption: C++ API for HPC: - :maxdepth: 2 - - distributed_context - dry_run diff --git a/doc/index.rst b/doc/index.rst index d559c817e878d2881b53211849e33ed94b5ffc25..7a55e36a995202f00c473e59a9bb72616f263876 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -27,8 +27,7 @@ Documentation organisation * :ref:`tutorial` contains a few ready-made examples you can use to quickly get started using Arbor. In the tutorial descriptions we link to the relevant Arbor concepts. * :ref:`modelintro` describes the design and concepts used in Arbor. The breakdown of concepts is mirrored (as much as possible) in the :ref:`pyoverview` and :ref:`cppoverview`, so you can easily switch between languages and concepts. -* :ref:`hpc-overview` details Arbor-features for distribution of computation over supercomputer nodes. -* :ref:`internals-overview` describes Arbor code that is not user-facing; convenience classes, architecture abstractions, etc. +* The API section details our :ref:`pyoverview` and :ref:`cppoverview` API, as well as :ref:`supported file formats <format-overview>`. :ref:`internals-overview` describes Arbor code that is not user-facing; convenience classes, architecture abstractions, etc. * Contributions to Arbor are very welcome! Under :ref:`contribindex` describe conventions and procedures for all kinds of contributions. Citing Arbor @@ -80,15 +79,35 @@ No. 785907 (Human Brain Project SGA2), and Specific Grant Agreement No. 945539 ( Arbor is an `eBrains project <https://ebrains.eu/service/arbor/>`_. .. toctree:: - :caption: Arbor documentation: + :caption: Get started: :maxdepth: 1 install/index tutorial/index + +.. toctree:: + :caption: Concepts: + :maxdepth: 1 + concepts/index + concepts/recipe + concepts/cell + concepts/interconnectivity + concepts/hardware + concepts/domdec + concepts/simulation + concepts/cable_cell + concepts/lif_cell + concepts/spike_source_cell + concepts/benchmark_cell + +.. toctree:: + :caption: API reference: + :maxdepth: 1 + python/index cpp/index - hpc/index + fileformat/index internals/index .. toctree:: diff --git a/doc/install/index.rst b/doc/install/index.rst index 509818e173063a550b16f36a1b64f3eb5ed6aa5f..892fb0045d11f96c76ba0095868b885afafe0f43 100644 --- a/doc/install/index.rst +++ b/doc/install/index.rst @@ -15,4 +15,5 @@ If you wish to use the C++ API, you'll need to build Arbor from source. Note tha :caption: Install Arbor: python + spack build_install diff --git a/doc/internals/extending-catalogues.rst b/doc/internals/extending_catalogues.rst similarity index 100% rename from doc/internals/extending-catalogues.rst rename to doc/internals/extending_catalogues.rst diff --git a/doc/internals/index.rst b/doc/internals/index.rst index 2044b739588d10e622d2c73c4be0b9a5ac187d23..b6400862987f8c9badf01d0012c4384298823ae0 100644 --- a/doc/internals/index.rst +++ b/doc/internals/index.rst @@ -10,7 +10,6 @@ Here we document internal components of Arbor. These pages can be useful if you' :maxdepth: 2 util - nmodl simd_api - sampling_api + extending_catalogues diff --git a/doc/python/benchmark_cell.rst b/doc/python/benchmark_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..aad447f2bd55459fd6b31960a62146a284c412b5 --- /dev/null +++ b/doc/python/benchmark_cell.rst @@ -0,0 +1,24 @@ +.. _pybenchcell: + +Benchmark cells +=============== + +.. currentmodule:: arbor + +.. py:class:: benchmark_cell + + A benchmarking cell, used by Arbor developers to test communication performance. + + .. function:: benchmark_cell(schedule, realtime_ratio) + + A benchmark cell generates spikes at a user-defined sequence of time points: + + - at regular intervals (using an :class:`arbor.regular_schedule`) + - at a sequence of user-defined times (using an :class:`arbor.explicit_schedule`) + - at times defined by a Poisson sequence (using an :class:`arbor.poisson_schedule`) + + and the time taken to integrate a cell can be tuned by setting the parameter ``realtime_ratio``. + + :param schedule: User-defined sequence of time points (choose from :class:`arbor.regular_schedule`, :class:`arbor.explicit_schedule`, or :class:`arbor.poisson_schedule`). + + :param realtime_ratio: Time taken to integrate a cell, for example if ``realtime_ratio`` = 2, a cell will take 2 seconds of CPU time to simulate 1 second. diff --git a/doc/python/cable_cell.rst b/doc/python/cable_cell.rst index 707bcc0dd4f442274dfbb1bc862161ec696eaa63..75a6144b5a56b9e5c6ec65959c264f93b2409bc7 100644 --- a/doc/python/cable_cell.rst +++ b/doc/python/cable_cell.rst @@ -71,152 +71,11 @@ Cable cells .. _pycablecell-probes: -Cable cell probes ------------------ - -Cable cell probe addresses are defined analagously to their counterparts in -the C++ API (see :ref:`cablecell-probes` for details). Sample data recorded -by the Arbor simulation object is returned in the form of a NumPy array, -with the first column holding sample times, and subsequent columns holding -the corresponding scalar- or vector-valued sample. - -Location expressions will be realised as zero or more specific sites on -a cell; probe addresses defined over location expressions will describe zero, -one, or more probes, one per site. They are evaluated in the context of -the cell on which the probe is attached. - -Each of the functions described below generates an opaque :class:`probe` -object for use in the recipe :py:func:`get_probes` method. - -More information on probes, probe metadata, and sampling can be found -in the documentation for the class :class:`simulation`. - -Membrane voltage - .. py:function:: cable_probe_membrane_voltage(where) - - Cell membrane potential (mV) at the sites specified by the location - expression string ``where``. This value is spatially interpolated. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_membrane_voltage_cell() - - Cell membrane potential (mV) associated with each cable in each CV of - the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - -Axial current - .. py:function:: cable_probe_axial_current(where) - - Estimation of intracellular current (nA) in the distal direction at the - sites specified by the location expression string ``where``. - - Metadata: the explicit :class:`location` of the sample site. - -Ionic current - .. py:function:: cable_probe_ion_current_density(where, ion) - - Transmembrane current density (A/m²) associated with the given ``ion`` at - sites specified by the location expression string ``where``. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_ion_current_cell(ion) - - Transmembrane current (nA) associated with the given ``ion`` across each - cable in each CV of the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - -Total ionic current - .. py:function:: cable_probe_total_ion_current_density(where) - - Transmembrane current density (A/m²) _excluding_ capacitive currents at the - sites specified by the location expression string ``where``. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_total_ion_current_cell() - - Transmembrane current (nA) _excluding_ capacitive currents across each - cable in each CV of the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - -Total transmembrane current - .. py:function:: cable_probe_total_current_cell() - - Transmembrane current (nA) _including_ capacitive currents across each - cable in each CV of the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - -Density mechanism state variable - .. py:function:: cable_probe_density_state(where, mechanism, state) - - The value of the state variable ``state`` in the density mechanism ``mechanism`` - at the sites specified by the location expression ``where``. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_density_state_cell(mechanism, state) - - The value of the state variable ``state`` in the density mechanism ``mechanism`` - on each cable in each CV of the cell discretixation. - - Metadata: the list of corresponding :class:`cable` objects. - -Point process state variable - .. py:function:: cable_probe_point_state(target, mechanism, state) - - The value of the state variable ``state`` in the point process ``mechanism`` - associated with the target index ``target`` on the cell. If the given mechanism - is not associated with the target index, no probe will be generated. - - Metadata: an object of type :class:`cable_point_probe_info`, comprising three fields: - - * ``target``: target index on the cell; - - * ``multiplicity``: number of targets sharing the same state in the discretization; - - * ``location``: :class:`location` object corresponding to the target site. - - .. py:function:: cable_probe_point_state_cell(mechanism, state) - - The value of the state variable ``state`` in the point process ``mechanism`` - at each of the targets where that mechanism is defined. - - Metadata: a list of :class:`cable_point_probe_info` values, one for each matching - target. - -Ionic internal concentration - .. py:function:: cable_probe_ion_int_concentration(where, ion) - - Ionic internal concentration (mmol/L) of the given ``ion`` at the - sites specified by the location expression string ``where``. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_ion_int_concentration_cell(ion) - - Ionic internal concentration (mmol/L) of the given ``ion`` in each able in each - CV of the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - -Ionic external concentration - .. py:function:: cable_probe_ion_ext_concentration(where, ion) - - Ionic external concentration (mmol/L) of the given ``ion`` at the - sites specified by the location expression string ``where``. - - Metadata: the explicit :class:`location` of the sample site. - - .. py:function:: cable_probe_ion_ext_concentration_cell(ion) - - Ionic external concentration (mmol/L) of the given ``ion`` in each able in each - CV of the cell discretization. - - Metadata: the list of corresponding :class:`cable` objects. - +.. toctree:: + :maxdepth: 1 + + morphology + labels + mechanisms + decor + probe_sample diff --git a/doc/python/cell.rst b/doc/python/cell.rst index 19cdb7a804114792ce1494bb640e747a1fab2460..ca1d1df158e14c8bbd22686051f1053dbca37d0c 100644 --- a/doc/python/cell.rst +++ b/doc/python/cell.rst @@ -83,70 +83,19 @@ Cell kinds ---------- .. class:: lif_cell + :noindex: - A benchmarking cell (leaky integrate-and-fire), used by Arbor developers to test communication performance, - with neuronal parameters: - - .. attribute:: tau_m - - Membrane potential decaying constant [ms]. - - .. attribute:: V_th - - Firing threshold [mV]. - - .. attribute:: C_m - - Membrane capacitance [pF]. - - .. attribute:: E_L - - Resting potential [mV]. - - .. attribute:: V_m - - Initial value of the Membrane potential [mV]. - - .. attribute:: t_ref - - Refractory period [ms]. - - .. attribute:: V_reset - - Reset potential [mV]. + See :ref:`pylifcell`. .. class:: spike_source_cell + :noindex: - A spike source cell, that generates a user-defined sequence of spikes - that act as inputs for other cells in the network. - - .. function:: spike_source_cell(schedule) - - Construct a spike source cell that generates spikes - - - at regular intervals (using an :class:`arbor.regular_schedule`) - - at a sequence of user-defined times (using an :class:`arbor.explicit_schedule`) - - at times defined by a Poisson sequence (using an :class:`arbor.poisson_schedule`) - - :param schedule: User-defined sequence of time points (choose from :class:`arbor.regular_schedule`, :class:`arbor.explicit_schedule`, or :class:`arbor.poisson_schedule`). + See :ref:`pyspikecell`. .. class:: benchmark_cell + :noindex: - A benchmarking cell, used by Arbor developers to test communication performance. - - .. function:: benchmark_cell(schedule, realtime_ratio) - - A benchmark cell generates spikes at a user-defined sequence of time points: - - - at regular intervals (using an :class:`arbor.regular_schedule`) - - at a sequence of user-defined times (using an :class:`arbor.explicit_schedule`) - - at times defined by a Poisson sequence (using an :class:`arbor.poisson_schedule`) - - and the time taken to integrate a cell can be tuned by setting the parameter ``realtime_ratio``. - - :param schedule: User-defined sequence of time points (choose from :class:`arbor.regular_schedule`, :class:`arbor.explicit_schedule`, or :class:`arbor.poisson_schedule`). - - :param realtime_ratio: Time taken to integrate a cell, for example if ``realtime_ratio`` = 2, a cell will take 2 seconds of CPU time to simulate 1 second. + See :ref:`pybenchcell`. .. class:: cable_cell :noindex: diff --git a/doc/python/index.rst b/doc/python/index.rst index c45dedcd77d82fffd5068032a52a180f143d5ce8..f3ca257b2e7a5683f85439440dbc5e1cb276521b 100644 --- a/doc/python/index.rst +++ b/doc/python/index.rst @@ -48,8 +48,7 @@ These details are described and examples are given in the next sections :ref:`py simulation profiler cable_cell - morphology - labels - mechanisms - decor + lif_cell + spike_source_cell + benchmark_cell single_cell_model diff --git a/doc/python/lif_cell.rst b/doc/python/lif_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..dfd6d469020fb61e939282165e023840cdab1721 --- /dev/null +++ b/doc/python/lif_cell.rst @@ -0,0 +1,39 @@ +.. _pylifcell: + +LIF cells +=========== + +.. currentmodule:: arbor + +.. py:class:: lif_cell + + A benchmarking cell (leaky integrate-and-fire), used by Arbor developers to test communication performance, + with neuronal parameters: + + .. attribute:: tau_m + + Membrane potential decaying constant [ms]. + + .. attribute:: V_th + + Firing threshold [mV]. + + .. attribute:: C_m + + Membrane capacitance [pF]. + + .. attribute:: E_L + + Resting potential [mV]. + + .. attribute:: V_m + + Initial value of the Membrane potential [mV]. + + .. attribute:: t_ref + + Refractory period [ms]. + + .. attribute:: V_reset + + Reset potential [mV]. \ No newline at end of file diff --git a/doc/python/probe_sample.rst b/doc/python/probe_sample.rst new file mode 100644 index 0000000000000000000000000000000000000000..663682660ee266e060daf76b60a3550e683c6009 --- /dev/null +++ b/doc/python/probe_sample.rst @@ -0,0 +1,151 @@ +.. _pycablecell-probesample: + +Cable cell probing and sampling +=============================== + +Cable cell probe addresses are defined analagously to their counterparts in +the C++ API (see :ref:`cablecell-probes` for details). Sample data recorded +by the Arbor simulation object is returned in the form of a NumPy array, +with the first column holding sample times, and subsequent columns holding +the corresponding scalar- or vector-valued sample. + +Location expressions will be realised as zero or more specific sites on +a cell; probe addresses defined over location expressions will describe zero, +one, or more probes, one per site. They are evaluated in the context of +the cell on which the probe is attached. + +Each of the functions described below generates an opaque :class:`probe` +object for use in the recipe :py:func:`get_probes` method. + +More information on probes, probe metadata, and sampling can be found +in the documentation for the class :class:`simulation`. + +Membrane voltage + .. py:function:: cable_probe_membrane_voltage(where) + + Cell membrane potential (mV) at the sites specified by the location + expression string ``where``. This value is spatially interpolated. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_membrane_voltage_cell() + + Cell membrane potential (mV) associated with each cable in each CV of + the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + +Axial current + .. py:function:: cable_probe_axial_current(where) + + Estimation of intracellular current (nA) in the distal direction at the + sites specified by the location expression string ``where``. + + Metadata: the explicit :class:`location` of the sample site. + +Ionic current + .. py:function:: cable_probe_ion_current_density(where, ion) + + Transmembrane current density (A/m²) associated with the given ``ion`` at + sites specified by the location expression string ``where``. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_ion_current_cell(ion) + + Transmembrane current (nA) associated with the given ``ion`` across each + cable in each CV of the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + +Total ionic current + .. py:function:: cable_probe_total_ion_current_density(where) + + Transmembrane current density (A/m²) _excluding_ capacitive currents at the + sites specified by the location expression string ``where``. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_total_ion_current_cell() + + Transmembrane current (nA) _excluding_ capacitive currents across each + cable in each CV of the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + +Total transmembrane current + .. py:function:: cable_probe_total_current_cell() + + Transmembrane current (nA) _including_ capacitive currents across each + cable in each CV of the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + +Density mechanism state variable + .. py:function:: cable_probe_density_state(where, mechanism, state) + + The value of the state variable ``state`` in the density mechanism ``mechanism`` + at the sites specified by the location expression ``where``. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_density_state_cell(mechanism, state) + + The value of the state variable ``state`` in the density mechanism ``mechanism`` + on each cable in each CV of the cell discretixation. + + Metadata: the list of corresponding :class:`cable` objects. + +Point process state variable + .. py:function:: cable_probe_point_state(target, mechanism, state) + + The value of the state variable ``state`` in the point process ``mechanism`` + associated with the target index ``target`` on the cell. If the given mechanism + is not associated with the target index, no probe will be generated. + + Metadata: an object of type :class:`cable_point_probe_info`, comprising three fields: + + * ``target``: target index on the cell; + + * ``multiplicity``: number of targets sharing the same state in the discretization; + + * ``location``: :class:`location` object corresponding to the target site. + + .. py:function:: cable_probe_point_state_cell(mechanism, state) + + The value of the state variable ``state`` in the point process ``mechanism`` + at each of the targets where that mechanism is defined. + + Metadata: a list of :class:`cable_point_probe_info` values, one for each matching + target. + +Ionic internal concentration + .. py:function:: cable_probe_ion_int_concentration(where, ion) + + Ionic internal concentration (mmol/L) of the given ``ion`` at the + sites specified by the location expression string ``where``. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_ion_int_concentration_cell(ion) + + Ionic internal concentration (mmol/L) of the given ``ion`` in each able in each + CV of the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + +Ionic external concentration + .. py:function:: cable_probe_ion_ext_concentration(where, ion) + + Ionic external concentration (mmol/L) of the given ``ion`` at the + sites specified by the location expression string ``where``. + + Metadata: the explicit :class:`location` of the sample site. + + .. py:function:: cable_probe_ion_ext_concentration_cell(ion) + + Ionic external concentration (mmol/L) of the given ``ion`` in each able in each + CV of the cell discretization. + + Metadata: the list of corresponding :class:`cable` objects. + diff --git a/doc/python/simulation.rst b/doc/python/simulation.rst index 410e70f7f5733530a950cbbff2f9f76802042e0e..a5e2573f14c5e52f3eac2297a03808ddde949b58 100644 --- a/doc/python/simulation.rst +++ b/doc/python/simulation.rst @@ -254,7 +254,7 @@ Definitions A measurement that can be performed on a cell. Each cell kind will have its own sorts of probe; Cable cells (:py:attr:`arbor.cable_probe`) allow the monitoring of membrane voltage, total membrane current, mechanism state, and a number of other quantities, measured either over the whole cell, - or at specific sites (see :ref:`pycablecell-probes`). + or at specific sites (see :ref:`pycablecell-probesample`). Probes are described by probe addresses, and the collection of probe addresses for a given cell is provided by the :py:class:`recipe` object. One address may correspond to more than one probe: @@ -296,7 +296,7 @@ Procedure Each probe address is an opaque object describing what to measure and where, and each cell kind will have its own set of functions for generating valid address specifications. Possible cable - cell probes are described in the cable cell documentation: :ref:`pycablecell-probes`. + cell probes are described in the cable cell documentation: :ref:`pycablecell-probesample`. 2. Instructing the simulator to record data. diff --git a/doc/python/spike_source_cell.rst b/doc/python/spike_source_cell.rst new file mode 100644 index 0000000000000000000000000000000000000000..339f5ec4e50be133911f2fcbe5f677d55bf7efc8 --- /dev/null +++ b/doc/python/spike_source_cell.rst @@ -0,0 +1,21 @@ +.. _pyspikecell: + +Spike source cells +================== + +.. currentmodule:: arbor + +.. py:class:: spike_source_cell + + A spike source cell, that generates a user-defined sequence of spikes + that act as inputs for other cells in the network. + + .. function:: spike_source_cell(schedule) + + Construct a spike source cell that generates spikes + + - at regular intervals (using an :class:`arbor.regular_schedule`) + - at a sequence of user-defined times (using an :class:`arbor.explicit_schedule`) + - at times defined by a Poisson sequence (using an :class:`arbor.poisson_schedule`) + + :param schedule: User-defined sequence of time points (choose from :class:`arbor.regular_schedule`, :class:`arbor.explicit_schedule`, or :class:`arbor.poisson_schedule`).