Skip to content

Commit 5567f63

Browse files
authored
Merge pull request #9 from gallantlab/doc/improveflow
DOC improve flow with ngrok and cortex, add example delays
2 parents ed289f7 + 8d829d6 commit 5567f63

5 files changed

Lines changed: 85 additions & 25 deletions

File tree

tutorials/movies_3T/00_setup_colab.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
skip it if you run the tutorials on your machine.
99
"""
1010
# sphinx_gallery_thumbnail_path = "static/colab.png"
11-
#
1211
###############################################################################
1312
# Change runtime to use a GPU
1413
# ---------------------------

tutorials/movies_3T/01_plot_explainable_variance.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
references [1]_ [2]_ [3]_.
3838
"""
3939
# sphinx_gallery_thumbnail_number = 1
40-
41-
4240
###############################################################################
4341
# Path of the data directory
4442
# --------------------------
@@ -172,19 +170,11 @@
172170
#
173171
# The second mapper we provide maps the voxel data to a Freesurfer
174172
# average surface ("fsaverage"), that can be used in ``pycortex``.
175-
# First, let's download the "fsaverage" surface.
176-
177-
import cortex
178-
179-
surface = "fsaverage"
180-
181-
if not hasattr(cortex.db, surface):
182-
cortex.utils.download_subject(subject_id=surface)
183-
184-
###############################################################################
173+
#
185174
# If you are running the notebook on Colab, you might need to update the
186175
# pycortex filestore as following:
187176

177+
import cortex
188178
try:
189179
import google.colab # noqa
190180
in_colab = True
@@ -201,11 +191,20 @@
201191
cortex.quickflat.utils.db = cortex.database.db
202192
cortex.quickflat.composite.db = cortex.database.db
203193

194+
###############################################################################
195+
# Now, let's download the "fsaverage" surface.
196+
197+
surface = "fsaverage"
198+
199+
if not hasattr(cortex.db, surface):
200+
cortex.utils.download_subject(subject_id=surface)
201+
204202
###############################################################################
205203
# Then, we load the "fsaverage" mapper. The mapper is a matrix of shape
206204
# (n_vertices, n_voxels), which maps each voxel to some vertices in the
207205
# fsaverage surface. It is stored as a sparse CSR matrix. The mapper is applied
208206
# with a dot product ``@`` (equivalent to ``np.dot``).
207+
209208
from voxelwise_tutorials.io import load_hdf5_sparse_array
210209
voxel_to_fsaverage = load_hdf5_sparse_array(mapper_file,
211210
key='voxel_to_fsaverage')
@@ -220,14 +219,9 @@
220219
vertex = cortex.Vertex(ev_projected, surface, vmin=0, vmax=0.7, cmap='viridis')
221220

222221
###############################################################################
223-
# To start an interactive 3D viewer in the browser, use the ``webshow``
224-
# function.
225-
226-
if False:
227-
cortex.webshow(vertex, open_browser=False, port=8050)
228-
229-
###############################################################################
230-
# If you are running the notebook on Colab, you need to tunnel the pycortex
222+
# To start an interactive 3D viewer in the browser, we can use the ``webshow``
223+
# function in pycortex.
224+
# If you are running the notebook on Colab, you first need to tunnel the pycortex
231225
# application out of Colab. To do so, use the following cell to start a tunnel
232226
# with ``ngrok`` and to get an address where the pycortex viewer will be made
233227
# accessible.
@@ -246,6 +240,17 @@
246240
f"{result}\n"
247241
"and not the one proposed by pycortex ('Open viewer: ...')\n")
248242

243+
244+
###############################################################################
245+
# Now you can start an interactive 3D viewer by changing ``run_webshow`` to
246+
# ``True`` and running the following cell. If you are using Colab, remember to
247+
# use the address returned by ngrok in the cell above rather than the address
248+
# returned by this cell.
249+
250+
run_webshow = False
251+
if run_webshow:
252+
cortex.webshow(vertex, open_browser=False, port=8050)
253+
249254
###############################################################################
250255
# Alternatively, to plot a flatmap in a ``matplotlib`` figure, use the
251256
# `quickshow` function.
@@ -255,7 +260,6 @@
255260

256261
from cortex.testing_utils import has_installed
257262

