Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multisynaptic conns #846

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added doc/source/figs/multisyn_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/figs/multisyn_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 106 additions & 11 deletions doc/source/user_documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,9 @@ Each item of the ``connParams`` ordered dictionary consists of a key and value.
* **sec** (optional) - Name of target section on the postsynaptic neuron (e.g. ``'soma'``)
If omitted, defaults to 'soma' if it exists, otherwise to the first section in the cell sections list.

If ``synsPerConn`` > 1, and a list of sections or sectionList is specified, synapses will be distributed uniformly along the specified section(s), taking into account the length of each section.

If ``synsPerConn`` == 1, and list of sections or sectionList is specified, synapses (one per presynaptic cell) will be placed in sections randomly selected from the list. To enforce using always the first section from the list set ``cfg.connRandomSecFromList = False``.
Can be defined as a name of a single section, a list of sections, e.g. ``['soma', 'dend']``, or key from **secList** dictionary of post-synaptic cellParams.

If specified as a list, can be handled in different ways - see :ref:`Multisynapse connections<multisynapse_conn>` for more details.

* **loc** (optional) - Location of target synaptic mechanism (e.g. ``0.3``)
If omitted, defaults to 0.5.
Expand All @@ -390,16 +389,14 @@ Each item of the ``connParams`` ordered dictionary consists of a key and value.

If you have both a list of ``synMechs`` and ``synsPerConn`` > 1, you can have a 2D list for each synapse of each synMech (e.g. for two synMechs and ``synsPerConn`` = 3: ``[[0.2, 0.3, 0.5], [0.5, 0.6, 0.7]]``)

If ``synsPerConn`` == 1, and a list of ``loc``s is specified, synapses (one per presynaptic cell) will be placed in locations randomly selected from the list (note that the random section and location will go hand in hand, i.e. the same random index is used for both).

.. The above only applies for a single target section, ``sec``. If a list of target sections is specified, the ``loc`` value has no effect, and synapses will be distributed uniformly along the specified section(s), taking into account the length of each section. To enforce using always the first location from the list set ``cfg.connRandomSecFromList = False``.
In these multisynapse scenarios, additional parameters become available - see :ref:`Multisynapse connections<multisynapse_conn>` for more details.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be "additional combinations" or "additional options" ? or maybe I'm missing what are the new parameters available...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was referring to connRandomSecFromList and distributeSynsUniformly. Previously, they were briefly mentioned in this paragraph, but not described exhaustively, which I though might lead to confusions, so I moved it to that separate detailed section.

Maybe use "additional combinations and parameters"?



* **synMech** (optional) - Label (or list of labels) of target synaptic mechanism(s) on the postsynaptic neuron (e.g. ``'AMPA'`` or ``['AMPA', 'NMDA']``)

If omitted, employs first synaptic mechanism in the cell's synaptic mechanisms list.

If you have a list, a separate connection is created to each synMech; and a list of weights, delays and/or locs can be provided.
When using a list of synaptic mechanisms, a separate connection is created for each mechanism. You can optionally provide corresponding lists of weights, delays, and/or locations. See :ref:`Multisynapse connections<multisynapse_conn>` for more details.

* **synsPerConn** (optional) - Number of individual synaptic connections (*synapses*) per cell-to-cell connection (*connection*)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for clarity maybe add somewhere?: (Note: a cell-to-cell connection can include multiple individual synaptic connections or synaptic contacts, e.g., a presynaptic cell axon can branch and form multiple synaptic contacts at different locations of the postsynaptic cell dendrite)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I think it fits well just here in the description of synMech, even without "Note:":)
Alternatively, maybe put it in the beginning fo that separate section with detailed description, to become:

"By default, there is only one synapse created per cell-to-cell connection. However, the connection can include multiple individual synaptic connections or synaptic contacts, e.g., a presynaptic cell axon can branch and form multiple synaptic contacts at different locations of the postsynaptic cell dendrite. This can be achieved by setting synsPerConn to a value greater than 1, or by defining synMech as a list, or both."


Expand All @@ -409,11 +406,10 @@ Each item of the ``connParams`` ordered dictionary consists of a key and value.

The weights, delays and/or locs for each synapse can be specified as a list, or a single value can be used for all.

