.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "tutorials/tutorial_reconvolution_events.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_tutorials_tutorial_reconvolution_events.py: Reconvolution events ==================== This tutorial shows the basic building block of the reconvolution approach (see [1]_ and [2]_) that is implemented in the PyntBCI library for analysing code-modulated responses. This tutorial generates an arbitrary code (here an m-sequence) and shows different kinds of event definitions. References ---------- .. [1] Thielen, J., van den Broek, P., Farquhar, J., & Desain, P. (2015). Broad-Band visually evoked potentials: re(con)volution in brain-computer interfacing. PLOS ONE, 10(7), e0133797. DOI: https://doi.org/10.1371/journal.pone.0133797 .. [2] Thielen, J., Marsman, P., Farquhar, J., & Desain, P. (2021). From full calibration to zero training for a code-modulated visual evoked potentials for brain–computer interface. Journal of Neural Engineering, 18(5), 056007. DOI: https://doi.org/10.1088/1741-2552/abecef .. GENERATED FROM PYTHON SOURCE LINES 18-27 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import seaborn import pyntbci seaborn.set_context("paper", font_scale=1.5) .. GENERATED FROM PYTHON SOURCE LINES 28-32 The stimulus -------- PyntBCI contains a `stimulus` module with several functions that create various well-known noise-codes. Here we generate an m-sequence. .. GENERATED FROM PYTHON SOURCE LINES 32-51 .. code-block:: Python # Generate an m-sequence V = pyntbci.stimulus.make_m_sequence() n_classes, n_samples = V.shape print("V shape: ", V.shape, "(classes, samples)") # Visualize stimuli fr = 60 # the monitor refresh rate in Hz Vup = V.repeat(20, axis=1) # upsample to better visualize the sharp edges plt.figure(figsize=(15, 3)) plt.plot(np.arange(Vup.shape[1]) / (20 * fr), 2 * np.arange(n_classes) + Vup.T) for i in range(1 + int(V.shape[1])): plt.axvline(i / fr, c="k", alpha=0.1) plt.yticks(2 * np.arange(n_classes), np.arange(n_classes)) plt.xlabel("time [s]") plt.ylabel("code") plt.title("Code time-series") plt.tight_layout() .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_001.png :alt: Code time-series :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none V shape: (1, 63) (classes, samples) .. GENERATED FROM PYTHON SOURCE LINES 52-60 The event matrix ---------------- In reconvolution, sequences are decomposed into individual events. Reconvolution then learns a separate evoked response for each of these events. The event definition can be manually set. An event that is commonly used is the `dur` (duration) event, which defines an event for each run-length of ones in a sequence. There are many other potential events that can be used, such as `id` (identity), `on`, `off`, `onoff` (on and off), `re` (rising edge), `fe` (falling edge), and `refe` (rising and falling edge, contrast). Here, we show what these decompositions look like in more detail. .. GENERATED FROM PYTHON SOURCE LINES 60-79 .. code-block:: Python events = pyntbci.utilities.EVENTS # the event definitions i_class = 0 # the class to visualize for event in events: print(event) # Create event matrix E, events = pyntbci.utilities.event_matrix(V, event=event, onset_event=True) print("\tE shape:", E.shape, "(classes x events x samples)") print("\tEvents:", ", ".join([str(event) for event in events])) # Visualize event time-series fig, ax = plt.subplots(1, 1, figsize=(15, 3)) pyntbci.plotting.eventplot(V[i_class, :], E[i_class, :, :], fs=fr, ax=ax, events=events) ax.set_title(f"Event time-series {event} (code {i_class})") plt.tight_layout() # plt.show() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_002.png :alt: Event time-series id (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_002.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_003.png :alt: Event time-series on (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_003.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_004.png :alt: Event time-series off (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_004.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_005.png :alt: Event time-series onoff (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_005.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_006.png :alt: Event time-series dur (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_006.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_007.png :alt: Event time-series re (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_007.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_008.png :alt: Event time-series fe (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_008.png :class: sphx-glr-multi-img * .. image-sg:: /tutorials/images/sphx_glr_tutorial_reconvolution_events_009.png :alt: Event time-series refe (code 0) :srcset: /tutorials/images/sphx_glr_tutorial_reconvolution_events_009.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none id E shape: (1, 2, 63) (classes x events x samples) Events: id, onset on E shape: (1, 2, 63) (classes x events x samples) Events: on, onset off E shape: (1, 2, 63) (classes x events x samples) Events: off, onset onoff E shape: (1, 3, 63) (classes x events x samples) Events: on, off, onset dur E shape: (1, 6, 63) (classes x events x samples) Events: 1, 2, 3, 4, 6, onset re E shape: (1, 2, 63) (classes x events x samples) Events: rise, onset fe E shape: (1, 2, 63) (classes x events x samples) Events: fall, onset refe E shape: (1, 3, 63) (classes x events x samples) Events: rise, fall, onset .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.925 seconds) .. _sphx_glr_download_tutorials_tutorial_reconvolution_events.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: tutorial_reconvolution_events.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: tutorial_reconvolution_events.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: tutorial_reconvolution_events.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_