Skip to content

Commit effe5c7

Browse files
committed
example for varying b and simulating
1 parent 9ea0e3d commit effe5c7

File tree

1 file changed

+160
-1
lines changed

1 file changed

+160
-1
lines changed

examples/eg__vary_b_param.py

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,160 @@
1-
#init
1+
"""
2+
.. _ex-momi2023-part2:
3+
4+
========================================================
5+
Replicating Momi et al. (2023): TMS-evoked Responses
6+
========================================================
7+
8+
This script replicates the findings of the paper :footcite:`MomiEtAl2023`:
9+
10+
Momi, D., Wang, Z., Griffiths, J.D. (2023).
11+
"TMS-evoked responses are driven by recurrent large-scale network dynamics."
12+
# eLife, [doi: 10.7554/eLife.83232](https://elifesciences.org/articles/83232)
13+
14+
This code loads up a previously-fit whobpyt model, varies a specific model parameter (the inhibitory time constant; b), and simulates TEPs to visualize what effect this model parameter has on the output.
15+
16+
17+
"""
18+
19+
# sphinx_gallery_thumbnail_number = 1
20+
#
21+
# %%
22+
# Setup
23+
# --------------------------------------------------
24+
# Importage:
25+
26+
# os stuff
27+
import os
28+
import sys
29+
sys.path.append('..')
30+
31+
32+
# whobpyt stuff
33+
import whobpyt
34+
from whobpyt.datatypes import Parameter as par, Timeseries
35+
from whobpyt.models.jansen_rit import JansenRitModel,JansenRitParams
36+
from whobpyt.run import ModelFitting
37+
from whobpyt.optimization.custom_cost_JR import CostsJR
38+
39+
# python stuff
40+
import numpy as np
41+
import pandas as pd
42+
import scipy.io
43+
import gdown
44+
import pickle
45+
import warnings
46+
warnings.filterwarnings('ignore')
47+
48+
#neuroimaging packages
49+
import mne
50+
51+
# viz stuff
52+
import matplotlib.pyplot as plt
53+
54+
# %%
55+
# Download and load necessary data for the example
56+
download_data = True
57+
url = 'https://drive.google.com/drive/folders/1dpyyfJl9wjTrWVo5lqOmB8HRhD3irjNj?usp=drive_link'
58+
if download_data: gdown.download_folder(url, quiet=True)
59+
data_dir = os.path.abspath('eg__replicate_Momi2023_data')
60+
61+
# # %%
62+
# # load in a previously completed model fitting results object
63+
# full_run_fname = os.path.join(data_dir, 'Subject_1_low_voltage_fittingresults_stim_exp.pkl')
64+
# F = pickle.load(open(full_run_fname, 'rb'))
65+
# F.evaluate(u = u, empRec = data_mean, TPperWindow = batch_size, base_window_num = 20)
66+
67+
# define relevant variables for whobpyt fititng/simuations
68+
69+
# %%
70+
# Load EEG data from a file
71+
file_name = os.path.join(data_dir, 'Subject_1_low_voltage.fif')
72+
epoched = mne.read_epochs(file_name, verbose=False);
73+
evoked = epoched.average()
74+
75+
76+
# %%
77+
# define options for JR model
78+
eeg_data = evoked.data.copy()
79+
time_start = np.where(evoked.times==-0.1)[0][0]
80+
time_end = np.where(evoked.times==0.3)[0][0]
81+
eeg_data = eeg_data[:,time_start:time_end]/np.abs(eeg_data).max()*4
82+
node_size = F.model.node_size
83+
output_size = eeg_data.shape[0]
84+
batch_size = 20
85+
step_size = 0.0001
86+
num_epochs = 20 #2 # num_epochs = 20
87+
tr = 0.001
88+
state_size = 6
89+
base_batch_num = 20
90+
time_dim = 400
91+
state_size = 6
92+
base_batch_num = 20
93+
hidden_size = int(tr/step_size)
94+
95+
96+
# %%
97+
# prepare data structure of the model
98+
data_mean = Timeseries(eeg_data, num_epochs, batch_size)
99+
100+
# stimulation info
101+
u = np.zeros((node_size,hidden_size,time_dim))
102+
u[:,:,80:120]= 1000
103+
104+
105+
# %%
106+
# Visualizng the original fit
107+
ts_args = dict(xlim=[-0.1,0.3])
108+
ch, peak_locs1 = evoked.get_peak(ch_type='eeg', tmin=-0.05, tmax=0.01)
109+
ch, peak_locs2 = evoked.get_peak(ch_type='eeg', tmin=0.01, tmax=0.02)
110+
ch, peak_locs3 = evoked.get_peak(ch_type='eeg', tmin=0.03, tmax=0.05)
111+
ch, peak_locs4 = evoked.get_peak(ch_type='eeg', tmin=0.07, tmax=0.15)
112+
ch, peak_locs5 = evoked.get_peak(ch_type='eeg', tmin=0.15, tmax=0.20)
113+
times = [peak_locs1, peak_locs2, peak_locs3, peak_locs4, peak_locs5]
114+
115+
simulated_EEG_st = evoked.copy()
116+
simulated_EEG_st.data[:,time_start:time_end] = F.lastRec['eeg'].npTS()
117+
times = [peak_locs1, peak_locs2, peak_locs3, peak_locs4, peak_locs5]
118+
simulated_joint_st = simulated_EEG_st.plot_joint(ts_args=ts_args, times=times)
119+
120+
# %%
121+
# now we want to vary paramters and simulate again.
122+
123+
# looking at original value of b
124+
print(F.model.params.b.val)
125+
126+
# defining a range of b to vary and simulate
127+
b_range = np.linspace(45, 55, 4)
128+
129+
130+
# %%
131+
# Defining a range for the b paramter to explore
132+
b_range = np.linspace(45, 55, 5)
133+
# testing all ranges:
134+
sims_dict = {}
135+
for n, new_b in enumerate(b_range):
136+
# changing parameter in model
137+
F.model.params.b = par(new_b, new_b, 1, True)
138+
139+
# evaluate the model
140+
F.evaluate(u = u, empRec = data_mean, TPperWindow = batch_size, base_window_num = 20)
141+
142+
# plotting and saving new simulations
143+
simulated_EEG_st.data[:,time_start:time_end] = F.lastRec['eeg'].npTS()
144+
simulated_joint_st = simulated_EEG_st.plot_joint(ts_args=ts_args, times=times, title=f'b param = {new_b}')
145+
sims_dict[str(new_b)] = simulated_EEG_st.copy().crop(tmin=0, tmax=0.2)
146+
147+
# %%
148+
# comparing conditions
149+
fig, ax = plt.subplots(figsize=(12,4))
150+
mne.viz.plot_compare_evokeds(sims_dict, picks='eeg', combine='gfp', axes=ax, cmap='viridis',);
151+
fig.show()
152+
153+
# %%
154+
# Results Description
155+
# ---------------------------------------------------
156+
#
157+
#
158+
# Here we replicate the results of Momi et al. 2023 (Fig. 5D). As the inhibitory synaptic time constant b increases,
159+
# we observe an increase in the amplitude of the first, early, and local TEP components; and a decrease of the second,
160+
# late, and global TEP components.

0 commit comments

Comments
 (0)