258-
259263
fig = cortex.quickshow(vertex, colorbar_location='right',
260264
with_rois=has_installed("inkscape"))
261265
plt.show()

tutorials/movies_3T/03_plot_hemodynamic_response.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,64 @@
141141
scores = backend.to_numpy(scores)
142142
print("(n_voxels,) =", scores.shape)
143143

144+
###############################################################################
145+
# Intermission: understanding delays
146+
# ----------------------------------
147+
#
148+
# To have an intuitive understanding of what we accomplish by delaying the
149+
# features before model fitting, we will simulate one voxel and a single
150+
# feature. We will then create a ``Delayer`` object (which was used in the
151+
# previous pipeline) and visualize its effect on our single feature. Let's
152+
# start by simulating the data.
153+
154+
# number of total trs
155+
n_trs = 50
156+
# repetition time for the simulated data
157+
TR = 2.0
158+
rng = np.random.RandomState(42)
159+
y = rng.randn(n_trs)
160+
x = np.zeros(n_trs)
161+
# add some arbitrary value to our feature
162+
x[15:20] = .5
163+
x += rng.randn(n_trs) * 0.1 # add some noise
164+
165+
# create a delayer object and delay the features
166+
delayer = Delayer(delays=[0, 1, 2, 3, 4])
167+
x_delayed = delayer.fit_transform(x[:, None])
168+
169+
###############################################################################
170+
# In the next cell we are plotting six lines. The subplot at the top shows the
171+
# simulated BOLD response, while the other subplots show the simulated feature
172+
# at different delays. The effect of the delayer is clear: it creates multiple
173+
# copies of the original feature shifted forward in time by how many samples we
174+
# requested (in this case, from 0 to 4 samples, which correspond to 0, 2, 4, 6,
175+
# and 8 s in time with a 2 s TR).
176+
#
177+
# When these delayed features are used to fit a voxelwise encoding model, the
178+
# brain response :math:`y` at time :math:`t` is simultaneously modeled by the
179+
# feature :math:`x` at times :math:`t-0, t-2, t-4, t-6, t-8`. In the remaining
180+
# of this example we will see that this method improves model prediction accuracy
181+
# and it allows to account for the underlying shape of the hemodynamic response
182+
# function.
183+
184+
import matplotlib.pyplot as plt
185+
fig, axs = plt.subplots(6, 1, figsize=(8, 6.5), constrained_layout=True,
186+
sharex=True)
187+
times = np.arange(n_trs)*TR
188+
189+
axs[0].plot(times, y, color="r")
190+
axs[0].set_title("BOLD response")
191+
for i, (ax, xx) in enumerate(zip(axs.flat[1:], x_delayed.T)):
192+
ax.plot(times, xx, color='k')
193+
ax.set_title("$x(t - {0:.0f})$ (feature delayed by {1} sample{2})".format(
194+
i*TR, i, "" if i == 1 else "s"))
195+
for ax in axs.flat:
196+
ax.axvline(40, color='gray')
197+
ax.set_yticks([])
198+
_ = axs[-1].set_xlabel("Time [s]")
199+
plt.show()
200+
201+
144202
###############################################################################
145203
# Compare with a model without delays
146204
# -----------------------------------
@@ -171,7 +229,6 @@
171229
# diagonal corresponds to identical prediction accuracy for both models. A
172230
# distibution deviating from the diagonal means that one model has better
173231
# prediction accuracy than the other.
174-
import matplotlib.pyplot as plt
175232
from voxelwise_tutorials.viz import plot_hist2d
176233

177234
ax = plot_hist2d(scores_no_delay, scores)

tutorials/movies_3T/04_plot_motion_energy_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
###############################################################################
148148
# Plot the model performances
149149
# ---------------------------
150-
# The performances are computed using the math:`R^2` scores.
150+
# The performances are computed using the :math:`R^2` scores.
151151

152152
import matplotlib.pyplot as plt
153153
from voxelwise_tutorials.viz import plot_flatmap_from_mapper

tutorials/movies_3T/06_extract_motion_energy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
# Load the stimuli images
3838
# -----------------------
3939
#
40-
# Here the data is not loaded in memory, we only take a peak at the data shape.
40+
# Here the data is not loaded in memory, we only take a peek at the data shape.
4141

4242
import h5py
4343

0 commit comments

Comments
 (0)