diff --git a/doc/references.bib b/doc/references.bib index 6bc3dd91521..502c1704217 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -1,4 +1,7 @@ % Encoding: UTF-8 +% +% If available, include a DOI (preferred) *or* a URL for a given reference, but +# not both, as the DOI turns into a link which is redundant with the URL. % MNE-C reference @article{GramfortEtAl2014, @@ -518,7 +521,6 @@ @article{GramfortEtAl2010 title = {Graph-Based Variability Estimation in Single-Trial Event-Related Neural Responses}, journal = {{IEEE} Transactions on Biomedical Engineering}, doi = {10.1109/tbme.2009.2037139}, - url = {https://doi.org/10.1109%2Ftbme.2009.2037139}, year = {2010}, publisher = {Institute of Electrical and Electronics Engineers ({IEEE})}, volume = {57}, @@ -1306,7 +1308,6 @@ @article{Pascual-Marqui2002 @article{Pascual-Marqui2011, title = {Assessing interactions in the brain with exact low-resolution electromagnetic tomography}, volume = {369}, - url = {https://royalsocietypublishing.org/doi/full/10.1098/rsta.2011.0081}, doi = {10.1098/rsta.2011.0081}, number = {1952}, journal = {Philosophical Transactions of the Royal Society A: Mathematical, Physical and Engineering Sciences}, @@ -1980,7 +1981,6 @@ @article{OReillyEtAl2021 title = {Structural templates for imaging {EEG} cortical sources in infants}, volume = {227}, issn = {1053-8119}, - url = {http://www.sciencedirect.com/science/article/pii/S1053811920311678}, doi = {10.1016/j.neuroimage.2020.117682}, urldate = {2021-01-12}, journal = {NeuroImage}, @@ -1994,7 +1994,6 @@ @article{RichardsEtAl2016 title = {A database of age-appropriate average {MRI} templates}, volume = {124}, issn = {1053-8119}, - url = {http://www.sciencedirect.com/science/article/pii/S1053811915003559}, doi = {10.1016/j.neuroimage.2015.04.055}, journal = {NeuroImage}, author = {Richards, John E. and Sanchez, Carmen and Phillips-Meek, Michelle and Xie, Wanze}, @@ -2054,16 +2053,15 @@ @Article{Kappenman2021 } @article{GenoveseEtAl2002, -title = {Thresholding of Statistical Maps in Functional Neuroimaging Using the False Discovery Rate}, -journal = {NeuroImage}, -volume = {15}, -number = {4}, -pages = {870-878}, -year = {2002}, -issn = {1053-8119}, -doi = {https://doi.org/10.1006/nimg.2001.1037}, -url = {https://www.sciencedirect.com/science/article/pii/S1053811901910377}, -author = {Christopher R. Genovese and Nicole A. Lazar and Thomas Nichols}, + title = {Thresholding of Statistical Maps in Functional Neuroimaging Using the False Discovery Rate}, + journal = {NeuroImage}, + volume = {15}, + number = {4}, + pages = {870-878}, + year = {2002}, + issn = {1053-8119}, + doi = {https://doi.org/10.1006/nimg.2001.1037}, + author = {Christopher R. Genovese and Nicole A. Lazar and Thomas Nichols}, } @article{YaoEtAl2019, @@ -2077,3 +2075,15 @@ @article{YaoEtAl2019 doi = {10.1007/s10548-019-00707-x}, publisher={Springer} } + +@article{PolonenkoMaddox2019, + title = {The {Parallel} {Auditory} {Brainstem} {Response}}, + volume = {23}, + issn = {2331-2165}, + doi = {10.1177/2331216519871395}, + language = {en}, + journal = {Trends in Hearing}, + author = {Polonenko, Melissa J. and Maddox, Ross K.}, + year = {2019}, + pages = {2331216519871395} +} diff --git a/examples/io/plot_read_xdf.py b/examples/io/plot_read_xdf.py new file mode 100644 index 00000000000..5b65eb99a5f --- /dev/null +++ b/examples/io/plot_read_xdf.py @@ -0,0 +1,42 @@ +""" +.. _ex-read-xdf: + +==================== +Reading XDF EEG data +==================== + +Here we read some sample XDF data. Although we do not analyze it here, this +recording is of a short parallel auditory response (pABR) experiment +:footcite:`PolonenkoMaddox2019` and was provided by the `Maddox Lab +`__. +""" +# Authors: Clemens Brunner +# Eric Larson +# +# License: BSD (3-clause) + +import os.path as op + +import pyxdf + +import mne +from mne.datasets import misc + +fname = op.join( + misc.data_path(), 'xdf', + 'sub-P001_ses-S004_task-Default_run-001_eeg_a2.xdf') +streams, header = pyxdf.load_xdf(fname) +data = streams[0]["time_series"].T +assert data.shape[0] == 5 # four raw EEG plus one stim channel +data[:4:2] -= data[1:4:2] # subtract (rereference) to get two bipolar EEG +data = data[::2] # subselect +data[:2] *= (1e-6 / 50 / 2) # uV -> V and preamp gain +sfreq = float(streams[0]["info"]["nominal_srate"][0]) +info = mne.create_info(3, sfreq, ["eeg", "eeg", "stim"]) +raw = mne.io.RawArray(data, info) +raw.plot(scalings=dict(eeg=100e-6), duration=1, start=12) + +############################################################################### +# References +# ---------- +# .. footbibliography:: diff --git a/mne/datasets/utils.py b/mne/datasets/utils.py index a40d64e5383..6df444191d2 100644 --- a/mne/datasets/utils.py +++ b/mne/datasets/utils.py @@ -254,7 +254,7 @@ def _data_path(path=None, force_update=False, update_path=True, download=True, path = _get_path(path, key, name) # To update the testing or misc dataset, push commits, then make a new # release on GitHub. Then update the "releases" variable: - releases = dict(testing='0.117', misc='0.8') + releases = dict(testing='0.117', misc='0.9') # And also update the "md5_hashes['testing']" variable below. # To update any other dataset, update the data archive itself (upload # an updated version) and update the md5 hash. @@ -345,7 +345,7 @@ def _data_path(path=None, force_update=False, update_path=True, download=True, bst_raw='fa2efaaec3f3d462b319bc24898f440c', bst_resting='70fc7bf9c3b97c4f2eab6260ee4a0430'), fake='3194e9f7b46039bb050a74f3e1ae9908', - misc='0f88194266121dd9409be94184231f25', + misc='f832ce9c4c27e83396cc977b293b0aa9', sample='12b75d1cb7df9dfb4ad73ed82f61094f', somato='32fd2f6c8c7eb0784a1de6435273c48b', spm='9f43f67150e3b694b523a21eb929ea75', diff --git a/requirements_doc.txt b/requirements_doc.txt index c2ca49b86f6..b119be1d666 100644 --- a/requirements_doc.txt +++ b/requirements_doc.txt @@ -8,3 +8,4 @@ neo seaborn sphinx_copybutton https://github.com/mne-tools/mne-bids/archive/main.zip +pyxdf diff --git a/tutorials/io/plot_20_reading_eeg_data.py b/tutorials/io/plot_20_reading_eeg_data.py index 5c84b8efcf5..f1b45565333 100644 --- a/tutorials/io/plot_20_reading_eeg_data.py +++ b/tutorials/io/plot_20_reading_eeg_data.py @@ -6,8 +6,8 @@ Importing data from EEG devices =============================== -MNE includes various functions and utilities for reading EEG -data and electrode locations. +MNE includes various functions and utilities for reading EEG data and electrode +locations. .. _import-bv: @@ -16,50 +16,51 @@ The BrainVision file format consists of three separate files: -1. A text header file (``.vhdr``) containing meta data +1. A text header file (``.vhdr``) containing meta data. 2. A text marker file (``.vmrk``) containing information about events in the - data -3. A binary data file (``.eeg``) containing the voltage values of the EEG + data. +3. A binary data file (``.eeg``) containing the voltage values of the EEG. -Both text files are based on the -`Microsoft Windows INI format `_ -consisting of: +Both text files are based on the `INI format `_ +consisting of -* sections marked as ``[square brackets]`` -* comments marked as ``; comment`` -* key-value pairs marked as ``key=value`` +* sections marked as ``[square brackets]``, +* comments marked as ``; comment``, +* and key-value pairs marked as ``key=value``. -A documentation for core BrainVision file format is provided by Brain Products. -You can view the specification hosted on the -`Brain Products website `_ +Brain Products provides documentation for their core BrainVision file format. +The format specification is hosted on the +`Brain Products website `_. -BrainVision EEG files can be read in using :func:`mne.io.read_raw_brainvision` -with the ``.vhdr`` header file as an input. +BrainVision EEG files can be read using :func:`mne.io.read_raw_brainvision`, +passing the ``.vhdr`` header file as the argument. .. warning:: Renaming BrainVision files can be problematic due to their - multifile structure. See this + multi-file structure. See this `example `_ - for an instruction. + for instructions. .. note:: For *writing* BrainVision files, you can use the Python package `pybv `_. + .. _import-edf: European data format (.edf) =========================== -EDF and EDF+ files can be read using :func:`mne.io.read_raw_edf`. - -`EDF (European Data Format) `_ and -`EDF+ `_ are 16-bit formats. +`EDF `_ and +`EDF+ `_ files can be read using +:func:`mne.io.read_raw_edf`. Both variants are 16-bit formats. -The EDF+ files may contain an annotation channel which can be used to store -trigger information. These annotations are available in ``raw.annotations``. +EDF+ files may contain annotation channels which can be used to store trigger +and event information. These annotations are available in ``raw.annotations``. -Saving EDF files is not supported natively yet. `This gist -`__ -can be used to save any mne.io.Raw into EDF/EDF+/BDF/BDF+. +Writing EDF files is not supported natively yet. `This gist +`__ or +`MNELAB `_ (both of which use +`pyedflib `_ under the hood) can be used +to export any :class:`mne.io.Raw` object to EDF/EDF+/BDF/BDF+. .. _import-biosemi: @@ -72,18 +73,18 @@ be imported with :func:`mne.io.read_raw_bdf`. BioSemi amplifiers do not perform "common mode noise rejection" automatically. -The signals in the EEG file are the voltages between each electrode and CMS +The signals in the EEG file are the voltages between each electrode and the CMS active electrode, which still contain some CM noise (50 Hz, ADC reference -noise, etc., see `the BioSemi FAQ `__ -for further detail). -Thus, it is advisable to choose a reference (e.g., a single channel like Cz, -average of linked mastoids, average of all electrodes, etc.) on import of +noise, etc.). The `BioSemi FAQ `__ +provides more details on this topic. +Therefore, it is advisable to choose a reference (e.g., a single channel like Cz, +average of linked mastoids, average of all electrodes, etc.) after importing BioSemi data to avoid losing signal information. The data can be re-referenced later after cleaning if desired. -.. warning:: The data samples in a BDF file are represented in a 3-byte +.. warning:: Data samples in a BDF file are represented in a 3-byte (24-bit) format. Since 3-byte raw data buffers are not presently - supported in the fif format these data will be changed to 4-byte + supported in the FIF format, these data will be changed to 4-byte integers in the conversion. @@ -92,7 +93,7 @@ General data format (.gdf) ========================== -GDF files can be read in using :func:`mne.io.read_raw_gdf`. +GDF files can be read using :func:`mne.io.read_raw_gdf`. `GDF (General Data Format) `_ is a flexible format for biomedical signals that overcomes some of the limitations of the @@ -100,26 +101,26 @@ and uses an event table. An updated specification (GDF v2) was released in 2011 and adds fields for additional subject-specific information (gender, age, etc.) and allows storing several physical units and other properties. -Both specifications are supported in MNE. +Both specifications are supported by MNE. .. _import-cnt: -Neuroscan CNT data format (.cnt) -================================ +Neuroscan CNT (.cnt) +==================== -CNT files can be read in using :func:`mne.io.read_raw_cnt`. -The channel locations can be read from a montage or the file header. If read +CNT files can be read using :func:`mne.io.read_raw_cnt`. +Channel locations can be read from a montage or the file header. If read from the header, the data channels (channels that are not assigned to EOG, ECG, -EMG or misc) are fit to a sphere and assigned a z-value accordingly. If a +EMG or MISC) are fit to a sphere and assigned a z-value accordingly. If a non-data channel does not fit to the sphere, it is assigned a z-value of 0. .. warning:: Reading channel locations from the file header may be dangerous, as the - x_coord and y_coord in ELECTLOC section of the header do not necessarily - translate to absolute locations. Furthermore, EEG-electrode locations that + x_coord and y_coord in the ELECTLOC section of the header do not necessarily + translate to absolute locations. Furthermore, EEG electrode locations that do not fit to a sphere will distort the layout when computing the z-values. - If you are not sure about the channel locations in the header, use of a + If you are not sure about the channel locations in the header, using a montage is encouraged. @@ -128,31 +129,33 @@ EGI simple binary (.egi) ======================== -EGI simple binary files can be read in using :func:`mne.io.read_raw_egi`. -The EGI raw files are simple binary files with a header and can be exported -from using the EGI Netstation acquisition software. +EGI simple binary files can be read using :func:`mne.io.read_raw_egi`. +EGI raw files are simple binary files with a header and can be exported by the +EGI Netstation acquisition software. .. _import-mff: EGI MFF (.mff) ============== -These files can also be read with :func:`mne.io.read_raw_egi`. + +EGI MFF files can be read with :func:`mne.io.read_raw_egi`. .. _import-set: -EEGLAB set files (.set) -======================= +EEGLAB files (.set, .fdt) +========================= -EEGLAB .set files can be read in using :func:`mne.io.read_raw_eeglab` -and :func:`mne.read_epochs_eeglab`. +EEGLAB .set files (which sometimes come with a separate .fdt file) can be read +using :func:`mne.io.read_raw_eeglab` and :func:`mne.read_epochs_eeglab`. .. _import-nicolet: Nicolet (.data) =============== + These files can be read with :func:`mne.io.read_raw_nicolet`. @@ -161,8 +164,8 @@ eXimia EEG data (.nxe) ====================== -EEG data from the Nexstim eXimia system can be read in using the -:func:`mne.io.read_raw_eximia` function. +EEG data from the Nexstim eXimia system can be read with +:func:`mne.io.read_raw_eximia`. .. _import-persyst: @@ -170,15 +173,15 @@ Persyst EEG data (.lay, .dat) ============================= -EEG data from the Persyst system can be read in using the -:func:`mne.io.read_raw_persyst` function. +EEG data from the Persyst system can be read with +:func:`mne.io.read_raw_persyst`. + +Note that subject metadata may not be properly imported because Persyst +sometimes changes its specification from version to version. Please let us know +if you encounter a problem. -Note that not all the subject metadata may be properly read in -due to the fact that Persyst changes its specification -sometimes from version to version. Please submit an issue, or -pull request if you encounter a problem. -Nihon Kohden EEG data (.EEG, .21E, .PNT, .LOG) +Nihon Kohden EEG data (.eeg, .21e, .pnt, .log) ============================================== EEG data from the Nihon Kohden (NK) system can be read using the @@ -186,20 +189,38 @@ Files with the following extensions will be read: -- The ``.EEG`` file contains the actual raw EEG data. -- The ``.PNT`` file contains the metadata related to the recording, such - as the measurement date. -- The ``.LOG`` file contains annotations for the recording. -- The ``.21E`` file contains the channel and electrode - recording system information. +- The ``.eeg`` file contains the actual raw EEG data. +- The ``.pnt`` file contains metadata related to the recording such as the + measurement date. +- The ``.log`` file contains annotations for the recording. +- The ``.21e`` file contains channel and electrode information. -Reading ``.11D``, ``.CMT``, ``.CN2``, and ``.EDF`` files is currently not +Reading ``.11d``, ``.cmt``, ``.cn2``, and ``.edf`` files is currently not supported. -Note that not all the subject metadata may be properly read in -due to the fact that NK changes the specification -sometimes from version to version. Please submit an issue, or -pull request if you encounter a problem. +Note that not all subject metadata may be properly read because NK changes the +specification sometimes from version to version. Please let us know if you +encounter a problem. + + +XDF data (.xdf, .xdfz) +====================== + +MNE-Python does not support loading +`XDF `_ files out of the box, +because the inherent flexibility of the XDF format makes it difficult to +provide a one-size-fits-all function. For example, XDF supports signals from +various modalities recorded with different sampling rates. However, it is +relatively straightforward to import only a specific stream (such as EEG +signals) using the `pyxdf `_ package. +See :ref:`ex-read-xdf` for a simple example. + +A more sophisticated version, which supports selection of specific streams as +well as converting marker streams into annotations, is available in +`MNELAB `_. If you want to use this +functionality in a script, MNELAB records its history (View - History), which +contains all commands required to load an XDF file after successfully loading +that file with the graphical user interface. Setting EEG references @@ -211,15 +232,16 @@ the data are assumed to already be properly referenced. See :ref:`tut-set-eeg-ref` for more information. + Reading electrode locations and head shapes for EEG recordings ============================================================== -Some EEG formats (EGI, EDF/EDF+, BDF) neither contain electrode location -information nor head shape digitization information. Therefore, this -information has to be provided separately. For that purpose all raw instances -have a :meth:`mne.io.Raw.set_montage` method to set electrode locations. +Some EEG formats (e.g., EGI, EDF/EDF+, BDF) contain neither electrode locations +nor head shape digitization information. Therefore, this information has to be +provided separately. For that purpose, all raw instances have a +:meth:`mne.io.Raw.set_montage` method to set electrode locations. -When using the locations of the fiducial points the digitization data -are converted to the MEG head coordinate system employed in the -MNE software, see :ref:`coordinate_systems`. +When using locations of fiducial points, the digitization data are converted to +the MEG head coordinate system employed in the MNE software, see +:ref:`coordinate_systems`. """ # noqa:E501