Skip to content

Introducing heterogeneous modeling with MultiModel: rise and shine 🌈. Zap your models with the new Stimulus⚡️ class

Compare
Choose a tag to compare
@caglorithm caglorithm released this 05 Aug 10:46
· 91 commits to master since this release
696b099

In this new release, we introduce the MultiModel🌈 framework and the Stimulus⚡️ class.

MultiModel 🌈

  • MultiModel is a framework for constructing neural mass models and combining them with others into one neurolib model (example notebooks here, here, and here)

Here is a short summary of how MultiModel works:

Models in MultiModel are implemented and simulated in an hierarchical fashion with three different levels: The first level is a neural mass, representing a single homogeneous neural population which is defined by a set of differential equations. An example of this is the excitatory subpopulation of the ALNModel. The second level is a node, defined as a collection of neural masses. The subpopulations of a node are coupled via a local connectivity matrix. An example of this is a single node of the ALNModel with excitatory and inhibitory subpopulations. Finally, in the third level, a collection of nodes is represented as a network, in which nodes are connected according to a global connectivity matrix. In the case of a brain network, these are the fiber count and fiber length matrices from DTI. The dynamical equations within all levels in the hierarchy can be implemented by the user, and, more importantly, once defined, can be reused and "plugged together" with other models. MultiModel integrates the equations of each neural mass on the lowest level, and handles the synchronization and coupling of all relevant variables according to the predefined local and global coupling schemes on all higher levels.

Building MultiModel brings us closer to simulating truly heterogeneous neural mass models. What it allows us to do right now is, for example, to simulate a thalamocortical network, with the thalamus being represented by a ThalamicMassModel and the cortex by the ALNModel.
image

A block of pseudocode says more than a picture:

from neurolib.models.multimodel import MultiModel
		
from neurolib.models.multimodel.builder.base.network import Network	
from neurolib.models.multimodel.builder.aln import ALNNode
from neurolib.models.multimodel.builder.thalamus import ThalamicNode

class ThalamoCorticalNetwork(Network):
    def __init__(self):
    	cortex = ALNNode()
    	thalamus = ThalamicNode()
    	connectivity = np.array([0, 1], [1, 0])
    	super().__init__([aln_node, thalamus], connectivity)
    def _sync(self):
    	""" define which variables to couple """
    
model = MultiModel(ThalamoCorticalNetwork())

As you can see, here we have created a new model called ThalamoCorticalNetwork that consists of an ALNNode and a ThalamicNode. We have coupled them according to connectivity. In the real world, we would also have to define the _sync method, that tells neurolib which variables to couple to which, across models. We refer to the example notebooks for more details on how to implement a full model.

Our vision for this framework is adding more specialized models for different brain areas with the ultimate goal of heterogeneous whole-brain modeling, such as combining a cortical model with models of thalamic or hippocampal neural populations. This will enable us to model different brain rhythms generated in specialized neural circuits and study their whole-brain interactions.

Stimulus ⚡️

  • The Stimulus⚡️ class allows you to easily construct external stimuli that you can apply to neural mass models (example notebook here)

Stimuli are created by calling the appropriate classes that we've implemented:

# let's create some basic inputs
ou = stim.OrnsteinUhlenbeckProcess(mu=0.1, sigma=0.04, tau=2.0, n=2)
sq = stim.SquareInput(amplitude=0.2, frequency=1.7, n=2)
sin = stim.SinusoidalInput(amplitude=0.7, frequency=1.0, n=2)

image

You can now use the operators + and & to sum up stimuli and concatenate them. By combining different stimuli, this allows you to build a wide range of different stimuli. Here is an example of concatenation:

# same lengths - use &
conc = ou & sq & sin
plt.plot(conc.as_array(duration, dt).T);

image

Coupling a stimulus to a model couldn't be easier:

model.params["ext_exc_current"] = stimulus.to_model(model)

Special thanks for this release goes to @jajcayn who has been working hard to make this happen. We also want to thank all users who open Issues to report bugs, ask us questions, and let us learn more how neurolib is used in practice. Please feel free to contact us with your ideas and thoughts, we appreciate it a lot to know that there are researchers using neurolib out there.