You are on page 1of 60

THEVIRTUALBRAIN.

(TVB)
A Whole‐Brain modelling tool

Gustavo Patow
IMAE ‐ UdG

1
Working with TVB

• Two possible ways… GUI vs Scripting

2
Resources on TVB

• All official TVB tutorials:
https://docs.thevirtualbrain.org/tutorials/Tutorials.html

• All official TVB demos:
https://docs.thevirtualbrain.org/demos/Demos.html

3
User guides

• GUI Guide:
https://docs.thevirtualbrain.org/manuals/UserGuide/UserGuide‐UI.html

• Console Guide
https://docs.thevirtualbrain.org/manuals/UserGuide/UserGuide‐Shell.html

4
Data

• We are going to use tvb‐data which can be downloaded from:
https://zenodo.org/record/4263723#.Y‐klrXbMKMp

• Other than that, please follow this link:
https://www.thevirtualbrain.org/tvb/zwei/client‐
area/public?&_ga=2.181154980.207792273.1676199337‐
1370691999.1675639510#
to download the ModelingEpilepsy.zip project.

5
Getting Started

6
Region simulation

• Here we present the basic anatomy of a region simulation 
using TVB's scripting interface
• Can be used from an Jupyer notebook
• Or into a Python terminal/script 
• When the code is evaluated, TVB's internal logging mechanisms 
produce output describing when/where/what of the operation, this is 
the text you'll see below the code cells.

7
Region simulation

Import the modules we'll need for a simulation:
1. Model: a set of differential equations describing the local 
neuronal dynamics
2. Connectivity, represents the large scale structural connectivity of 
the brain, ie white‐matter tracts
3. Coupling: a function used to join the local Model dynamics at 
distinct locations over the connections described in Connectivity
4. Integrator: the integration scheme for the differential equations
5. Monitors: attached to a simulation, they act to record the output 
from the Simulator
6. Simulator object: used to run a simulation
8
Setup

• Let's begin by importing the modules we'll need:

from tvb.simulator.lab import *

• Note: you’ll get a lengthy log… 

9
Model

• Let's start with the Model for the local dynamics we wish to use
• There are a number of predefined Models available in TVB
• As an example here we'll use a generic 2 dimensional oscillator 
with its default parameters:

oscilator = models.Generic2dOscillator()

10
Connectivity

• TVB's defaults: calling Connectivity without arguments leads to 
a default connectivity dataset being loaded
• We can then alter the speed of signal propagation through the 
network to 4.0 ms−1:

white_matter = connectivity.Connectivity.from_file()
white_matter.speed = numpy.array([4.0])
11
Coupling function

• Requires some knowledge of the properties of both the Model 
being used and the structure through which it is connected
• For our present purposes, we know that 
• for the default parameters of TVB's Generic2dOscillator connected 
through TVB's default connectivity matrix
• a linear function with a slope of 0.0154 is reasonable
• NOTE: here we are setting a non‐default parameter via an 
argument to the definition of our coupling.

white_matter_coupling = coupling.Linear(a=numpy.array([0.0154]))
12
Integrator

• We need to select an integration scheme
• While TVB supports a number of schemes, for most purposes you 
should use either HeunDeterministic or HeunStochastic.
• We'll use HeunDeterministic with a step size of 2−6
• Use a step size that is small enough for the integration to be 
numerically stable

heunint = integrators.HeunDeterministic(dt=2**-6)
13
Monitors
• TVB doesn't support interpolation of the time‐series it 
produces
• which means that the period given to a monitor must be an integral 
multiple of the dt selected for the integration scheme
• Here we'll select two simple monitors just to show the idea
• There are Monitors which apply a biophysical measurement process to 
the simulated neural activity, such as EEG, MEG, etc
• The Raw Monitor takes no arguments and returns all the simulated 
data
• The TemporalAverage Monitor averages over a time window of length 
period returning one time point every period ms
• By default, only returns those state‐variables flagged in the Models definition as 
variables_of_interest
• Pass them (in order) to the Simulator
14
Monitors

#Initialise some Monitors with period in physical time


mon_raw = monitors.Raw()
mon_tavg = monitors.TemporalAverage(period=2**-2)

