Skip to content

Commit ecae057

Browse files
cbrnragramfort
andauthored
Minor improvements for metadata tutorial (mne-tools#11555)
Co-authored-by: Alexandre Gramfort <[email protected]>
1 parent 29e99c8 commit ecae057

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

tutorials/epochs/40_autogenerate_metadata.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
2222
This tutorial is loosely divided into two parts:
2323
24-
1. We will first focus on producing ERP time-locked to the **visual
24+
1. We will first focus on producing ERPs time-locked to the **visual
2525
stimulation**, conditional on response correctness and response time in
2626
order to familiarize ourselves with the `~mne.epochs.make_metadata`
2727
function.
@@ -114,19 +114,19 @@
114114
# a value of ``NaN``, simply indicating that no event latency could be
115115
# extracted.
116116
#
117-
# Now, there's a problem here. We want investigate the visual ERPs only,
117+
# Now, there's a problem here. We want to investigate the visual ERPs
118118
# conditional on responses. But the metadata that was just created contains
119119
# one row for **every** event, including responses. While we **could** create
120120
# epochs for all events, allowing us to pass those metadata, and later subset
121-
# the created events, there's a more elegant way to handle things:
121+
# the created events, there's a more elegant way to handle this:
122122
# `~mne.epochs.make_metadata` has a ``row_events`` parameter that
123123
# allows us to specify for which events to create metadata **rows**, while
124124
# still creating **columns for all events** in the ``event_id`` dictionary.
125125
#
126126
# Because the metadata, then, only pertains to a subset of our original events,
127127
# it's important to keep the returned ``events`` and ``event_id`` around for
128-
# later use when we're actually going to create our epochs, to ensure that
129-
# metadata, events, and event descriptions stay in sync.
128+
# later use when we actually create our epochs, to ensure that metadata,
129+
# events, and event descriptions stay in sync.
130130

131131
row_events = ['stimulus/compatible/target_left',
132132
'stimulus/compatible/target_right',
@@ -157,12 +157,13 @@
157157
# parameter. For example, in the case of the HEDs ``response/left`` and
158158
# ``response/right``, we could pass ``keep_first='response'`` to generate a new
159159
# column, ``response``, containing the latency of the respective event. This
160-
# value pertains only the first (or, in this specific example: the only)
160+
# value represents the first (or, in this specific example: the only)
161161
# response, regardless of side (left or right). To indicate **which** event
162-
# type (here: response side) was matched, a second column is added:
163-
# ``first_response``. The values in this column are the event types without the
164-
# string used for matching, as it is already encoded as the column name, i.e.
165-
# in our example, we expect it to only contain ``'left'`` and ``'right'``.
162+
# type (here: response side) was matched, a second column named
163+
# ``first_response`` is added. The values in this column are the event types
164+
# without the string used for matching, as it is already encoded as the column
165+
# name, i.e. in our example, we expect it to only contain ``'left'`` and
166+
# ``'right'``.
166167

167168
keep_first = 'response'
168169
metadata, events, event_id = mne.epochs.make_metadata(
@@ -182,10 +183,10 @@
182183
# We're facing a similar issue with the stimulus events, and now there are not
183184
# only two, but **four** different types: ``stimulus/compatible/target_left``,
184185
# ``stimulus/compatible/target_right``, ``stimulus/incompatible/target_left``,
185-
# and ``stimulus/incompatible/target_right``. Even more, because in the present
186-
# paradigm stimuli were presented in rapid succession, sometimes multiple
187-
# stimulus events occurred within the 1.5 second time window we're using to
188-
# generate our metadata. See for example:
186+
# and ``stimulus/incompatible/target_right``. What's more, because in the
187+
# present paradigm stimuli were presented in rapid succession, sometimes
188+
# multiple stimulus events occurred within the 1.5 second time window we used
189+
# to generate our metadata. See for example:
189190

190191
metadata.loc[metadata['stimulus/compatible/target_left'].notna() &
191192
metadata['stimulus/compatible/target_right'].notna(),
@@ -246,12 +247,12 @@
246247
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
247248
#
248249
# It's finally time to create our epochs! We set the metadata directly on
249-
# instantiation via the ``metadata`` parameter. Also it is important to
250+
# instantiation via the ``metadata`` parameter. Also, it is important to
250251
# remember to pass ``events`` and ``event_id`` as returned from
251252
# `~mne.epochs.make_metadata`, as we only created metadata for a subset of
252253
# our original events by passing ``row_events``. Otherwise, the length
253-
# of the metadata and the number of epochs would not match and MNE-Python
254-
# would raise an error.
254+
# of the metadata and the number of epochs would not match, which would raise
255+
# an error.
255256

256257
epochs_tmin, epochs_tmax = -0.1, 0.4 # epochs range: [-0.1, 0.4] s
257258
reject = {'eeg': 250e-6} # exclude epochs with strong artifacts
@@ -260,21 +261,19 @@
260261
reject=reject, preload=True)
261262

262263
# %%
263-
# Lastly, let's visualize the ERPs evoked by the visual stimulation, once for
264-
# all trials with correct responses, and once for all trials with correct
264+
# Lastly, let's visualize the ERPs associated with the visual stimulation, once
265+
# for all trials with correct responses, and once for all trials with correct
265266
# responses and a response time greater than 0.5 seconds
266267
# (i.e., slow responses).
267268
vis_erp = epochs['response_correct'].average()
268269
vis_erp_slow = epochs['(not response_correct) & '
269270
'(response > 0.3)'].average()
270271

271-
fig, ax = plt.subplots(2, figsize=(6, 6))
272+
fig, ax = plt.subplots(2, figsize=(6, 6), layout='constrained')
272273
vis_erp.plot(gfp=True, spatial_colors=True, axes=ax[0])
273274
vis_erp_slow.plot(gfp=True, spatial_colors=True, axes=ax[1])
274275
ax[0].set_title('Visual ERPs – All Correct Responses')
275276
ax[1].set_title('Visual ERPs – Slow Correct Responses')
276-
fig.tight_layout()
277-
fig
278277

279278
# %%
280279
# Aside from the fact that the data for the (much fewer) slow responses looks
@@ -298,11 +297,11 @@
298297
#
299298
# We only wish to consider the **last** stimulus and response in each time
300299
# window: Remember that we're dealing with rapid stimulus presentations in
301-
# this paradigm; taking the last response – at time point zero and the last
302-
# stimulus the one closest to the responseensures we actually create
300+
# this paradigm; taking the last response (at time point zero) and the last
301+
# stimulus (the one closest to the response) ensures that we actually create
303302
# the right stimulus-response pairings. We can achieve this by passing the
304-
# ``keep_last`` parameter, which works exactly like ``keep_first`` we got to
305-
# know above, only that it keeps the **last** occurrences of the specified
303+
# ``keep_last`` parameter, which works exactly like ``keep_first`` we used
304+
# previously, only that it keeps the **last** occurrences of the specified
306305
# events and stores them in columns whose names start with ``last_``.
307306

308307
metadata_tmin, metadata_tmax = -1.5, 0
@@ -316,7 +315,7 @@
316315
keep_last=keep_last)
317316

318317
# %%
319-
# Exactly like in the previous example, create new columns ``stimulus_side``
318+
# Exactly like in the previous example, we create new columns ``stimulus_side``
320319
# and ``response_correct``.
321320

322321
# left-side stimulation
@@ -339,8 +338,8 @@
339338

340339
# %%
341340
# Now it's already time to epoch the data! When deciding upon the epochs
342-
# duration for this specific analysis, we need to ensure we see quite a bit of
343-
# signal from before and after the motor response. We also must be aware of
341+
# duration for this specific analysis, we need to ensure to include quite a bit
342+
# of signal from before and after the motor response. We also must be aware of
344343
# the fact that motor-/muscle-related signals will most likely be present
345344
# **before** the response button trigger pulse appears in our data, so the time
346345
# period close to the response event should not be used for baseline

0 commit comments

Comments
 (0)