diff --git a/doc/concepts/cable_cell.rst b/doc/concepts/cable_cell.rst index 4c5d27a35785cc53edad8c6e06e62a369f88dcbe..6ce770812f847c8971bdcb1a30b03cb3131fc54b 100644 --- a/doc/concepts/cable_cell.rst +++ b/doc/concepts/cable_cell.rst @@ -10,11 +10,12 @@ Arbor cable cells are constructed from a morphology and a label dictionary, and provide a rich interface for specifying the cell's dynamics. .. note:: - The cable cell does not have *one* dedicated page, it has a few more! This page describes how to build a full description of a cable cell, based on three components that are broken out into their own pages: + The cable cell has more than *one* dedicated page, it has a few more! This page describes how to build a full + description of a cable cell, based on three components that are broken out into their own pages: - * :ref:`morphology descriptions <morph-morphology>`; - * :ref:`label dictionary <labels-dictionary>` that are used to describe :ref:`locations <labels-locset>` and :ref:`regions <labels-region>` on a cell; - * :ref:`mechanisms <mechanisms>`. + * :ref:`Morphology descriptions <morph-morphology>` + * :ref:`Label dictionaries <labels-dictionary>` + * :ref:`Mechanisms <mechanisms>` It can be helpful to consult those pages for some of the sections of this page. @@ -24,13 +25,13 @@ Decoration ---------------- A cable cell is *decorated* by specifying the distribution and placement of dynamics -on the cell to produce a full description -of a cell morphology and its dynamics with all information required to build -a standalone single-cell model, or as part of a larger network. +on the cell. The decorations, coupled with a description of a cell morphology, are all +that is required to build a standalone single-cell model, or a cell that is part of +a larger network. -Decoration uses region and locset descriptions, with -their respective use for this purpose reflected in the two broad classes -of dynamics in Arbor: +Decorations use :ref:`region <labels-region>` and :ref:`locset <labels-locset>` +descriptions, with their respective use for this purpose reflected in the two broad +classes of dynamics in Arbor: * *Painted dynamics* are applied to regions of a cell, and are associated with an area of the membrane or volume of the cable. @@ -163,7 +164,7 @@ Every mechanism is described by a string with its name, and an optional list of key-value pairs that define its range parameters. Because a global parameter is fixed over the entire spatial extent -of a density mechanism, a new mechanism has to created for every +of a density mechanism, a new mechanism has to be created for every combination of global parameter values. Take for example a mechanism passive leaky dynamics: diff --git a/doc/concepts/cell.rst b/doc/concepts/cell.rst index 20658f63c45428454f09f550a0e19e6c9a91a05a..5f9865bfd8d138b0d9976fd4e55af0c6f7c443e1 100644 --- a/doc/concepts/cell.rst +++ b/doc/concepts/cell.rst @@ -76,23 +76,28 @@ Cell kinds * **Gap Junction Sites**: These refer to the sites of :ref:`gap junctions <modelgapjunctions>`. They are declared by specifying a location on a branch of the cell. - Because cable cells are the main cell kind in Arbor and have more properties than listed here, they have a :ref:`dedicated page <cablecell>`. + Because cable cells are the main cell kind in Arbor and have more properties than listed here, they have a + :ref:`dedicated page <cablecell>`. 2. **LIF Cells** - A single compartment leaky integrate and fire neuron with one **source** and one **target**. - LIF cells does not support adding additional **sources** or **targets** or gap junctions. + LIF cells are single compartment leaky integrate and fire neurons with one **source** and one **target**. + LIF cells do not support adding additional **sources** or **targets**. They do not support **gap junctions**. + They are typically used to simulate point-neuron networks. 3. **Spiking Cells** - Spike source from values inserted via a `schedule description`. It is a point neuron with one built-in **source** and no **targets**. - It does not support adding additional **sources** or **targets**. It does not support gap junctions. + Spiking cells act as spike sources from values inserted via a `schedule description`. + They are point neurons with one built-in **source** and no **targets**. + They do not support adding additional **sources** or **targets**. They do not support **gap junctions**. 4. **Benchmark Cells** - Proxy cell used for benchmarking, and used by developers to benchmark the spike exchange and event delivery infrastructure. + Benchmark cells are proxy cells used for benchmarking, and used by developers to benchmark the spike exchange and + event delivery infrastructure. -Most Arbor users will want to use the cable cell, because it's the only cell kind that supports complex morphologies and user-defined mechanisms. See cable cells :ref:`dedicated page <cablecell>`. The LIF cell can be used to build networks with point-neurons. +Most Arbor users will want to use the cable cell, which is the only cell kind that supports complex morphologies +and user-defined mechanisms. You can visit the :ref:`cable cell page <cablecell>` for more information. API --- diff --git a/doc/concepts/index.rst b/doc/concepts/index.rst index a848bd49744a271a1ee12b4d3eb11980fd8d51a8..8c4399749b5ffe30a9dc0a482806c948ddf8f7e3 100644 --- a/doc/concepts/index.rst +++ b/doc/concepts/index.rst @@ -3,7 +3,7 @@ Concepts ==================== -To understand how to use Arbor, it is helpful if you understand some of its concepts. +To learn how to use Arbor, it is helpful to understand some of its concepts. Arbor's design aims to enable scalability through abstraction. @@ -17,6 +17,10 @@ To be able to simulate a model, three basic steps need to be considered: 2. Define the computational resources available to execute the model; 3. Initiate and execute a simulation of the recipe on the chosen hardware resources. +The python front-end further abstracts away some of these steps for single cell models, where users only need to +describe the cell and simulation; and the details of the recipe and computational resources construction are +handled under the hood. Generally speaking though, these 3 steps are the building blocks of an Arbor application. + :ref:`Recipes <modelrecipe>` represent a set of neuron constructions and connections with *mechanisms* specifying ion channel and synapse dynamics in a cell-oriented manner. This has the advantage that cell data can be initiated in parallel. A cell represents the smallest unit of computation and forms the smallest unit of work distributed across processes. Arbor has built-in support for different :ref:`cell types <modelcells>`, which can be extended by adding new cell types to the C++ cell group interface. diff --git a/doc/concepts/interconnectivity.rst b/doc/concepts/interconnectivity.rst index 189cb202c02cb03de34bd565c7a8365ad8fd1819..a45c8019b2fb6c155a937fb7057fec38dc374dba 100644 --- a/doc/concepts/interconnectivity.rst +++ b/doc/concepts/interconnectivity.rst @@ -5,8 +5,8 @@ Interconnectivity Networks can be regarded as a sort of graph, where the nodes are cells and the edges describe the communications between them. In Arbor, two sorts of edges are modelled: a -connection abstracts the propagation of action potentials (spikes) through the network, -while a gap junction is used to describe a direct electrical connection between two cells. +**connection** abstracts the propagation of action potentials (spikes) through the network, +while a **gap junction** is used to describe a direct electrical connection between two cells. Connections only capture the propagation delay and attenuation associated with spike connectivity: the biophysical modelling of the chemical synapses themselves is the responsibility of the target cell model. diff --git a/doc/concepts/labels.rst b/doc/concepts/labels.rst index ba81e4e2584cd8a9fab386775108713bfed59e27..12619b588c022330e2cba794b13783445c326fc8 100644 --- a/doc/concepts/labels.rst +++ b/doc/concepts/labels.rst @@ -236,7 +236,7 @@ Locset expressions The result of ``(location 1 0.5)``, which corresponds to the mid point of branch 1. -.. label:: (terminal} +.. label:: (terminal) The location of terminal points, which are the most distal locations on the morphology. These will typically correspond to the tips, or end points, of dendrites and axons. diff --git a/doc/concepts/morphology.rst b/doc/concepts/morphology.rst index ed4b1393f309bba0c11bcbbe8407cccba714fb23..6bcad30af67023f4ec651b3746d064d5fa3af878 100644 --- a/doc/concepts/morphology.rst +++ b/doc/concepts/morphology.rst @@ -90,9 +90,7 @@ tag 2 coloured grey for axon; tag 3 coloured blue for basal dendrites. :align: center Example Python code to generate this morphology is in the :class:`segment_tree<arbor.segment_tree>` - documentation :ref:`below <morph-label-seg-code>`. - -We can apply the following labels to the segments: + documentation :ref:`here <morph-label-seg-code>`. * The tree is composed of 11 segments (1 soma, 2 axon, 8 dendrite). * The proximal ends of segments 0 and 9 (the soma and axon hillock respectively) are attached to the root of the tree. diff --git a/doc/concepts/recipe.rst b/doc/concepts/recipe.rst index be22cae55d0f34ae019485cad4ead66f06a19184..05ff1285c158b074a60ab83cac9853ab5f4a5650 100644 --- a/doc/concepts/recipe.rst +++ b/doc/concepts/recipe.rst @@ -14,6 +14,7 @@ building phase to provide information about cells in the model, such as: * the number of gap junction sites; * incoming network connections from other cells terminating on a cell; * gap junction connections on a cell. + * probes on a cell. Why recipes? -------------- @@ -22,7 +23,7 @@ The interface and design of Arbor recipes was motivated by the following aims: * Building a simulation from a recipe description must be possible in a distributed system efficiently with minimal communication. - * To minimise the amount of memory used in model building, to make it + * Minimising the amount of memory used in model building, making it possible to build and run simulations in one run. Recipe descriptions are cell-oriented, in order that the building phase can diff --git a/doc/install/build_install.rst b/doc/install/build_install.rst index 3f05513358e456efe99b16f4059c846694ae19f0..2202d29c4130da74b16cbee0bb95913b7c9069a9 100644 --- a/doc/install/build_install.rst +++ b/doc/install/build_install.rst @@ -84,7 +84,7 @@ We recommend using GCC or Clang, for which Arbor has been tested and optimised. ... .. Note:: - Is is commonly assumed that to get the best performance one should use a vendor-specific + It is commonly assumed that to get the best performance one should use a vendor-specific compiler (e.g. the Intel, Cray or IBM compilers). These compilers are often better at auto-vectorizing loops, however for everything else GCC and Clang nearly always generate more efficient code. @@ -92,7 +92,7 @@ We recommend using GCC or Clang, for which Arbor has been tested and optimised. The main computational loops in Arbor are generated from `NMODL <https://www.neuron.yale.edu/neuron/static/docs/help/neuron/nmodl/nmodl.html>`_. The generated code is explicitly vectorised, obviating the need for vendor compilers, - and we can take advantage of their benefits of GCC and Clang: + and we can take advantage of the benefits of GCC and Clang: faster compilation times; fewer compiler bugs; and better support for C++ standards. .. Note:: @@ -177,7 +177,7 @@ Building and installing Arbor Once the Arbor code has been checked out, first run CMake to configure the build, then run make. Below is a simple workflow for: **1)** getting the source; **2)** configuring the build; -**3)** building; **4)** running tests; **5)** install. +**3)** building; **4)** running tests; **5)** installing. For more detailed build configuration options, see the `quick start <quickstart_>`_ guide. @@ -334,7 +334,8 @@ for the architecture, enabling ``ARB_VECTORIZE`` will lead to a compilation erro With this flag set, the library will use architecture-specific vectorization intrinsics to implement these kernels. Arbor currently has vectorization support for x86 architectures -with AVX, AVX2 or AVX512 ISA extensions, and for ARM architectures with support for AArch64 NEON intrinsics (first available on ARMv8-A). +with AVX, AVX2 or AVX512 ISA extensions; and for AArch64 ARM architectures with NEON and SVE +(first available on ARMv8-A). .. _install-gpu: diff --git a/doc/install/index.rst b/doc/install/index.rst index 4feaa8300940fd710bea3d6ec29d41cf4b8686d7..509818e173063a550b16f36a1b64f3eb5ed6aa5f 100644 --- a/doc/install/index.rst +++ b/doc/install/index.rst @@ -3,12 +3,12 @@ Get Arbor ========= -Currently we offer three ways to get Arbor. +Currently we offer two ways to get Arbor. 1. **Python Package**. To get started quickly with Arbor using its Python API on your personal machine, see the :ref:`Python installation guide <in_python>`. 2. **Build and install from source**. To build and install Arbor, on your own machine or HPC environment, see :ref:`in_build_install`. -If you wish to use the C++ API, you'll need to build Arbor from source. Note that you can build the Python bindings with both of those as well. +If you wish to use the C++ API, you'll need to build Arbor from source. Note that you can also build the Python bindings using this method. .. toctree:: :maxdepth: 2 diff --git a/doc/install/python.rst b/doc/install/python.rst index d49b57d48c952e553864f1005efc67c2fac26deb..c08bf49273efc1996450d4f5d7d9bca78b618e7f 100644 --- a/doc/install/python.rst +++ b/doc/install/python.rst @@ -84,7 +84,7 @@ below demonstrate this for both pip and ``setup.py``. pip3 install --install-option='--mpi' ./arbor python3 ./arbor/setup.py install --mpi -**Compile with** :ref:`vectorization <install-vectorize>` on a system with SkyLake: +**Compile with** :ref:`vectorization <install-vectorize>` on a system with a SkyLake :ref:`architecture <install-architecture>`: .. code-block:: bash diff --git a/doc/tutorial/single_cell_model.rst b/doc/tutorial/single_cell_model.rst index caadeac7c82dca79344316e56f2acd09ecdf0593..f0f8c56b1bad5062705492662fe4d76697f64984 100644 --- a/doc/tutorial/single_cell_model.rst +++ b/doc/tutorial/single_cell_model.rst @@ -12,7 +12,7 @@ This guide will walk through a series of single cell models of increasing comple Links are provided to separate documentation that covers relevant topics in more detail. In an interactive Python interpreter, you can use ``help()`` on any class or function to -obtain some documentation. +obtain some documentation. (Try, for example, ``help(arbor.simulation``). .. _single_soma: @@ -21,8 +21,8 @@ Single segment cell with HH dynamics The most trivial representation of a cell in Arbor is to model the entire cell as a single cylinder. The following example shows the steps required to construct a model of a -cylindrical cell with radius 3 μm, Hodgkin–Huxley dynamics and a current clamp stimulus, -then run the model for 30 ms. +cylindrical cell with a length of 6 μm and a radius of 3 μm; Hodgkin–Huxley dynamics +and a current clamp stimulus, then run the model for 30 ms. The first step is to construct the cell. In Arbor, the abstract representation used to define a cell with branching "cable" morphology is a ``cable_cell``, which holds a @@ -53,40 +53,43 @@ create the ``cable_cell`` that represents it are as follows: Let's unpack that. -Step **(1)** above shows how the cell is represented using a :class:`arbor.segment_tree` -to which a single segment is added. Arbor's cell morphologies are constructed from a -:ref:`segment tree<morph-segment_tree>` which is a list of segments, which are tapered -cones with a *tag*. :meth:`arbor.segment_tree.append` takes 4 arguments, starting with -the parent segment. The first segment added has no parent, which is made clear by -using :class:`arbor.mnpos`. Then two :class:`arbor.mpoint` s are supplied, the proximal -and distal endpoints of the segment. Finally, an integer value is supplied to tag the -segment for future reference. +Step **(1)** constructs a :class:`arbor.segment_tree` (see also :ref:`segment tree<morph-segment_tree>`). +The segment tree is the representation used to construct the morphology of a cell. A segment is +a tapered cone with a tag; the tag can be used to classify the type of the segment (for example +soma, dendrite etc). To create a segment tree representing our single-cylinder cell, we need to add +one segment to our ``tree`` object. We use the :meth:`arbor.segment_tree.append` method, which takes +4 arguments: the parent segment which does not exist for the first segment, so we use :class:`arbor.mnpos`; +the proximal :class:`arbor.mpoint` (location and radius) of the segment; the distal :class:`arbor.mpoint` +of the segment; and the tag. -In step **(2)** a dictionary of labels is created using :class:`arbor.label_dict<arbor.label_dict>`. -Cell builders need to refer to *regions* and *locations* on a cell morphology. Arbor uses a domain -specific language (DSL) to describe regions and locations, which are given labels. We add two labels: +Step **(2)** creates a dictionary of labels (:class:`arbor.label_dict<arbor.label_dict>`). Labels give +names to :ref:`regions<labels-region>` and :ref:`location<labels-locset>` described using a DSL +based on s-expressions. Labels from the dictionary can then be used to facilitate adding synapses, +dynamics, stimulii and probes to the cell. We add two labels: * ``soma`` defines a *region* with ``(tag 1)``. Note that this corresponds to the ``tag`` parameter that was used to define the single segment in step (1). * ``center`` defines a *location* at ``(location 0 0.5)``, which is the mid point ``0.5`` of branch ``0``, which corresponds to the center of the soma on the morphology defined in step (1). -In step **(3)** a :class:`arbor.cable_cell` is constructed by combining the segment tree -with the named regions and locations. - -* "Cell-wide" properties are set through :meth:`arbor.cable_cell.set_properties`. Here, - the initial membrane potential is set to -40 mV everywhere on the cell. -* Properties can also be set to a region of the cell, which Arbor calls 'painting'. This - is meant to convey placement is not precise: we wouldn't want to manually place ion - channels all over the surface of the cell. :meth:`arbor.cable_cell.paint` lets us - instruct Arbor to use HH dynamics on the region we've labelled soma and sort the details - out for us. -* Other properties should be added to the cell on a precise :class:`arbor.location`. This is - done using the :meth:`arbor.cable_cell.place<arbor.cable_cell.place>` method. - We place a current stimulus :class:`arbor.iclamp<arbor.iclamp>` with a duration of 2 ms - and a current of 0.8 nA, starting at 10 ms on the location we've labelled 'center'. We also - place a :class:`arbor.spike_detector<arbor.spike_detector>` with a threshold of -10 mV on the - same location. +Step **(3)** constructs the :class:`arbor.cable_cell` from the segment tree and dictionary of labeled +regions and locations. The resulting cell's default properties can be modified, and we can use +:meth:`arbor.cable_cell.paint` and :meth:`arbor.cable_cell.place` to further customise it in the +following way: + +* :meth:`arbor.cable_cell.set_properties` is used to set some default properties on the entire cell. + In the above example we set the initial membrane potential to -40 mV. +* :meth:`arbor.cable_cell.paint` is used to set properties or add dynamics to a region of the cell. + We call this method 'painting' to convey that we are working on sections of a cell, as opposed to + precise locations: for example, we might want to ``paint`` an ion channel on all dendrites, and then + ``place`` a synapse at the tip of the axon. In the above example we :meth:`arbor.cable_cell.paint` + HH dynamics on the region we previously named 'soma' in our label dictionary. +* :meth:`arbor.cable_cell.place<arbor.cable_cell.place>` is used to add objects on a precise + :class:`arbor.location` on a cell. Examples of objects that are ``placed`` are synapses, + spike detectors, current stimulii, and probes. In the above example we place a current stimulus + :class:`arbor.iclamp<arbor.iclamp>` with a duration of 2 ms and a current of 0.8 nA, starting at 10 ms + on the location we previously labelled 'center'. We also place a :class:`arbor.spike_detector<arbor.spike_detector>` + with a threshold of -10 mV on the same location. Single cell model ---------------------------------------------------- @@ -112,12 +115,12 @@ recording potentials and running the simulation more easily. Step **(4)** instantiates the :class:`arbor.single_cell_model<arbor.single_cell_model>` with our single-compartment cell. -In step **(5)** a :meth:`arbor.single_cell_model.probe()<arbor.single_cell_model.probe>` -is used to record variables from the model. Three pieces of information are +Step **(5)** adds a :meth:`arbor.single_cell_model.probe()<arbor.single_cell_model.probe>` +used to record variables from the model. Three pieces of information are provided: the type of quantity we want probed (voltage), the location where we want to probe ('"center"'), and the frequency at which we want to sample (10kHz). -Finally, step **(6)** starts the actual simulation for a duration of 30 ms. +Step **(6)** runs the actual simulation for a duration of 30 ms. Results ---------------------------------------------------- @@ -141,13 +144,13 @@ results! Let's take a look at what the spike detector and a voltage probes from df = pandas.DataFrame({'t/ms': m.traces[0].time, 'U/mV': m.traces[0].value}) seaborn.relplot(data=df, kind="line", x="t/ms", y="U/mV").savefig('single_cell_model_result.svg') -In step **(7)** we access :meth:`arbor.single_cell_model.spikes<arbor.single_cell_model.spikes>` -to access the spike time. A single spike at a little over 10 ms should be printed, -which matches the stimulus we have provided in step (3). +Step **(7)** accesses :meth:`arbor.single_cell_model.spikes<arbor.single_cell_model.spikes>` +to print the spike times. A single spike should be generated at around the same time the stimulus +we provided in step (3) gets activated (10ms). -The other measurement we have is that of the potential, which we plot in step **(8)**. -Arbor stores sampled quantities under :meth:`arbor.single_cell_model.traces<arbor.single_cell_model.traces>`. -You should be seeing something like this: +Step **(8)** plots the measured potentials during the runtime of the simulation. The sampled quantities +can be accessed through :meth:`arbor.single_cell_model.traces<arbor.single_cell_model.traces>`. +We should be seeing something like this: .. figure:: single_cell_model_result.svg :width: 400