When ``synsPerConn`` > 1 and a single section is specified, the locations of synapses can be specified as a list in ``loc``.
When ``synsPerConn`` > 1 and a *single section* is specified, the locations of synapses can be specified as a list in ``loc``. If a *list of target sections* is specified, ``loc`` should be omitted, and synapses will be distributed uniformly along the specified section(s), taking into account the length of each section. See :ref:`Multisynapse connections<multisynapse_conn>` for more details.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I guess there is no way of providing a fixed location (eg 0.5) for a list of sections eg. synsePerConn=3; secs=[soma, dend1, dend2]; loc=0.5 ?

Not sure this case is required or useful, just double checking. Of course, would require that synsPerConn = len(secs), so might be confusing if it's not the case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, passing loc as single value is not possible (in previous version this value was silently ignored, and now exception is raised to attract user's attention). But one can use a workaround by having loc value repeated: loc = [0.5] * 3
This also requires settingdistributeSynsUniformly to False though (otherwise, loc is not allowed at all). This is described in the extended section.


When ``synsPerConn`` > 1, if ``loc`` is a single value or omitted, or if a list of target sections is specified, synapses will be distributed uniformly along the specified section(s), taking into account the length of each section.
If you have a list of ``synMechs``, you can have single ``synsPerConn`` value for all, or a list of values, one per synaptic mechanism in the list.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be useful to add a specific example similar to the one used for 'loc' above

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have exactly this example in the extended session.
Here I can put a 'condensed' version to not distract with extra details:

netParams.connParams['...'] = {
    'synMech': ['AMPA', 'GABA'],
    'synsPerConn': [2, 1],
# ...
# per each cell-to-cell connections, 2 AMPA synapses and 1 GABA synapse will be created



* **weight** (optional) - Strength of synaptic connection (e.g. ``0.01``)
Associated with a change in conductance, but has different meaning and scale depending on the synaptic mechanism and cell model.

Expand Down Expand Up @@ -535,6 +531,105 @@ Here is an example of connectivity rules:
'delay': [5, 10], # different delays for each of 3 synapses per synMech
'loc': [[0.1, 0.5, 0.7], [0.3, 0.4, 0.5]]} # different locations for each of the 6 synapses

.. _multisynapse_conn:

**Connectivity Rules with Multiple Synapses per Connection**

By default, there is only one synapse created per connection. However, multiple synapses can be created targeting each post-synaptic cell. This can be achieved by setting ``synsPerConn`` to a value greater than 1, or by defining ``synMech`` as a list, or both.

* Setting ``synsPerConn`` >= 1 with ``synMech`` as a single value
If ``synsPerConn`` is > 1, then for each connection, this number of synapses will be created. The weights and delays can be specified as lists, or a single value can be used for all. ``loc`` should be a list, a single value is not accepted. If ``loc`` is omitted, a uniform distribution is used (i.e., synapses are placed at equal distances along the section).

.. code-block:: python

netParams.connParams['PYR->PYR'] = {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be useful to include: synMech: ['AMPA'] and sec: ['soma'] ? or you think more confusing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, maybe similar example code blocks for the more complex rules in this subsection might be useful?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, 'synMech': 'AMPA' is definitely needed here (missed to add it), but I wouldn't include sec, to not inflate the example..

'preConds': {'pop': 'src'}, 'postConds': {'pop': 'dst'},
'synsPerConn': 2,
'weight': [0.1, 0.2], # individual weights for each synapse
'delay': 0.1, # single delay for all synapses
'loc': [0.5, 1.0] # individual locations for each synapse
}
# This will create 2 synapses: one with weight 0.1, delay 0.1, and loc 0.5
# and another with weight 0.2, delay 0.1, and loc 1.0.

When ``synsPerConn`` > 1 and a *single* section is specified, all synapses will be created there, and the locations of synapses can be specified as a list in ``loc`` (one per synapse, e.g., if ``synsPerConn`` = 3: ``[0.4, 0.5, 0.7]``).
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"all synapses will be created within that section, and their locations can be specified as a list in loc"

Perhaps also useful to make this and the next paragraph a subheading/subcategory of the above; eg bolding the conditions and using an indented bullet point **

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


