Introducing heterogeneous modeling with MultiModel: rise and shine 🌈. Zap your models with the new Stimulus⚡️ class
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 oneneurolib
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 theALNModel
. 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 theALNModel
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
.
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)
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);
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.