#Bundle them
what_to_watch = (mon_raw, mon_tavg)

15
Simulator

• Bring all these components together into a Simulator object
• Then need to run the configure method
• Just acts to calculate information necessary for the simulation that 
draws on specific combinations of the components

#Initialise a Simulator -- Model, Connectivity, Integrator, and Monitors.


sim = simulator.Simulator(model = oscilator, connectivity = white_matter,
coupling = white_matter_coupling,
integrator = heunint, monitors = what_to_watch)
sim.configure()

16
Running a simulation
#Perform the simulation
raw_data = []

The simulator is an  raw_time = []
tavg_data = []
iterable object
tavg_time = []
• All we need to do 
is iterate for some  for raw, tavg in sim(simulation_length=2**10):
length, which we  if not raw is None:
provide in ms, and  raw_time.append(raw[0])
raw_data.append(raw[1])
collect the output
if not tavg is None:
tavg_time.append(tavg[0])
tavg_data.append(tavg[1])
17
Taking a look at the results

• The data returned by the simulator is in the form of a list of 
arrays
• For most subsequent purposes it is much easier to deal with the data 
if it exists as a single contiguous array

#Make the lists numpy.arrays for easier use.


RAW = numpy.array(raw_data)
TAVG = numpy.array(tavg_data)

18
Taking a look at the results
#Plot raw time series
Importing  figure(1) plot(raw_time, RAW[:, 0, :, 0])
tvb.simulator.lab title("Raw -- State variable 0")
above also 
imported the  #Plot temporally averaged time series
plotting  figure(2)
functionality of  plot(tavg_time, TAVG[:, 0, :, 0])
matplotlib.pyplot title("Temporal average")

#Show them
show()
19
Results Transient 

20
Modeling Epilepsi

21
Mathematical aside: Bifurcation
• Definition: The existence of a qualitative change in the 
dynamics of a nonlinear system due to a change in the 
parameters of that system
• Example:   𝑢 𝑥

𝑢 2 𝑢 0 𝑢 1
𝑑𝑥/𝑑𝑡 𝑑𝑥/𝑑𝑡 𝑑𝑥/𝑑𝑡

𝑥 𝑥 𝑥
Modeling Epilepsy

• we can reproduce clinically relevant scenarios such as the 
propagation of an epileptic seizure in the human brain, 
electrical stimulation of a brain region that can trigger a 
seizure, or surgical resection of brain regions

23
Current Modeling Capabilities
Electroencephalogram 
(EEG) ’Normal’  Seizure  ‘Normal’ 
Activity Activity activity

“On The Nature of Seizure Dynamics,” V.K. Jirsa et. al, 2014
The Epileptor

• It is the current state of the art in seizure 
dynamics 
• There are many ways a seizure can occur
• E.g., lack of sleep and flashing lights
• This model proposes to look only at the aspects of 
seizures that are invariant
• The dynamics underlying a particular type of seizure that 
is common across all instances of its occurrence 

25
The Epileptor
[Jirsa, V. K., Stacey, W. C., Quilichini, P. P., Ivanov, A. I., & Bernard, 
C. (2014). On the nature of seizure dynamics. In Brain (Vol. 137, 
Issue 8, pp. 2210–2230). Oxford University Press (OUP)] 
https://doi.org/10.1093/brain/awu133

26
The Epileptor

• Jirsa et al. proposed a model that dictates the dynamics of just one 
channel at a time, where a channel can be modeled with just five 
state variables, and therefore, five differential equations
• Two of the variables are fast state variables, which reflect the high frequency 
signals
• Two are slow variables, reflecting the higher amplitude signals
• One connects the two characteristic behaviors. 
• One of the most important aspects of the epileptor model is its 
inclusion of a parameter that when changed, introduces two key 
bifurcations in the system. 
• One bifurcation, or a qualitative change in the behavior in the system, 
models the onset of the seizure
• The other models its offset.  
27
The Epileptor
Electroencephalogram  Epileptor
u u’ u’’
(EEG) ’Normal’  Seizure  ‘Normal’  ‐ Fast (2 var)
Activity Activity activity ‐ Slow 
ẋ1 =
(2 var)
f(x, u) = 
‐ Linking 
(1 var)