If a *list of sections* is specified (either explicitly or as a key from `secLists`), synapses will be distributed uniformly along the specified section(s), taking into account the length of each section. (E.g., if you provide 'soma' and 'dend' with lengths 10 and 20 respectively, and ``synsPerConn`` = 5, the following sections and locations will be as shown in the figure below). Providing location explicitly is not possible in this case.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here: can use consistent language and indented bullet point:
** When synsPerConn > 1 and a list of sections section is specified

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"E.g., if you specify 'soma' and 'dend' with lengths of 10 and 20, respectively, and set synsPerConn = 5, the resulting distribution of synapses will be in the sections and locations illustrated in the figure below."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. image:: figs/multisyn_0.png
:width: 50%
:align: center

The behavior above is due to the ``distributeSynsUniformly`` flag, which is True by default. Alternatively, if it is set to False (and ``connRandomSecFromList`` is True, which is default value), a random section will be picked from the sections list for each synapse. The ``loc`` value should also be a list, and the values will be picked from it randomly and independently from section choice. If the length of sections or locations list is greater or equal to ``synsPerConn``, random choice is guaranteed to be without replacement. If ``loc`` is omitted, the value for each synapse is randomly sampled from uniform[0, 1].
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave a line / vertical spacing below the fig.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph is complicated and a bit overwhelming. We suddenly introduce 2 new flags (distributeSynsUniformly and connRandomSecFromList), and it is unclear what happens in each of the 4 possible combinations (T/T, T/F, F/T, F/F) since we only mention 2 of them. Perhaps describing this more systematically might be useful, maybe using subheadings: "If distributeSynsUniformly=True, connRandomSecFromList=False: ... " etc

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

", which is the default value)"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, I forgot to mention here that these two flags are described in simConfig's section.. Do you think it's better to link there from here, or just repeat their meaning here?
Also, I didn't mention that now their default values (from cfg) can be overridden in connParams

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding the combinations, in fact, there are not that many of them. First the distributeSynsUniformly is taken into account, and only if it False, connRandomSecFromList comes into play.
Perhaps I should indicate this explicitly?


To enforce a deterministic way of picking ``sec`` and ``loc``, set ``connRandomSecFromList`` to False (N-th synapse then gets N-th section and N-th loc from their respective lists, or if ``loc`` is a single value, it is used for all synapses). Make sure that lists of sections and locations both have the length equal to ``synsPerConn``.

If ``synsPerConn`` == 1, and a list of sections is specified, synapses (one per presynaptic cell) will be placed in sections randomly selected from the list. If ``loc`` is also a list, locations will be picked randomly (note that the random section and location will go hand in hand, i.e., the same random index is used for both).
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to clarify here that this requires connRandomSecFromList=True? what happens if its False?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's the other way round:) Here I describe the case with connRandomSecFromList is False.
The case with True is mentioned in the paragraph above the two highlighted, it says:

The behavior above is due to the distributeSynsUniformly flag, which is True by default. Alternatively, if it is set to False (and connRandomSecFromList is True, which is the default value), a random section will be picked from the sections list for each synapse. [.....]

[these two paragraphs]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it worth adding one more level of bullet-pointed list hierarchy?

  • synsPerConn > 1
    • single sec
    • list of secs
      • distribSynsUniformly = True (default)
      • distribSynsUniformly = False
        • connRandomSec = True (default)
        • connRandomSec = False
  • synsPerConn == 1

And this all falls under bigger bullet-point "Setting synsPerConn >= 1 with synMech as a single value"


* Setting ``synMech`` as a list
If ``synMech`` is a list, then for each mechanism in the list, a synapse will be created. The weights, delays, and locs can be specified as lists of the same length as ``synMech``, or a single value can be used for all.

.. code-block:: python

netParams.connParams['PYR->PYR'] = {
'preConds': {'pop': 'src'}, 'postConds': {'pop': 'dst'},
'synMech': ['AMPA', 'GABA'],
'weight': [0.1, 0.2], # individual weights for each synapse
'delay': 0.1, # single delay for all synapses
}
# This will create 2 synapses: one with AMPA synMech and weight 0.1
# and another with GABA synMech and weight 0.2. Both will have the same delay of 0.1.


However, for the sections, no such one-to-one correspondence to ``synMech`` elements applies. Instead, contents of ``secs`` are repeated for each synapse.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Instead, the synapses or (sets of synapses) are replicated at each section specified in secs"

