Skip to content

Commit

Permalink
Use mini tabs for Python/HOC fragments in NMODL pages
Browse files Browse the repository at this point in the history
  • Loading branch information
kbvw committed Jun 20, 2024
1 parent 030a61a commit 7706c51
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 52 deletions.
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"sphinx.ext.mathjax",
"nbsphinx",
"sphinx_design",
"sphinx_inline_tabs",
]

source_suffix = {
Expand Down
1 change: 1 addition & 0 deletions docs/docs_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ plotly
nbsphinx
jinja2
sphinx-design
sphinx-inline-tabs
packaging==21.3
tenacity<8.4
35 changes: 24 additions & 11 deletions docs/nmodl/language/nmodl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -722,23 +722,36 @@ Description:
However if a procedure is called
by the user, and it makes use of any range variables, then the user is
responsible for telling the mechanism from what location it should get
its range variable data. This is done in Python with
its range variable data. This is done at the Python/HOC level with

.. code-block::
python
.. tab:: Python

h.setdata_mechname(x)
.. code-block::
python
or in HOC with
h.setdata_mechname(x)
.. code-block::
none
.. tab:: HOC

.. code-block::
none
setdata_mechname(x)
where ``mechname`` is the mechanism name.

.. tab:: Python

.. note::
For range variables one must of course pass in a ``sec=section`` argument
(otherwise the so-called currently accessed section,
discoverable via h.cas(), is used).

.. tab:: HOC

setdata_mechname(x)
.. note::
For range variables there must of course be a currently accessed section.

where ``mechname`` is the mechanism name. For range variables one must
of course pass in a ``sec=section`` argument in Python (otherwise the so-called
currently accessed section, discoverable via h.cas(), is used).
In the case of Point processes, one calls procedures using the object notation

.. code-block::
Expand Down
108 changes: 67 additions & 41 deletions docs/nmodl/language/nmodl_neuron_extension.rst
Original file line number Diff line number Diff line change
Expand Up @@ -723,19 +723,21 @@ Pointer Communication


Description:
Basically what is needed is a way to implement the Python statement
Basically what is needed is a way to implement the statement

.. code-block::
python
.. tab:: Python

section1(x1).mech1.var1 = section2(x2).mech2.var2
.. code-block::
python
or the HOC statement
section1(x1).mech1.var1 = section2(x2).mech2.var2
.. code-block::
none
.. tab:: HOC

section1.var1_mech1(x1) = section2.var2_mech2(x2)
.. code-block::
none
section1.var1_mech1(x1) = section2.var2_mech2(x2)
efficiently from within a mechanism without having to explicitly connect them
through assignment at the Python/HOC level everytime the :samp:`{var2}` might change.
Expand All @@ -761,19 +763,19 @@ Description:
"located" in a section. Then, at the Python/HOC level each POINTER variable
that exists should be set up via the command

.. code-block::
python
.. tab:: Python

mechanism_object._ref_somepointer = source_obj._ref_varname
.. code-block::
python
in Python or
mechanism_object._ref_somepointer = source_obj._ref_varname
.. code-block::
none
.. tab:: HOC

setpointer pointer, variable
.. code-block::
none
in HOC.
setpointer pointer, variable
Here mechanism_object (a point process object or a density mechanism) and
the other arguments (in Python) or pointer and variable (in HOC)
Expand All @@ -782,8 +784,27 @@ Description:
mechanism, this means the section and location information. For a point
process it means the object. The reference may also be to any NEURON variable
or voltage, e.g. ``soma(0.5)._ref_v`` in Python.
See ``nrn/share/examples/nrniv/nmodl/(tstpnt1.py and tstpnt2.py)`` for examples of usage.

.. TODO: Replace hard-coded GitHub hyperlinks with a robust way to link to source files.
.. tab:: Python

.. note::
In ``nrn/share/examples/nrniv/nmodl/``, see
`tstpnt1.py <https://github.com/neuronsimulator/nrn/blob/master/share/examples/nrniv/nmodl/tstpnt1.py>`_
and
`tstpnt2.py <https://github.com/neuronsimulator/nrn/blob/master/share/examples/nrniv/nmodl/tstpnt2.py>`_
for examples of usage.

.. tab:: HOC

.. note::
In ``nrn/share/examples/nrniv/nmodl/``, see
`tstpnt1.hoc <https://github.com/neuronsimulator/nrn/blob/master/share/examples/nrniv/nmodl/tstpnt1.hoc>`_
and
`tstpnt2.hoc <https://github.com/neuronsimulator/nrn/blob/master/share/examples/nrniv/nmodl/tstpnt2.hoc>`_
for examples of usage.

For example, consider a synapse which requires a presynaptic potential
in order to calculate the amount of transmitter release. Assume the
declaration in the presynaptic model
Expand All @@ -793,44 +814,46 @@ Description:
NEURON { POINTPROCESS Syn POINTER vpre }
Then
Then

.. code-block::
python
.. tab:: Python

syn = h.Syn(section(0.8))
syn._ref_vpre = axon(1)._ref_v
.. code-block::
python
in Python or
syn = h.Syn(section(0.8))
syn._ref_vpre = axon(1)._ref_v
.. code-block::
none
.. tab:: HOC

objref syn
somedendrite {syn = new Syn(.8)}
setpointer syn.vpre, axon.v(1)
.. code-block::
none
in HOC will allow the ``syn`` object located at ``section(0.8)``
objref syn
somedendrite {syn = new Syn(.8)}
setpointer syn.vpre, axon.v(1)
will allow the ``syn`` object located at ``section(0.8)``
to know the voltage at the distal end of the axon section.
As a variation on that example, if one supposed that the synapse
needed the presynaptic transmitter concentration (call it :samp:`{tpre}`) calculated
from a point process model called "release" (with object reference :samp:`{rel}`, say)
then the statement would be

.. code-block::
python
.. tab:: Python

syn._ref_tpre = rel._ref_ACH_release
.. code-block::
python
in Python or
syn._ref_tpre = rel._ref_ACH_release
.. code-block::
none
.. tab:: HOC

setpointer syn.tpre, rel.AcH_release
.. code-block::
none
setpointer syn.tpre, rel.AcH_release
in HOC.

The caveat is that tight coupling between states in different models
may cause numerical instability. When this happens,
merging models into one larger model may eliminate the instability,
Expand All @@ -845,7 +868,10 @@ Description:
one may declare it as LOCAL, but in that case the model cannot be vectorized
and different instances cannot be called in parallel.

.. note::
.. tab:: Python

.. note::

For density mechanisms, one cannot pass in e.g. ``h.hh`` in Python as this raises a TypeError;
one can, however, pass in ``nrn.hh`` where ``nrn`` is defined via ``from neuron import nrn``.
For density mechanisms, one cannot pass in e.g. ``h.hh`` as this raises
a TypeError; one can, however, pass in ``nrn.hh`` where ``nrn`` is defined
via ``from neuron import nrn``.

0 comments on commit 7706c51

Please sign in to comment.