Epileptor Simulation

u u’ u’’

x1 + x2

fast var Time (seconds)
“On The Nature of Seizure Dynamics,” V.K. Jirsa et. al, 2014 slow var
The Epileptor
‐ Fast (2 var) 
u u’ u’’ Epileptor, of single 
‐ Slow  (2 var)
channel ẋ1 =
‐ Linking 
f(x, u) = 
(1 var)

x1 + x2
Where:
𝑥 3𝑥 , 𝑥 0
1 𝑦 𝑓 𝑥 ,𝑥 𝑧 𝑰𝟏 𝑓 𝑥 ,𝑥
𝑥 .6 𝑧 4 𝑥 , 𝑥 0
2 𝑦 5𝑥 𝑦
3 𝑦 𝑥 𝑥 .002𝑔 𝑥 .3 𝑧 3.5 𝑰𝟐 0, 𝑥 .25
𝑓 𝑥 ,𝑥
6 𝑥 .25 , 𝑥 .25
4 𝑦 𝑓 𝑥 ,𝑥
5 4 𝑥 𝑥 𝑧 𝑔 𝑥 𝑒 𝑥 𝑡 𝑑𝜏
The Epileptor u x0 = ‐1.6
y0 = 1
I_1= .45
I_2= 3.1 
t0 = 2857 
t1 = 1 
t2 = 10 
u u’ u” gamma = 0.01 

u’ x0 = ‐1.6 I_1= 50
y0 = 100              I_2= 3.1 
t0 = 2857 
t1 = 1 
t2 = 10 
gamma = 0.01 

u” x0 = ‐1.6 I_1= .45
y0 = 1 I_2= 3.1 
t0 = 2857 
t1 = 1 
t2 = 10 
x1 + x2 vs. time gamma = 0.01 
Exploring the Epileptor model

from tvb.simulator.plot.phase_plane_interactive import PhasePlaneInteractive

# Create an Epileptor model instance


epileptor = models.Epileptor()

# Open the phase plane tool with the epileptor model


ppi_fig = PhasePlaneInteractive(model=epileptor)
ppi_fig.show()

31
Exploring the Epileptor model

32
Exploring the Epileptor model
• Looking at the phase space, we have here the first 
population (variables y0 in abscissa and y1 in ordinate)
• The leftmost intersection of the nullcline defines a stable 
fixed point, representing the interictal state
• The rightmost intersection is the center of a limit cycle, 
being the ictal state
• Both states are separated by a separatrix, as you can see by 
drawing different trajectories in this phase space
• We can look at other variables in the phase space, such 
as the second population y3 & y4, responsible for the 
interictal spikes in the Epileptor model
33
Region based simulation of a temporal 
lobe seizure
• We will model a patient with temporal lobe epilepsy (TLE)
• We will set different values of epileptogenicity x0 parameter in the Epileptor according to 
the region positions, thereby introducing heterogeneities in the network parameters
• We set the right limbic areas (right hippocampus (rHC, region 47), parahippocampus
(rPHC, region 62) and amygdala (rAMYG, region 40)) as epileptic zones
• We also add two lesser epileptogenic regions: the superior temporal cortex (rTCI, region 
69) and the ventral temporal cortex (rTCV, region 72).
• In other words, we assign to all the nodes the Dynamics for which x0 has a value 
of value of −2.2
• We apply the epileptogenic configura on (−1.6) to the right limbic areas.
• Additionally, we chose which kind of coupling we want (between the fast 
variable (Kvf), the spike‐and‐wave events (Kf), or the slow permittive coupling 
(Ks))
• Here we use Kf and Ks of them.
• Finally, we also slow‐down the dynamics of the Epileptor by choosing r=0.00015

34
Region based simulation of a temporal 
lobe seizure
• Setting the basic parameters
• All others take default values…

epileptors = models.Epileptor( Ks=numpy.array([-0.2]),


Kf=numpy.array([0.1]),
r=numpy.array([0.00015]))
epileptors.x0 = np.ones((76))*-2.4
epileptors.x0[[62, 47, 40]] = np.ones((3))*-1.6
epileptors.x0[[69, 72]] = np.ones((2))*-1.8
35
Region based simulation of a temporal 
lobe seizure
• Load the connectivity matrix and choose the coupling function