Is this the case? ie. what will happen if in the example codeblock above we add ["soma", "dend"] ? Will it create a total of 4 synapses? Maybe such an example would be useful?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an error in my description. I meant "Instead, contents of secs are repeated for each synMech", not "per each synapse".

There is already an example below. Yes, if you have ['AMPA', 'GABA'] and ["soma", "dend"], it will create 2 ampa synapses and 2 gaba synapses, with same locs for corresponding ampa and gaba synapses

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh btw, it will be the case is synsPerConn is 2 (will also fix it in the example below). Because if synsPerConn is 1, it will just pick soma for AMPA and soma for GABA, and ignore dend in both cases.


.. code-block:: python

netParams.connParams['PYR->PYR'] = {
'preConds': {'pop': 'src'}, 'postConds': {'pop': 'dst'},
'synMech': ['AMPA', 'GABA'],
'sec': ['soma', 'dend']
}
# Both AMPA and GABA synapses will span 'soma' and 'dend' sections

If you want to have different sections, separate connectivity rules (``connParams`` entries) should be defined for each synaptic mechanism.

* Both ``synMech`` as a list and ``synsPerConn`` > 1
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency: "Setting both synsPerConn > 1 and synMech as a list"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

If you have both a N-element list of ``synMechs`` and ``synsPerConn`` > 1, weights and delays can still be specified as a single value for all synapses, as a list of length N (each value corresponding to ``synMech`` list index), or a 2D list with outer dimension N (corresponding to ``synMechs``) and inner dimension corresponding to ``synsPerConn``.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a 2D list with outer dimension N corresponding to synMechs and inner dimension corresponding to synsPerConn.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. image:: figs/multisyn_1.png
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe place the top yellow box synapse also on the right hand side of the dendrite, to avoid confusion

:width: 35%
:align: right

.. code-block:: python

netParams.connParams['PYR->PYR'] = {
'preConds': {'pop': 'src'}, 'postConds': {'pop': 'dst'},
'synMech': ['AMPA', 'GABA'],
'sec': 'dend',
'synsPerConn': [2, 1],
'loc': [[0.5, 0.75], [0.3]],
'distributeSynsUniformly': False,
}

Note that ``synsPerConn`` itself can be a list, so that each ``synMech`` can correspond to a distinct number of synapses.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that, as shown in the example, ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


* Usage with **'connList'**
If, in addition, you are using **'connList'**-based connectivity (explicit list of connections between individual pre- and post-synaptic cells), then the weights, delays, locs, secs are lists that can be described by up to 3-dimensional lists. The outer dimension now corresponds to the length of ``connList`` (i.e., number of cell-to-cell connections). Then the same logic as above applies to each element of this outer list.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If, in addition, you want to use 'connList'-based connectivity (explicit list of connections between individual pre- and post-synaptic cells), then weights, delays, locs, and secs can be described as lists of up to three dimensions. The outermost dimension will now correspond to the length of connList (i.e., the number of cell-to-cell connections). The same logic described above will apply to each element of this outer list."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. code-block:: python

netParams.connParams['PYR->PYR'] = {
'preConds': {'pop': 'src'}, 'postConds': {'pop': 'dst'},
'connList': [[0,0], [1,0]],
'synMech': ['AMPA', 'GABA'],
'synsPerConn': 3,
'weight': [[[1, 2, 3], [4, 5, 6]], # first conn: AMPA, GABA, 3 synsPerConn each
[[7, 8, 9], [10, 11, 12]]], # second conn: AMPA, GABA (...)

'delay': [[0.1, 0.2], # first conn: AMPA, GABA, same for all syns in synsPerConn
[0.3, 0.4]], # second conn: AMPA, GABA (...)
}

.. _function_string:

Expand Down Expand Up @@ -2268,7 +2363,7 @@ connections from the sensory to the motor population.
inspyred allows customization of the various components of the
evolutionary algorithm, including:

-  a selector that determines which sets of parameter values become
- a selector that determines which sets of parameter values become
parents and thus which parameter values will be used to form the next
generation in the evolutionary iteration,
- a variator that determines how each current iteration of parameter
Expand Down
Loading
Loading