From b10238e037b340948fb3c44c10926ea274419d1e Mon Sep 17 00:00:00 2001 From: Brent Huisman <brenthuisman@users.noreply.github.com> Date: Thu, 14 Jan 2021 09:38:49 +0100 Subject: [PATCH] Docs: define branch, mlocation, cv default. (#1302) * Used Sphinx glossary directive to create terms that can be referred to in `concepts/morphology.rst` and `concepts/labels.rst`. * Added note box on difference with Neuron, add source for NEURON cylinder discretisation * Parameters added to svg generation script: turn off colors, root * Fix cpp TOC duplication, match ordering in other sections. * State default cv policy * center/re -> midpoints * Clarify and remove compartment term --- doc/concepts/cable_cell.rst | 38 +++-- doc/concepts/cell.rst | 12 +- doc/concepts/labels.rst | 55 ++++--- doc/concepts/morphology.rst | 221 ++++++++++++++++++++------- doc/concepts/simulation.rst | 5 +- doc/cpp/index.rst | 3 +- doc/cpp/simulation.rst | 2 +- doc/python/labels.rst | 2 +- doc/python/mechanisms.rst | 4 +- doc/scripts/inputs.py | 1 + doc/scripts/make_images.py | 71 +++++---- doc/tutorial/single_cell_model.rst | 20 +-- python/example/single_cell_model.py | 10 +- python/example/single_cell_recipe.py | 12 +- 14 files changed, 297 insertions(+), 159 deletions(-) diff --git a/doc/concepts/cable_cell.rst b/doc/concepts/cable_cell.rst index 7042c197..a1a2bfc3 100644 --- a/doc/concepts/cable_cell.rst +++ b/doc/concepts/cable_cell.rst @@ -45,7 +45,7 @@ Decoration The distribution and placement of dynamics on a cable cell is called the *decor* of a cell. A decor is composed of individual *decorations*, which associate a property or dynamic process -with a :ref:`region <labels-region>` or :ref:`locset <labels-locset>`. +with a :term:`region` or :term:`locset`. The choice of region or locset is reflected in the two broad classes of dynamics on cable cells: * *Painted dynamics* are applied to regions of a cell, and are associated with @@ -335,16 +335,33 @@ See :ref:`modelgapjunctions`. Discretisation and CV policies ------------------------------ -For the purpose of simulation, cable cells are decomposed into discrete -subcomponents called *control volumes* (CVs). The CVs are -uniquely determined by a set of *B* ``mlocation`` boundary points. -For each non-terminal point *h* in *B*, there is a CV comprising the points -{*x*: *h* ≤ *x* and ¬∃ *y* ∈ *B* s.t *h* < *y* < *x*}, where < and ≤ refer to the -geometrical partial order of locations on the morphology. A fork point is -owned by a CV if and only if all of its corresponding representative locations -are in the CV. +.. glossary:: -The set of boundary points used by the simulator is determined by a *CV policy*. + control volume + compartment + For the purpose of simulation, Arbor discretises cable cell :term:`morphologies <morphology>` + into control volumes, or CVs. Discretising happens through a :term:`CV policy`. + The CVs are uniquely determined by a set of *B* :term:`mlocation` boundary points. For each non-terminal + point *h* in *B*, there is a CV comprising the points {*x*: *h* ≤ *x* and ¬∃ *y* ∈ *B* s.t *h* < *y* < *x*}, + where < and ≤ refer to the geometrical partial order of locations on the morphology. A fork + point is owned by a CV if and only if all of its corresponding representative locations are + in the CV. + + 'Compartment' is often used to refer to the substructure in cable cells; the 'compartment' in multi-compartment cells. + A compartment is equivalent to a control volume. We avoid using 'compartment' to avoid potential confusion + with :term:`segments <segment>` or :term:`branches <branch>`. + +.. Note:: + In NEURON, discretisation is controlled through splitting a NEURON section into a + number of NEURON segments or NEURON compartments (`nseg`, `1` by default). Note that a NEURON segment/compartment is + not the same as an Arbor :term:`segment`! + +.. glossary:: + + CV policy + Generating the set of boundary points used by the simulator (discretisation) is controlled by a + :term:`CV <control volume>` policy. The default policy used to generate the set of boundary points is + ``cv_policy_fixed_per_branch(1)``. Specific CV policies are created by functions that take a ``region`` parameter that restrict the domain of applicability of that policy; this facility is useful @@ -383,7 +400,6 @@ By default, CVs will terminate at branch ends. An optional flag will be included in non-trivial, branched CVs and CVs covering terminal points in the morphology will be half-sized. - ``cv_policy_max_extent`` '''''''''''''''''''''''' diff --git a/doc/concepts/cell.rst b/doc/concepts/cell.rst index 79d3217a..8cb79eac 100644 --- a/doc/concepts/cell.rst +++ b/doc/concepts/cell.rst @@ -72,7 +72,7 @@ Cell kind 2. **LIF Cells** - LIF cells are single-compartment leaky integrate and fire neurons. They are typically used to simulate + LIF cells are :term:`single-compartment <control volume>` leaky integrate and fire neurons. They are typically used to simulate point-neuron networks. LIF cells can only interact with other cells via spike exchange over a @@ -115,13 +115,13 @@ It details everything needed to build a cell. The degree of detail differs accor * Discretisation: specifies how to split the morphology into discrete components for the simulation. * Initial membrane voltage. * Initial axial resistivity. - * Intial membrane capacitance. + * Initial membrane capacitance. * Initial temperature. * Initial ion internal and external concentrations. * Initial ion reversal potential. - * Stimuli: such as current clamps; placed on specific :ref:`locations <labels-locset>` on the cell. + * 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 - :ref:`regions <labels-region>` of the cell. + :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; @@ -148,7 +148,7 @@ It details everything needed to build a cell. The degree of detail differs accor * Firing threshold. * Refractory period. - The morphology of a LIF cell is automatically modeled as a single compartment; each cell has one built-in + 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. @@ -156,7 +156,7 @@ It details everything needed to build a cell. The degree of detail differs accor 3. **Spiking cells** The description of a spiking cell controls the spiking schedule of the cell. Its morphology is - automatically modeled as a single compartment; each cell has one built-in **source** which does not need to + 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. diff --git a/doc/concepts/labels.rst b/doc/concepts/labels.rst index 2865e326..62acfb13 100644 --- a/doc/concepts/labels.rst +++ b/doc/concepts/labels.rst @@ -3,9 +3,9 @@ Cable cell labels ================= -Arbor provides a domain specific language (DSL) for describing regions and -locations on morphologies, and a dictionary for associating these descriptions -with a string label. +Arbor provides a domain specific language (DSL) for describing :term:`regions <region>` and +:term:`locations <locset>` on :term:`morphologies <morphology>`, and a :ref:`dictionary <labels-dictionary>` for associating these :ref:`expressions <labels-expressions>` +with a string :term:`label`. The labels are used to refer to regions and locations when setting cell properties and attributes. @@ -46,13 +46,12 @@ axon proper with constant radius 0.4 μm. Label types ----------- -.. _labels-locset: +.. glossary:: + locset + A locset is a set of :term:`locations <mlocation>` on a morphology, specifically a `multiset <https://en.wikipedia.org/wiki/Multiset>`_, + which may contain multiple instances of the same location. -Locsets -~~~~~~~ - -A *locset* is a set of locations on a morphology, specifically a *multiset*, -which may contain multiple instances of the same location, for example: +Possible locsets might refer to: * The center of the soma. * The locations of inhibitory synapses. @@ -68,13 +67,12 @@ which may contain multiple instances of the same location, for example: The :ref:`root <morph-segment-definitions>` of the morphology is shown with a red circle for reference. +.. glossary:: -.. _labels-region: - -Regions -~~~~~~~ + region + A region is a subset of a morphology's cable :term:`segments <segment>`. -A *region* is a subset of a morphology's cable segments, for example: +Some common regions: * The soma. * The dendritic tree. @@ -103,7 +101,7 @@ the region of cables that have radius less than 0.5 μm Expressions ----------- -Regions and locsets are described using *expressions* written with the DSL. +:term:`Regions <region>` and :term:`locsets <locset>` are described using *expressions* written with the DSL. Examples of expressions that define regions include: @@ -366,7 +364,7 @@ Region expressions .. label:: (tag tag_id:integer) - All of the segments with :ref:`tag <morph-tag-definition>` ``tag_id``. + All of the segments with :term:`tag` ``tag_id``. .. figure:: ../gen-images/tag_label.svg :width: 900 @@ -576,19 +574,20 @@ Thingification -------------- When a region or locset expression is applied to a cell morphology, it is represented -as a list of unbranched *cables* or a set of *locations* on the morphology. +as a list of unbranched :term:`cables <cable>` or a set of :term:`locations <mlocation>` on the morphology. This process is called ``thingify`` in arbor, because it turns the abstract description -of a region or a loscet into an actual 'thing' when it is applied to a real morphology. +of a :term:`region` or a :term:`locset` into an actual 'thing' when it is applied to a real morphology. .. note:: Applying an expression to different morphologies may give different thingified results. .. _labels-locations: + Locations ~~~~~~~~~ -A *location* on a cell is described using a tuple ``(branch, pos)``, where +A :term:`location <mlocation>` on a cell is described using a tuple ``(branch, pos)``, where ``branch`` is a branch id, and ``0 ≤ pos ≤ 1`` is the relative distance along the branch, given that 0 and 1 are the proximal and distal ends of the branch respectively. @@ -601,10 +600,11 @@ Examples of locations, :ref:`expressed using the DSL <labels-location-def>`, inc * One quarter of the way along branch 5 ``(location 5 0.25)``. .. _labels-cables: + Cables ~~~~~~ -An unbranched *cable* is a tuple of the form ``(branch, prox, dist)``, +An unbranched :term:`cable` is a tuple of the form ``(branch, prox, dist)``, where ``branch`` is the branch id, and ``0 ≤ prox ≤ dist ≤ 1`` define the relative position of the end points of the section on the branch. @@ -626,14 +626,20 @@ Examples of cables, :ref:`expressed using the DSL <labels-cable-def>`, include: Label Dictionaries ------------------ -*Labels* can be assigned to expressions, and used to refer to the expression or the -concrete region or locset generated when the expression is applied to a morphology. +.. glossary:: + label + A label is a string assigned to an :ref:`expression <labels-expressions>`, and used to refer to the expression or the + concrete :term:`region` or :term:`locset` generated when the expression is applied to a morphology. + Although any string is a valid label, it is a good idea to avoid labels that would also be valid expressions in the region DSL; creating a label ``"(tag 1)"`` will only lead to confusion. -Labels are stored with their associated expressions as key-value pairs in *label dictionaries*. -Label dictionaries are then used to create a cable-cell along with the :ref:`morphology <morph>` +.. glossary:: + label dictionary + An Arbor structure in which labels are stored with their associated expressions as key-value pairs. + +Label dictionaries are used to create a cable-cell along with the :ref:`morphology <morph>` and a :ref:`decor <cablecell-decoration>`. The decorations can be painted or placed on the regions or locsets defined in the label dictionary by referring to their labels. @@ -650,7 +656,6 @@ the regions or locsets defined in the label dictionary by referring to their lab }) - API --- diff --git a/doc/concepts/morphology.rst b/doc/concepts/morphology.rst index 769c5c95..b4b53a19 100644 --- a/doc/concepts/morphology.rst +++ b/doc/concepts/morphology.rst @@ -3,86 +3,172 @@ Cable cell morphology ===================== -A cell's *morphology* describes both its geometry and branching structure. -Morphologies in Arbor are modelled as a set of one dimensional cables of variable radius, -joined together to form a tree. Only :ref:`cable cells <modelcablecell>` support custom -morphologies in Arbor. +In morphologically detailed simulations of neurons, +`the cell is modelled <https://en.wikipedia.org/wiki/Cable_theory>`_ +as a set of round electrical cables, which have, among others properties, +capacitances and resistances. These can in turn be expressed as a system of +partial differential equations which can be solved to compute a current or +voltage. The geometry of the biological cell is approximated as a tree of +cable segments, which is a :term:`morphology` in Arbor nomenclature. -The building blocks of a morphology tree are points and segments. -A *point* is a three-dimensional location and a radius, used to mark the cross-sectional -centre and radius of the cable. +Let's first define the building blocks out of which we can construct a +proper definition for a morphology. -.. csv-table:: +.. note:: + In certain cases, a second term appears in the + definitions, where the second term corresponds to the associated type in Python and C++. + The ``m`` prefix, short for *morphology*, avoids overly generic type names. + +.. glossary:: + + point + mpoint + A point in 3D space has three coordinates. In Arbor, we add a fourth coordinate: + radius. The mpoint thus represents the centre of a cable and the radius represents + the cross-sectional radius of the cable. + +.. csv-table:: The properties of a :term:`point <mpoint>`, in the context of cable cell morphologies. :widths: 10, 10, 30 + :align: center **Field**, **Type**, **Description** - ``x``, real, x coordinate of centre of cable (μm). - ``y``, real, y coordinate of centre of cable (μm). - ``z``, real, z coordinate of centre of cable (μm). + ``x``, real, x coordinate of center of cable (μm). + ``y``, real, y coordinate of center of cable (μm). + ``z``, real, z coordinate of center of cable (μm). ``radius``, real, cross sectional radius of cable (μm). +.. glossary:: -A *segment* is a frustum (cylinder or truncated cone), with the centre and radius at each -end defined by a pair of points. In other words, in Arbor the radius between two points is interpolated -linearly, resulting in either a cylinder (equal radii) or truncated cone (differing radii), -centred at the line through the pair of points. + segment + msegment + A segment is a frustum (cylinder or truncated cone), with the center and radius at each + end defined by a pair of :term:`points <mpoint>`. In other words, in Arbor the radius between two points is interpolated + linearly, resulting in either a cylinder (equal radii) or truncated cone (differing radii), + centred at the line through the pair of points. -.. csv-table:: +.. csv-table:: The properties of a :term:`segment`. :widths: 10, 10, 30 + :align: center - **Field**, **Type**, **Description** - ``prox``, :py:class:`point <arbor.mpoint>`, the center and radius of the proximal end. - ``dist``, :py:class:`point <arbor.mpoint>`, the center and radius of the distal end. - ``tag``, integer, tag meta-data. + **Field**, **Type**, **Description** + ``prox``, :term:`mpoint`, the center and radius of the proximal end. + ``dist``, :term:`mpoint`, the center and radius of the distal end. + ``tag``, integer, ":term:`tag` meta-data, can be used to classify segments of the same kind (ex: soma, dendrite, but also arbitrary use-defined groups" + +.. figure:: ../gen-images/term_segments.svg + :width: 300 + :align: center -.. _morph-tag-definition: + Four segments arranged head to toe. + +.. glossary:: + + branch + A branch is the longest possible unbranched sequence of :term:`segments <segment>`. + +.. figure:: ../gen-images/term_branch.svg + :width: 300 + :align: center + + A branch corresponding to the previous segments. + +.. glossary:: + + location + mlocation + A location is not a point in 3D space, but a point in the cable cell morphology's + coordinate system. It is defined by a specific branch and a position along the length of the branch. + +.. csv-table:: The properties of :term:`mlocation`. + :widths: 10, 10, 30 + :align: center -A *tag* is an integer label on every segment, which can be used to define disjoint -regions on cells. -The meaning of tag values are not fixed in Arbor, however we typically use tag values that correspond -to SWC `structure identifiers <http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html>`_. + **Field**, **Type**, **Description** + ``branch``, integer, id of the branch + ``pos``, real (0≤pos≤1), position along the length of the branch + +.. glossary:: + + cable + mcable + A cable is a subset of a :term:`branch`, and is thus defined as between two :term:`locations <mlocation>` on a particular branch. + +.. figure:: ../gen-images/term_cable.svg + :width: 300 + :align: center + + A cable shown in black is defined as a section :term:`located <mlocation>` between 0.2 and 0.8 of the length of the previous branch. + +.. glossary:: + + tag + A tag is an integer label on every segment, which can be used to define disjoint regions on cells. + The meaning of tag values are not fixed in Arbor, however we typically use tag values that correspond + to SWC `structure identifiers <http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html>`_. + +With these definitions, we can create proper definitions for :term:`morphology` and :term:`segment tree`. + +.. note:: + + NEURON uses different nomenclature for segments and branches. The segments (alternatively referred to as compartments) that + NEURON uses for control over discretisation (by assigning ``nseg`` segments per section) + most closely correspond to :term:`control volumes <control volume>` in Arbor. Arbor + uses truncated cones to represent branches and segments, Neuron uses a weighted + average radius to create cylinders (see "trapezoidal integration" in the + `Neuron documentation <https://www.neuron.yale.edu/neuron/static/py_doc/modelspec/programmatic/topology/geometry.html>`_.). .. _morph-segment_tree: Segment trees -------------- -A *segment tree* describes a morphology as a set of segments and their connections, -designed to support both the diverse descriptions -of cell morphologies (e.g. SWC, NeuroLicida, NeuroML), and tools that -iteratively construct cell morphologies (e.g. L-system generators, interactive cell-builders). - -Segment trees comprise a sequence of segments starting from at lease one *root* segment, -together with a parent-child adjacency relationship where a child segment is -distal to its parent. -Branches in the tree occur where a segment has more than one child. -Furthermore, a segment can not have more than one parent. -In this manner, neuron morphologies are modelled as a *tree*, where cables that +.. glossary:: + + segment tree + segment_tree + A segment tree describes a morphology as a set of :term:`segments <segment>` and their connections, + designed to support both the diverse descriptions of cell morphologies (e.g. SWC, NeuroLicida, NeuroML), + and tools that iteratively construct cell morphologies (e.g. L-system generators, interactive cell-builders). + +Segment trees comprise a sequence of segments starting from +at lease one :term:`root` segment, together with a parent-child adjacency relationship +where a child segment is distal to its parent. Branches in the tree occur where a segment +has more than one child. Furthermore, a segment can not have more than one parent. +In this manner, neuron morphologies are modelled as a tree, where cables that represent dendrites and axons can branch, but branches can not rejoin. .. _morph-segment-definitions: The following definitions are used to refer to segments in a segment tree: -* *root*: segments at the root or start of the tree. A non-empty tree must have at least one root segment, - and the first segment will always be a root. +.. glossary:: + + root + Segments at the root or start of the tree. A non-empty tree must have at least one root segment, + and the first segment will always be a root. + + parent + Each segment has one parent, except for root segments which have :data:`mnpos <arbor.mnpos>` as their parent. -* *parent*: Each segment has one parent, except for root segments which have :data:`mnpos <arbor.mnpos>` as their parent. + * The id of a segment is always greater than the id of its parent. + * The ids of segments on the same unbranched sequence of segments do not need to be contiguous. - * The id of a segment is always greater than the id of its parent. - * The ids of segments on the same unbranched sequence of segments do not need to be contiguous. + child + A segment's children are the segments that have the segment as their parent. -* *child*: A segment's children are the segments that have the segment as their parent. -* *terminal*: A segment with no children. Terminals lie at the end of dendritic trees or axons. -* *fork*: A segment with more than one child. The distal end of a fork segment are *fork points*, - where a cable splits into two or more branches. + terminal + A segment with no children. Terminals lie at the end of dendritic trees or axons. - * Arbor allows more than two branches at a fork point. + fork + A segment with more than one child. The distal end of a fork segment are *fork points*, + where a cable splits into two or more branches. + + * Arbor allows more than two branches at a fork point. The following segment tree models a soma as a cylinder, a branching dendritic tree and an axon with an axonal hillock. The segments are coloured according to their tag, which in this case are SWC structure identifiers: tag 1 coloured pink for soma; -tag 2 coloured grey for axon; tag 3 coloured blue for basal dendrites. +tag 2 coloured grey for axon; tag 3 coloured light blue for basal dendrites. .. _morph-label-seg-fig: @@ -90,7 +176,8 @@ tag 2 coloured grey for axon; tag 3 coloured blue for basal dendrites. :width: 600 :align: center - Example Python code to generate this morphology is in the :class:`segment_tree<arbor.segment_tree>` + A ten segment cable cell, with soma (pink), axon (grey) and dendrite (light blue). + Python code to generate this cable cell is in the :class:`segment_tree<arbor.segment_tree>` documentation :ref:`here <morph-label-seg-code>`. * The tree is composed of 11 segments (1 soma, 2 axon, 8 dendrite). @@ -144,11 +231,30 @@ uses 4 segments to model the soma. Morphology ---------- -A *morphology* describes the geometry of a cell as unbranched cables with variable radius, -and their associated tree structure. -Every segment tree can be used to generate a unique morphology, which derives and enumerates -*branches* from the segments. -The branches of a morphology are unbranched cables, composed of one or more segments, where: +.. glossary:: + + morphology + Morphologies in Arbor are modelled as a set of one dimensional :term:`cables <cable>` of variable radius, + joined together to form a tree. Only :ref:`cable cells <modelcablecell>` support custom + morphologies in Arbor. Morphologies can be created by :ref:`loading a file<morph-formats>` with a cell description, + or by manually constructing one from a :term:`segment tree`. + +A segment tree and a morphology can both describe the exact same cable cell geometry, and if you create a morphology *from* a segment tree, they do! The two descriptions differ in two ways: + +#. in their 'morphological coordinate system': a :term:`segment tree` is defined in terms + of connections between :term:`points <mpoint>` in 3D space, while a morphology is defined + in terms of connections between :term:`branches <branch>`. A segment tree makes it easy to + recreate a cell from image data, because that is usually done by setting points in space + and assigning a cable radius. A :term:`morphology` makes accessing locations in terms of + the cable cells shape easy: "We've placed the clamp on the midway point of the 53rd branch + of cell B." :ref:`More on placement later <labels>`. +#. the fact that angles between branches are not defined in morphologies but are in segment trees, or, + equivalently, in morphologies the branching points have no specific position in space, other than in + relation to a specific distance from other branching points through any branch that links them. + +Every segment tree can be used to generate a unique :term:`morphology`, which derives and enumerates +:term:`branches <branch>` from the segments. The branches of a morphology are unbranched cables, +composed of one or more segments, where: * the first (proximal) segment of the branch is either a root or the child of fork segment; * the last (distal) segment of the branch is either a fork or terminal segment; @@ -183,6 +289,8 @@ which is illustrated along with its branches below. :width: 800 :align: center + Left, the same 10 segment cable cell seen before. On the right, the associated morphology and branches. + Note that the :term:`root` point of the soma is always the start (and possibly end) of a branch. The code used to generate this morphology is in the :class:`segment_tree<arbor.segment_tree>` :ref:`python documentation <morph-label-seg-code>`. @@ -276,7 +384,7 @@ multiple soma and dendrite segments in branch 0. This representation of the cell morphology in terms of *branches* is what Arbor uses to create a :ref:`cable cell <cablecell>`, and it is how Arbor view's the cell's geometry and refers to it internally. - :ref:`Regions <labels-region>` and :ref:`locsets <labels-locset>` formed + :term:`Regions <region>` and :term:`locsets <locset>` formed on the cell, are eventually represented either as :ref:`subsets of branches <labels-cables>` of the morphology, or exact :ref:`locations on branches <labels-locations>` of the morphology. @@ -356,7 +464,7 @@ distinct cable segments: :align: center The morphology is an unbranched cable comprised of 4 cable segments, - coloured according to their tags: tag 1 red; tag 2 green; tag 3 blue (left). + coloured according to their tags: tag 1 pink; tag 2 grey; tag 3 light blue (left). The four segments form one branch (right). Gaps are possible between two segments. The example below inserts a 1 μm gap between the second @@ -478,7 +586,8 @@ because it has two children: the dendrites attached to its distal end. .. note:: - The discretisation process, which converts segments and branches into compartments, + The discretisation process, which converts :term:`segments <segment>` and + :term:`branches <branch>` into :term:`control volumes <control volume>`, will ignore gaps between segments in the input. The cell below, in which the dendrites and axon have been translated to remove any gaps, is equivalent to the previous example for the back end simulator. diff --git a/doc/concepts/simulation.rst b/doc/concepts/simulation.rst index abce937b..81a28eb9 100644 --- a/doc/concepts/simulation.rst +++ b/doc/concepts/simulation.rst @@ -24,9 +24,8 @@ Simulations provide an interface for executing and interacting with the model: * The simulation is executed/*run* by advancing the model state from the current simulation time to another with maximum time step size. * The model state can be *reset* to its initial state before the simulation was started. - * *Sampling* of the simulation state can be performed during execution with samplers and probes (e.g. - compartment voltage and current) and spike output with the total number of spikes generated since either - construction or reset. + * *Sampling* of the simulation state can be performed during execution with samplers and probes + and spike output with the total number of spikes generated since either construction or reset. API --- diff --git a/doc/cpp/index.rst b/doc/cpp/index.rst index ac5799ff..f57dc418 100644 --- a/doc/cpp/index.rst +++ b/doc/cpp/index.rst @@ -17,8 +17,6 @@ A :cpp:type:`arb::recipe` describes a model, and a :cpp:type:`arb::simulation` i recipe cell - cable_cell - morphology interconnectivity hardware domdec @@ -26,3 +24,4 @@ A :cpp:type:`arb::recipe` describes a model, and a :cpp:type:`arb::simulation` i profiler neuroml cable_cell + morphology diff --git a/doc/cpp/simulation.rst b/doc/cpp/simulation.rst index 79154352..929ed276 100644 --- a/doc/cpp/simulation.rst +++ b/doc/cpp/simulation.rst @@ -65,7 +65,7 @@ Class documentation * **Advance model state** from one time to another and reset model state to its original state before simulation was started. * **I/O** interface for sampling simulation state during execution - (e.g. compartment voltage and current) and spike output. + (e.g. voltage and current) and spike output. **Types:** diff --git a/doc/python/labels.rst b/doc/python/labels.rst index faef5675..83ed8d34 100644 --- a/doc/python/labels.rst +++ b/doc/python/labels.rst @@ -21,7 +21,7 @@ Cell labels .. code-block:: python labels = arbor.label_dict({'soma': '(tag 1)', # region - 'center': '(location 0 0.5)'}) # locset + 'midpoint': '(location 0 0.5)'}) # locset .. attribute:: regions diff --git a/doc/python/mechanisms.rst b/doc/python/mechanisms.rst index d744ddfa..079d5ffb 100644 --- a/doc/python/mechanisms.rst +++ b/doc/python/mechanisms.rst @@ -25,7 +25,7 @@ mechanism that is to be painted or placed on the cable cell. of a mechanism. * range parameters: the value of range parameters is defined for each instance of the mechanism on a cell. For density mechanisms, this means one value for - each compartment on which it is present. + each :term:`control volume` on which it is present. The method for setting a parameter depends on its type. If global parameters change, we are effectively defining a new type @@ -160,7 +160,7 @@ mechanism that is to be painted or placed on the cable cell. .. py:attribute:: linear :type: bool - True if a synapse mechanism has linear current contributions so that multiple instances on the same compartment can be coalesced. + True if a synapse mechanism has linear current contributions so that multiple instances on the same :term:`control volume` can be coalesced. .. py:class:: ion_dependency diff --git a/doc/scripts/inputs.py b/doc/scripts/inputs.py index 11d7da67..c7526982 100644 --- a/doc/scripts/inputs.py +++ b/doc/scripts/inputs.py @@ -135,6 +135,7 @@ reg_branch0 = {'type': 'region', 'value': [(0, 0.0, 1.0)]} reg_branch3 = {'type': 'region', 'value': [(3, 0.0, 1.0)]} reg_segment0 = {'type': 'region', 'value': [(0, 0.0, 0.3324708796524168)]} reg_segment3 = {'type': 'region', 'value': [(1, 0.0, 0.5920519526598877)]} +reg_cable_0_28 = {'type': 'region', 'value': [(0, 0.2, 0.8)]} reg_cable_1_01 = {'type': 'region', 'value': [(1, 0.0, 1.0)]} reg_cable_1_31 = {'type': 'region', 'value': [(1, 0.3, 1.0)]} reg_cable_1_37 = {'type': 'region', 'value': [(1, 0.3, 0.7)]} diff --git a/doc/scripts/make_images.py b/doc/scripts/make_images.py index 69edbde3..87daec93 100644 --- a/doc/scripts/make_images.py +++ b/doc/scripts/make_images.py @@ -3,7 +3,8 @@ import svgwrite import math import inputs -tag_colors = ['white', '#ffc2c2', 'gray', '#c2caff', '#81c8aa'] +tag_colors_colorscheme = ['white', '#ffc2c2', 'gray', '#c2caff', '#81c8aa'] +tag_colors_bwscheme = ['lightgray']*len(tag_colors_colorscheme) # # ############################################ @@ -17,8 +18,9 @@ def translate_all(points, f, xshift): # Draw one or more morphologies, side by side. # Each morphology can be drawn as segments or branches. -def morph_image(morphs, methods, filename, sc=20): +def morph_image(morphs, methods, filename, drawnumbers=True, colors=True, sc=20): assert(len(morphs)==len(methods)) + tag_colors = tag_colors_colorscheme if colors else tag_colors_bwscheme print('generating:', filename) dwg = svgwrite.Drawing(filename=filename, debug=True) @@ -79,19 +81,20 @@ def morph_image(morphs, methods, filename, sc=20): lines.add(dwg.polygon(points=line, fill=tag_colors[seg.tag])) pos = translate(seg.location(0.5), sc, offset) - points.add(dwg.circle(center=pos, - stroke='black', - r=sc*0.55, - fill='white')) - # The svg alignment_baseline attribute: - # - works on Chrome/Chromium - # - doesn't work on Firefox - # so for now we just shift the relative position by sc/3 - label_pos = (pos[0], pos[1]+sc/3) - numbers.add(dwg.text(str(segid), - insert=label_pos, - stroke='black', - fill='black')) + if drawnumbers: + points.add(dwg.circle(center=pos, + stroke='black', + r=sc*0.55, + fill='white')) + # The svg alignment_baseline attribute: + # - works on Chrome/Chromium + # - doesn't work on Firefox + # so for now we just shift the relative position by sc/3 + label_pos = (pos[0], pos[1]+sc/3) + numbers.add(dwg.text(str(segid), + insert=label_pos, + stroke='black', + fill='black')) segid += 1 elif method=='branches': @@ -99,20 +102,21 @@ def morph_image(morphs, methods, filename, sc=20): lines.add(dwg.polygon(points=translate_all(line, sc, offset), fill=branchfillcolor)) - pos = translate(branch.location(0.5), sc, offset) - points.add(dwg.circle(center=pos, - stroke=bcolor, - r=sc*0.55, - fill=bcolor)) - # The svg alignment_baseline attribute: - # - works on Chrome/Chromium - # - doesn't work on Firefox - # so for now we just shift the relative position by sc/3 - label_pos = (pos[0], pos[1]+sc/3) - numbers.add(dwg.text(str(i), - insert=label_pos, - stroke='white', - fill='white')) + if drawnumbers: + pos = translate(branch.location(0.5), sc, offset) + points.add(dwg.circle(center=pos, + stroke=bcolor, + r=sc*0.55, + fill=bcolor)) + # The svg alignment_baseline attribute: + # - works on Chrome/Chromium + # - doesn't work on Firefox + # so for now we just shift the relative position by sc/3 + label_pos = (pos[0], pos[1]+sc/3) + numbers.add(dwg.text(str(i), + insert=label_pos, + stroke='white', + fill='white')) offset = maxx - minx + sc @@ -134,7 +138,7 @@ def morph_image(morphs, methods, filename, sc=20): # ordering don't have collocated distal-proximal locations respectively. # Handling this case would make rendering regions more complex, but would # not bee too hard to support. -def label_image(morphology, labels, filename, sc=20): +def label_image(morphology, labels, filename, drawroot=True, sc=20): morph = morphology print('generating:', filename) dwg = svgwrite.Drawing(filename=filename, debug=True) @@ -188,7 +192,8 @@ def label_image(morphology, labels, filename, sc=20): # Draw the root root = translate(morph[0].location(0), sc, offset) - points.add(dwg.circle(center=root, stroke='red', r=sc/2.5, fill='white')) + if drawroot: + points.add(dwg.circle(center=root, stroke='red', r=sc/2.5, fill='white')) if lab['type'] == 'locset': for loc in lab['value']: @@ -230,6 +235,10 @@ def label_image(morphology, labels, filename, sc=20): def generate(path=''): + morph_image([inputs.branch_morph2], ['segments'], path+'/term_segments.svg', False, False) + morph_image([inputs.branch_morph2], ['branches'], path+'/term_branch.svg', False, False) + label_image(inputs.branch_morph2, [inputs.reg_cable_0_28], path+'/term_cable.svg', False) + morph_image([inputs.label_morph], ['branches'], path+'/label_branch.svg') morph_image([inputs.label_morph], ['segments'], path+'/label_seg.svg') diff --git a/doc/tutorial/single_cell_model.rst b/doc/tutorial/single_cell_model.rst index 14e2aeb8..4c838c44 100644 --- a/doc/tutorial/single_cell_model.rst +++ b/doc/tutorial/single_cell_model.rst @@ -44,16 +44,16 @@ Our *single-segment HH cell* has a simple morphology and dynamics, constructed a tree = arbor.segment_tree() tree.append(arbor.mnpos, arbor.mpoint(-3, 0, 0, 3), arbor.mpoint(3, 0, 0, 3), tag=1) - # (2) Define the soma and its center + # (2) Define the soma and its midpoint labels = arbor.label_dict({'soma': '(tag 1)', - 'center': '(location 0 0.5)'}) + 'midpoint': '(location 0 0.5)'}) # (3) Create cell and set properties decor = arbor.decor() decor.set_property(Vm=-40) decor.paint('"soma"', 'hh') - decor.place('"center"', arbor.iclamp( 10, 2, 0.8)) - decor.place('"center"', arbor.spike_detector(-10)) + decor.place('"midpoint"', arbor.iclamp( 10, 2, 0.8)) + decor.place('"midpoint"', arbor.spike_detector(-10)) # (4) Create cell cell = arbor.cable_cell(tree, labels, decor) @@ -68,14 +68,14 @@ the proximal :class:`arbor.mpoint` (location and radius) of the segment; the dis of the segment; and the tag. 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 +names to :term:`regions<region>` and :term:`location<locset>` described using a DSL based on s-expressions. Labels from the dictionary can then be used to facilitate adding synapses, dynamics, stimuli 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). +* ``midpoint`` defines a *location* at ``(location 0 0.5)``, which is the mid point ``0.5`` + of branch ``0``, which corresponds to the midpoint of the soma on the morphology defined in step (1). Step **(3)** constructs a :class:`arbor.decor` that describes the distribution and placement of dynamics and properties on a cell. The cell's default properties can be modified, and we can use @@ -93,7 +93,7 @@ following way: :class:`arbor.location` on a cell. Examples of objects that are *placed* are synapses, spike detectors, current stimuli, and probes. In the above example we place a current stimulus :class:`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` + on the location we previously labelled ``"midpoint"``. We also place a :class:`arbor.spike_detector` with a threshold of -10 mV on the same location. Step **(4)** constructs the :class:`arbor.cable_cell` from the segment tree and dictionary of labelled regions and locations. @@ -112,7 +112,7 @@ an interface for recording outputs and running the simulation. m = arbor.single_cell_model(cell) # (6) Attach voltage probe sampling at 10 kHz (every 0.1 ms). - m.probe('voltage', '"center"', frequency=10000) + m.probe('voltage', '"midpoint"', frequency=10000) # (7) Run simulation for 30 ms of simulated activity. m.run(tfinal=30) @@ -123,7 +123,7 @@ with our single-compartment cell. Step **(6)** adds a :meth:`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). +probe ('"midpoint"'), and the frequency at which we want to sample (10kHz). Step **(7)** runs the actual simulation for a duration of 30 ms. diff --git a/python/example/single_cell_model.py b/python/example/single_cell_model.py index 6701b179..319c8ee3 100755 --- a/python/example/single_cell_model.py +++ b/python/example/single_cell_model.py @@ -7,16 +7,16 @@ import pandas, seaborn # You may have to pip install these. tree = arbor.segment_tree() tree.append(arbor.mnpos, arbor.mpoint(-3, 0, 0, 3), arbor.mpoint(3, 0, 0, 3), tag=1) -# (2) Define the soma and its center +# (2) Define the soma and its midpoint labels = arbor.label_dict({'soma': '(tag 1)', - 'center': '(location 0 0.5)'}) + 'midpoint': '(location 0 0.5)'}) # (3) Create cell and set properties decor = arbor.decor() decor.set_property(Vm=-40) decor.paint('"soma"', 'hh') -decor.place('"center"', arbor.iclamp( 10, 2, 0.8)) -decor.place('"center"', arbor.spike_detector(-10)) +decor.place('"midpoint"', arbor.iclamp( 10, 2, 0.8)) +decor.place('"midpoint"', arbor.spike_detector(-10)) # (4) Create cell and the single cell model based on it cell = arbor.cable_cell(tree, labels, decor) @@ -25,7 +25,7 @@ cell = arbor.cable_cell(tree, labels, decor) m = arbor.single_cell_model(cell) # (6) Attach voltage probe sampling at 10 kHz (every 0.1 ms). -m.probe('voltage', '"center"', frequency=10000) +m.probe('voltage', '"midpoint"', frequency=10000) # (7) Run simulation for 30 ms of simulated activity. m.run(tfinal=30) diff --git a/python/example/single_cell_recipe.py b/python/example/single_cell_recipe.py index 057eb496..43a28f86 100644 --- a/python/example/single_cell_recipe.py +++ b/python/example/single_cell_recipe.py @@ -9,16 +9,16 @@ import pandas, seaborn # You may have to pip install these. tree = arbor.segment_tree() tree.append(arbor.mnpos, arbor.mpoint(-3, 0, 0, 3), arbor.mpoint(3, 0, 0, 3), tag=1) -# (2) Define the soma and its center +# (2) Define the soma and its midpoint labels = arbor.label_dict({'soma': '(tag 1)', - 'center': '(location 0 0.5)'}) + 'midpoint': '(location 0 0.5)'}) # (3) Create cell and set properties decor = arbor.decor() decor.set_property(Vm=-40) decor.paint('"soma"', 'hh') -decor.place('"center"', arbor.iclamp( 10, 2, 0.8)) -decor.place('"center"', arbor.spike_detector(-10)) +decor.place('"midpoint"', arbor.iclamp( 10, 2, 0.8)) +decor.place('"midpoint"', arbor.spike_detector(-10)) cell = arbor.cable_cell(tree, labels, decor) # (4) Define a recipe for a single cell and set of probes upon it. @@ -54,9 +54,9 @@ class single_recipe (arbor.recipe): def global_properties(self, kind): return self.the_props -# (5) Instantiate recipe with a voltage probe located on "center". +# (5) Instantiate recipe with a voltage probe located on "midpoint". -recipe = single_recipe(cell, [arbor.cable_probe_membrane_voltage('"center"')]) +recipe = single_recipe(cell, [arbor.cable_probe_membrane_voltage('"midpoint"')]) # (6) Create a default execution context and a default domain decomposition. -- GitLab