con = connectivity.Connectivity.from_file()

• We choose a difference coupling function

coupl = coupling.Difference(a=numpy.array([1.]))

36
Region based simulation of a temporal 
lobe seizure
• We use a stochastic integration scheme; the noise is only added 
on the two variables of the second population (y3, y4)

hiss = noise.Additive(nsig = numpy.array([0., 0., 0., 0.0003, 0.0003, 0.]))


heunint = integrators.HeunStochastic(dt=0.05, noise=hiss)

37
Region based simulation of a temporal 
lobe seizure
• We will now set the monitors
• a temporal average
• an EEG
• a SEEG
• For this we need to load a region mapping, the projection 
matrices and the sensors
• In the Epileptor model, the LFP is defined as ‐y0+y3
• We want the projection matrices to be applied on the LFP, so we use 
this as a 'pre' expression
• We also keep track of the slow permittivity variable y2.

38
Region based simulation of a temporal 
lobe seizure
# load the default region mapping
rm = region_mapping.RegionMapping.from_file()

#Initialise some Monitors with period in physical time


mon_tavg = monitors.TemporalAverage(period=1.)
mon_EEG = monitors.EEG.from_file()
mon_EEG.region_mapping=rm mon_EEG.period=1.
mon_SEEG = monitors.iEEG.from_file()
mon_SEEG.region_mapping=rm mon_SEEG.period=1.

#Bundle them
what_to_watch = (mon_tavg, mon_EEG, mon_SEEG) 39
Region based simulation of a temporal 
lobe seizure
• we iniatilise and configure our Simulator object

#Initialise a Simulator
# -- Model, Connectivity, Integrator, and Monitors.
sim = simulator.Simulator(model=epileptors, connectivity=con,
coupling=coupl,
integrator=heunint, monitors=what_to_watch)
sim.configure()

40
Region based simulation of a temporal 
lobe seizure
• We perform the simulation of 10.000 ms

(ttavg, tavg), (teeg, eeg), (tseeg, seeg) =


sim.run(simulation_length=10000)

41
Region based simulation of a temporal 
lobe seizure
# Normalize the time series to have nice plots
tavg /= (np.max(tavg,0) - np.min(tavg,0 ))
• And plot 
the results! eeg /= (np.max(eeg,0) - np.min(eeg,0 ))
eeg -= np.mean(eeg, 0)
seeg /= (np.max(seeg,0) - np.min(seeg, 0))
seeg -= np.mean(seeg, 0)

#Plot raw time series


figure(figsize=(10,10))
plot(ttavg[:], tavg[:, 0, :, 0] + np.r_[:76], 'r')
title("Epileptors time series")
show() 42
Region based simulation of a temporal 
lobe seizure

43
Region based simulation of a temporal 
lobe seizure

figure(figsize=(10,10))
plot(teeg[:], 10*eeg[:, 0, :, 0] + np.r_[:65])
yticks(np.r_[:65], mon_EEG.sensors.labels)
title("EEG")

44
Region based simulation of a temporal 
lobe seizure

45
Region based simulation of a temporal 
lobe seizure

figure(figsize=(10,10))
plot(tseeg[:], seeg[:, 0, :75, 0] + np.r_[:75])
yticks(np.r_[:75], mon_SEEG.sensors.labels)
title("SEEG")

46
Region based simulation of a temporal 
lobe seizure SEEG

47
Modeling surgical resection

• Surgical resection is used for around 20% of epileptic 
patient whose seizures are drug‐resistant
• We will simulate the hypothetic case of a surgical resection 
of the amygdala and the hippocampus, but leaving the 
parahippocampal cortex

48
Modeling surgical resection

• We set all the connections to the right amygdala (40) and right 
hippocampus (47) to 0 in the connectivity matrix
• The resection of the EZ is not complete, will it be enough to prevent 
seizures?

con = connectivity.Connectivity.from_file()
con.weights[[ 47, 40]] = 0.
con.weights[:, [47, 40]] = 0.

49
Modeling surgical resection
# we plot only the right hemisphere
# the lines and columns set to 0 are clearly visible
figure()
imshow(con.weights[38:, 38:],
interpolation='nearest',
cmap='binary')
colorbar()
show()

