In this demo we show how to use the TVB DSL in order to automatically generate model code and execute it in the TVB simulator. The TVB DSL is an extension of LEMS and is defined using XML syntax.
import tvb.dsl.LEMS2python as templating
from IPython.display import Code
In this demo we will define a new model to TVB called the Montbrio model. This model is based on: Montbrió, Ernest, Diego Pazó, and Alex Roxin. "Macroscopic description for networks of spiking neurons." Physical Review X 5.2 (2015): 021028. This is a model with two state variables derived from on a network of all-to-all coupled heterogeneous quadratic integrate-and-fire QIF neurons, which is exact in the thermodynamic limit.
In the example of the montbrio model, we can see different elements which allow us to express the model variables and dynamics. We can now take a deeper look into each component.
Lets start with the definition of the model name and description documentation. This is done by defining a new Component using the keyword ComponentType.
<ComponentType name="MontbrioT" description="This is a demo describing the Montbrio model" value="">
Constants for a model are defined using the Constant keyword, such as in:
<Constant name="I" domain="lo=-10.0, hi=10.0, step=0.01" default="0.0" description="A constant"/>
The domain specification allows TVB to check if a value set by the user to this constant before simulation is within the expected range or not.
The model dynamics are specified in a special section tagged as Dynamics. Inside this section we can define state variables using the keyword StateVariable, other variables derived from combinations of constants and state variables using the keyword DerivedVariable, and the time derivatives of the model with the keyword TimeDerivative. Some examples are illustrated below:
<StateVariable name="r" default="0., 2.0" boundaries="0.0, inf"/>
The default term defines the range within which the default value of this state variable can be defined before the simulation takes place. The boundaries specify hard limits for the values of these variables in order to avoid numerical overflows.
<DerivedVariable name="Coupling_global" expression="alpha * coupling[0]"/>
The expression term in the DerivedVariable is used to state the combination of constanst / variables that define the new variable. The experssion is expected to be in Python-like syntax
<TimeDerivative name="dx" expression="Delta / pi + 2 * V * r - k * r**2 + Gamma * r / pi"/>
As in the derived variable, the expression term in the TimeDerivative is used to mathematically describe the update in the state variable that will be performed on each integration step and should be expressed in Python-like syntax.
It is important to highlight that the order of the definition of the state variables must be preserved for the definition of their time derivatives in order for the DSL to correctly match them.
Finally, outside of the dynamics section we can use the keyword Exposure to define the state variables we are interested on monitoring from the outside e.g.:
<Exposure name="r" choices="r, V" default="r, V" description="The quantities of interest for monitoring for the Infinite QIF 2D oscillator."/>
We can now take a look at the whole XML code which is used to define the Montbrio model. The model in this example has been defined using the DSL in the file /tvb/dsl/NeuroML/XMLmodels.
import tvb.dsl
import os
xmlfile = open(os.path.join(os.path.dirname(tvb.dsl.__file__), "NeuroML/XMLmodels/montbriot.xml"),"r")
model = xmlfile.read()
display(Code(model, language='xml'))
xmlfile.close()
We will call the templating function in order to automatically generate the model code. This will be directly moved to the right path in the tvb library so it will be recognized by the simulator when we call it later. Please notice that the name provided to the templating function needs to be the exact name given to the model ComponentType in xml.
templating.regTVB_templating('MontbrioT')
from tvb.simulator.lab import *
import numpy as np
from tvb.simulator import models
sim_length = 400
white_matter = connectivity.Connectivity.from_file(source_file="connectivity_68.zip")
white_matter.configure()
white_matter_coupling = coupling.Linear(a=np.array([1.0]))
SC = white_matter.weights
integrator = integrators.EulerDeterministic(dt=0.1)
populations = models.MontbrioT()
populations.configure()
monitorsen = (monitors.TemporalAverage(period=10.0))
sim = simulator.Simulator(model=populations,
connectivity=white_matter,
coupling=white_matter_coupling,
integrator=integrator,
monitors=[monitorsen])
sim.configure()
(_,tavg_data) = sim.run(simulation_length=sim_length)[0]
print(tavg_data)
import tvb.simulator.models
models.MontbrioT
from tvb.simulator.models.montbriot import MontbrioT