Skip to content

Conversation

@HanjiaJiang
Copy link
Contributor

We implemented a new connection rule, currently named "pairwise_bernoulli_astro", for the creation of tripartite connectivity in neuron-astrocyte networks. This rule is adapted from the "symmetric_pairwise_bernoulli" rule.

The conn_spec parameter "p" determines connection probability between neurons as in the "symmetric_pairwise_bernoulli" rule. Three new conn_spec parameters are added: "p_syn_astro" determines the probability of each created neuron-neuron connection to be paired with an astrocyte, "max_astro_per_target" determines the maximal number of astrocytes each target neuron can be connected with, and "astro_pool_by_index" determines whether the astrocytes are paired with neurons randomly or by index.

The new syn_spec parameters "weight_pre2post", "weight_pre2astro", "weight_astro2post", "delay_pre2post", "delay_pre2astro", and "delay_astro2post" determine the weights and delays in the tripartite connectivity.

The naming and design in this new rule are still open to discussion and changes. We will continue to improve the code during the review process.

HanjiaJiang and others added 20 commits September 15, 2023 14:28
- move the code that determines the starting astrocyte in the deterministic case to a separate function
- update some comments
…irwise_bernoulli_astro.py

- add a test for max_astro_per_target
- improve comments
- add astrocyte_small_network.py and astrocyte_brunel.py to example list
- add a subsection for astrocyte in the documentation "Connection Rules"
…nel.py

Co-Authored-By: Jugoslava Acimovic <jugoslava.acimovic@tuni.fi>
Co-Authored-By: Tiina Manninen <tiina.manninen@tuni.fi>
Co-Authored-By: Jonas Stapmanns <j.stapmanns@fz-juelich.de>
Co-Authored-By: Sacha van Albada <s.van.albada@fz-juelich.de>
@heplesser heplesser requested a review from jhnnsnk September 24, 2023 05:19
@heplesser heplesser marked this pull request as draft September 24, 2023 05:19
@heplesser heplesser self-assigned this Sep 24, 2023
@heplesser heplesser added T: Enhancement New functionality, model or documentation S: High Should be handled next I: No breaking change Previously written code will work as before, no one should note anything changing (aside the fix) labels Sep 24, 2023
@heplesser
Copy link
Contributor

This PR introduces a new concept, tripartite connectivity between neurons and astrocytes. The user interface included in the PR is specific to astrocytes. I propose a more generic API for tripartite connections and would like to discuss details here.

The connection rule

In tripartite connections, we have

  • source population
  • target population
  • third-party population

Exactly how these are connected is up to the specific connection rule. The first connection rule propose here, works as follows:

  1. Perform a Bernoulli experiment to test whether to connect a source-target pair. Connect that pair.
  2. If a source-target pair is to be connected, perform a second Bernoulli experiment to determine if the third party shall be connected.
  3. If the third party is to be connected
    1. Build a pool of third-party nodes specific to the target node chosen in step 1 (see below for details).
    2. Randomly select a single third-party node from the pool.
    3. Connect the source node from step 1 to the chosen third-party node and the third-party node to the target node.

The pool from 3.i has the following properties:

  1. For a given target, the same pool is used for all sources connected to this target.
  2. The user can specify a pool size, between one and the size of the third-party population.
  3. If no pool size is given, the entire third-party population is the pool.
  4. Nodes of the third-party population can either be chosen at random (selection with uniform probability without replacement) or based on a regular pattern (for pool size n, assign the first n astrocytes as pool to target 1, the next n to target 2, etc).

I suggest to call this rule tripartite_bernoulli_with_pool.

API proposal

I suggest here two variants. One maintains the single Connect() function, the other introduces a new function.
Before discussing the Connect() function, let's look at synapse specifications first.

Synapse specifications

For tripartite connections, we need synapse specifications for

  1. the source -> target connection (the primary connection)
  2. the source -> third-party connection (third-party input connection)
  3. the third-party -> target connection (third-party output connection)

This is easily achieved by allowing a dictionary of connection specifications, which in turn can contain anything that is legal as a syn_spec argument otherwise and defaults to static synapse with weight and delay 1 if missing:

    syn_spec={
        "primary": {"model": "tsodyks_synapse", "weight": 1.0, "delay": 1.0},
        "third_in": {"model": "tsodyks_synapse", "weight": 1.0, "delay": 1.0},
        "third_out": {"model": "sic_connection", "weight": 1.0, "delay": 1.0},
    }