50
Modeling surgical resection

• The rest of the model is set as before, but we just use a time 
average monitor:

coupl = coupling.Difference(a=numpy.array([1.]))
hiss = noise.Additive(nsig = numpy.array([0., 0., 0., 0.0003, 0.0003, 0.]))
heunint = integrators.HeunStochastic(dt=0.05, noise=hiss)
mon_tavg = monitors.TemporalAverage(period=1.)

51
Modeling surgical resection
• Now, relaunch our first simulation, taking care of replacing the 
dynamic of the EZ by a stable node, as if the region was resected
epileptors = models.Epileptor( Ks=numpy.array([-0.2]),
Kf=numpy.array([0.1]),
r=numpy.array([0.00015]))
epileptors.x0 = np.ones((76))*-2.4
epileptors.x0[[69, 72]] = np.ones((2))*-1.8
sim = simulator.Simulator(model=epileptors, connectivity=con,
coupling=coupl,
integrator=heunint, monitors=(mon_tavg,))
sim.configure();
(ttavg, tavg), = sim.run(simulation_length=10000) 52
Modeling surgical resection
• As you can see, no seizure is triggered anymore

# normalize the time series


tavg /= (np.max(tavg,0) - np.min(tavg,0 ))

figure(figsize=(10,10))
plot(ttavg[:], tavg[:, 0, :, 0] + np.r_[:76], 'r')
title("Epileptors time series")
show()

53
Triggering a seizure by stimulation

• We are now going to model an electric stimulation and trigger a 
seizure
• We set the whole brain to non‐epileptogenic but close to the 
threshold

epileptors = models.Epileptor(Ks=numpy.array([-0.2]), Kf=numpy.array([0.1]), r=numpy.array([0.00035]))


epileptors.x0 = np.ones((76))*-2.1
con = connectivity.Connectivity.from_file()
coupl = coupling.Difference(a=numpy.array([0.]))
heunint = integrators.HeunDeterministic(dt=0.05)
mon_tavg = monitors.TemporalAverage(period=1.)

54
Triggering a seizure by stimulation
# Weighting for regions to receive stimuli.
weighting = numpy.zeros((76))
weighting[[69, 72]] = numpy.array([2.])

eqn_t = equations.PulseTrain()
eqn_t.parameters["T"] = 10000.0
eqn_t.parameters["onset"] = 2500.0
eqn_t.parameters["tau"] = 50.0
eqn_t.parameters["amp"] = 20.0
stimulus = patterns.StimuliRegion(temporal = eqn_t, connectivity = con, weight = weighting)

#Configure space and time


stimulus.configure_space()
stimulus.configure_time(numpy.arange(0., 3000., heunint.dt))
#And take a look
plot_pattern(stimulus)
55
show()
Triggering a seizure by stimulation

56
Triggering a seizure by stimulation
#Bundle them
what_to_watch = (mon_tavg, )
#Initialise Simulator
# -- Model, Connectivity, Integrator, Monitors, and stimulus.
sim = simulator.Simulator(model=epileptors,
connectivity=con,
coupling=coupl,
integrator=heunint,
monitors=what_to_watch,
stimulus=stimulus)
sim.configure()
57
Triggering a seizure by stimulation
(t, tavg), = sim.run(simulation_length=10000)

# Normalize the time series to have nice plots


tavg /= (np.max(tavg,0) - np.min(tavg,0 ))
#Plot raw time series
figure(figsize=(10,10))
plot(t[:], tavg[:, 0, :, 0] + np.r_[:76], 'r')
title("Epileptors time series")

#Show them
show()
58
More information

• https://docs.thevirtualbrain.org/tutorials/Tutorials.html
• https://docs.thevirtualbrain.org/demos/Demos.html

• https://docs.thevirtualbrain.org/manuals/UserGuide/UserGuid
e‐UI.html
• https://docs.thevirtualbrain.org/manuals/UserGuide/UserGuid
e‐Shell.html

• https://docs.thevirtualbrain.org/doc_site/top_developers.html
59
THEVIRTUALBRAIN. (TVB)
A Whole‐Brain modelling tool

Thanks!

60

You might also like