Extending Connect() semantics

Change from

nest.Connect(pre, post, conn_spec=None, syn_spec=None, return_synapsecollection=False)

to

nest.Connect(pre, post, conn_spec=None, syn_spec=None, return_synapsecollection=False, third=None)

allowing calls of the form

nest.Connect(pre_neurons, post_neurons, <conn spec>, <syn spec>, third=astrocytes)
nest.Connect(pre_neurons, post_neurons, third=astrocytes, conn_spec={...}, syn_spec_={...})

The downside of this approach is that one either needs to place the third-party argument last or use argument names for conn_spec and syn_spec.

Introducing a new connection function

nest.TripartiteConnect(pre, post, third, conn_spec=None, syn_spec=None, return_synapsecollection=False)

called as

nest.TripartiteConnect(pre_neurons, post_neurons, astrocytes, <conn spec>, <syn spec>)

This is slightly more expressive and would use the same syn_spec semantics as the extended Connect() alternative, see below. Alternatively, one could have all syn specs explicit:

nest.TripartiteConnect(pre, post, third, conn_spec=None, *, 
  syn_spec_primary=None, syn_spec_third_in=None, syn_spec_third_out=None, return_synapsecollection=False)

called as

nest.TripartiteConnect(pre_neurons, post_neurons, astrocytes, <conn spec>, 
   syn_spec_primary={...}, syn_spec_third_in={...}, syn_spec_third_out={...})

In this case, I believe one should force named keyword args for the syn specs to avoid confusion.

Connection specifications

These will depend on the connection rule for details. For the tripartite_bernoulli_with_pool, I suggest

    conn_spec={
        "rule": "tripartite_bernoulli_with_pool",
        "p_primary": 0.2,
        "p_cond_third": 0.5,
        "pool_size": 3,
        "random_pool": False,
    }

where p_primary is the probability to create a source-target connection and p_cond_third the probability to create a third-party connection if a primary connection is created.

Open questions

  1. If we all Connect() twice on the same target and third party populations, do we required the same random pools or may the pools be different from call to call?
  2. Shall we restrict index-based pooling to cases where third-party, target and pool size are commensurable? If we do not restrict like this, how do we handle nodes that do not fit?

Copy link
Contributor

@heplesser heplesser left a comment

Choose a reason for hiding this comment

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

@HanjiaJiang This looks very good. I just have two suggestions for the documentation, especially the figure.

Copy link
Contributor

@heplesser heplesser left a comment

Choose a reason for hiding this comment

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

@HanjiaJiang Thanks a lot, approved!

@heplesser
Copy link
Contributor

@jhnnsnk Ping :).

Copy link
Contributor

@jessica-mitchell jessica-mitchell left a comment

Choose a reason for hiding this comment

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

@HanjiaJiang Looks good, I found a couple of very minor typos, but I approve. Thanks for all your work. As for the image I think it's fine using the image directive. The figure directive is useful for referencing, but I don't think it's necessary.

Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
@HanjiaJiang
Copy link
Contributor Author

Thanks a lot. I have merged Jessica's corrections. I will wait and see if Johanna has any suggestions/corrections. :)

Copy link
Contributor

@jhnnsnk jhnnsnk left a comment

Choose a reason for hiding this comment

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

Thanks a lot for all this great work!
I left suggestions and change requests in the code.
In particular I tried to align the notation to the connectivity concepts study and #2992 .

@heplesser heplesser requested a review from jhnnsnk November 23, 2023 14:34
@heplesser
Copy link
Contributor

@jhnnsnk Could you re-review?

Copy link
Contributor

@jhnnsnk jhnnsnk left a comment

Choose a reason for hiding this comment

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

Thanks a lot @HanjiaJiang for having addressed all my comments. Looks very good! 👍

@heplesser heplesser merged commit a5f0d71 into nest:master Nov 23, 2023
@HanjiaJiang
Copy link
Contributor Author

Thank you guys! Finally concluded this PR :).
Many thanks to Jessica for her review as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I: No breaking change Previously written code will work as before, no one should note anything changing (aside the fix) S: High Should be handled next T: Enhancement New functionality, model or documentation

Projects

Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants