Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MRG: Tutorial improvements #9416

Merged
merged 2 commits into from
May 23, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 47 additions & 48 deletions tutorials/io/30_reading_fnirs_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,21 @@
Importing data from fNIRS devices
=================================

MNE includes various functions and utilities for reading fNIRS
data and optode locations. Regardless of the manufacturer and file format,
MNE stores both the measurement data and metadata in a consistent manner.

fNIRS devices consist of light sources and light detectors,
often also termed emitter/transmitter and receiver respectively.
A channel is formed by source-detector pairs, and MNE represents the
channel location as the midpoint between source and detector.
MNE stores the location of the channels, sources, and
detectors.
There are a variety of fNIRS data types which can be represented in MNE.
For continuous wave fNIRS data this includes amplitude, optical density,
oxyhaemoglobin, and deoxyhemoglobin.
And for frequency domain fNIRS this additionally includes
AC amplitude and phase.
Different vendors save the data as different data types, and MNE will load
the data as the appropriate type.

.. warning:: MNE stores metadata internally with a specific structure,
fNIRS devices consist of two kinds of optodes: light sources (AKA "emitters" or
"transmitters") and light detectors (AKA "receivers"). Channels are defined as
source-detector pairs, and channel locations are defined as the midpoint
between source and detector.

MNE-Python provides functions for reading fNIRS data and optode locations from
several file formats. Regardless of the device manufacturer or file format,
MNE-Python's fNIRS functions will internally store the measurement data and its
metadata in the same way (e.g., data values are always converted into SI
units). Supported measurement types include amplitude, optical density,
oxyhaemoglobin concentration, and deoxyhemoglobin concentration (for continuous
wave fNIRS), and additionally AC amplitude and phase (for
frequency domain fNIRS).

.. warning:: MNE-Python stores metadata internally with a specific structure,
and internal functions expect specific naming conventions.
Manual modification of channel names and metadata
is not recommended.
Expand All @@ -44,13 +40,13 @@
is designed by the fNIRS community in an effort to facilitate
sharing and analysis of fNIRS data. And is the official format of the
Society for functional near-infrared spectroscopy (SfNIRS).
SNIRF is the preferred format for reading data in to MNE.
SNIRF is the preferred format for reading data in to MNE-Python.
Data stored in the SNIRF format can be read in
using :func:`mne.io.read_raw_snirf`.

.. note:: The SNIRF format has provisions for many different types of fNIRS
recordings. MNE currently only supports reading continuous wave data
stored in the .snirf format.
recordings. MNE-Python currently only supports reading continuous
wave data stored in the .snirf format.


***********************
Expand All @@ -66,9 +62,10 @@
NIRx produce continuous wave fNIRS devices.
NIRx recordings can be read in using :func:`mne.io.read_raw_nirx`.
The NIRx device stores data directly to a directory with multiple file types,
MNE extracts the appropriate information from each file.
MNE only supports NIRx files recorded with NIRStar version 15.0 and above.
MNE supports reading data from NIRScout and NIRSport 1 devices.
MNE-Python extracts the appropriate information from each file.
MNE-Python only supports NIRx files recorded with NIRStar
version 15.0 and above.
MNE-Python supports reading data from NIRScout and NIRSport 1 devices.


.. _import-hitachi:
Expand All @@ -94,7 +91,7 @@
BOXY recordings can be read in using :func:`mne.io.read_raw_boxy`.
The BOXY software and ISS Imagent I and II devices are frequency domain
systems that store data in a single ``.txt`` file containing what they call
(with MNE's name for that type of data in parens):
(with MNE-Python's name for that type of data in parens):

- DC
All light collected by the detector (``fnirs_cw_amplitude``)
Expand All @@ -110,9 +107,10 @@

These raw data files can be saved by the acquisition devices as parsed or
unparsed ``.txt`` files, which affects how the data in the file is organised.
MNE will read either file type and extract the raw DC, AC, and Phase data.
If triggers are sent using the ``digaux`` port of the recording hardware, MNE
will also read the ``digaux`` data and create annotations for any triggers.
MNE-Python will read either file type and extract the raw DC, AC,
and Phase data. If triggers are sent using the ``digaux`` port of the
recording hardware, MNE-Python will also read the ``digaux`` data and
create annotations for any triggers.


******************
Expand All @@ -128,10 +126,11 @@
provided by the Society for functional Near-Infrared Spectroscopy,
and then load it using :func:`mne.io.read_raw_snirf`.

fNIRS measurements can have a non-standardised format that is not supported by
MNE and cannot be converted easily into SNIRF. This legacy data is often in CSV
or TSV format, we show here a way to load it even though it is not officially
supported by MNE due to the lack of standardisation of the file format (the
fNIRS measurements may be stored in a non-standardised format that is not
supported by MNE-Python and cannot be converted easily into SNIRF.
This legacy data is often in CSV or TSV format,
we show here a way to load it even though it is not officially supported by
MNE-Python due to the lack of standardisation of the file format (the
naming and ordering of channels, the type and scaling of data, and
specification of sensor positions varies between each vendor). You will likely
have to adapt this depending on the system from which your CSV originated.
Expand All @@ -144,10 +143,10 @@
# sphinx_gallery_thumbnail_number = 2

###############################################################################
# First, we generate an example CSV file which will then be loaded in to MNE.
# This step would be skipped if you have actual data you wish to load.
# We simulate 16 channels with 100 samples of data and save this to a file
# called fnirs.csv.
# First, we generate an example CSV file which will then be loaded in to
# MNE-Python. This step would be skipped if you have actual data you wish to
# load. We simulate 16 channels with 100 samples of data and save this to a
# file called fnirs.csv.

pd.DataFrame(np.random.normal(size=(16, 100))).to_csv("fnirs.csv")

Expand All @@ -173,7 +172,7 @@
# Then, the metadata must be specified manually as the CSV file does not
# contain information about channel names, types, sample rate etc.
#
# .. warning:: In MNE the naming of channels MUST follow the structure of
# .. warning:: In MNE-Python the naming of channels MUST follow the structure
# ``S#_D# type`` where # is replaced by the appropriate source and
# detector numbers and type is either ``hbo``, ``hbr`` or the
# wavelength.
Expand All @@ -190,14 +189,14 @@


###############################################################################
# Finally, the data can be converted in to an MNE data structure.
# Finally, the data can be converted in to an MNE-Python data structure.
# The metadata above is used to create an :class:`mne.Info` data structure,
# and this is combined with the data to create an MNE :class:`~mne.io.Raw`
# object. For more details on the info structure see :ref:`tut-info-class`, and
# for additional details on how continuous data is stored in MNE see
# :ref:`tut-raw-class`.
# For a more extensive description of how to create MNE data structures from
# raw array data see :ref:`tut_creating_data_structures`.
# and this is combined with the data to create an MNE-Python
# :class:`~mne.io.Raw` object. For more details on the info structure
# see :ref:`tut-info-class`, and for additional details on how continuous data
# is stored in MNE-Python see :ref:`tut-raw-class`.
# For a more extensive description of how to create MNE-Python data structures
# from raw array data see :ref:`tut_creating_data_structures`.

info = mne.create_info(ch_names=ch_names, ch_types=ch_types, sfreq=sfreq)
raw = mne.io.RawArray(data, info, verbose=True)
Expand All @@ -212,10 +211,10 @@
# etc), this is may be particularly important for fNIRS as information about
# the optode locations is required to convert the optical density data in to an
# estimate of the haemoglobin concentrations.
# MNE provides methods to load standard sensor configurations (montages) from
# some vendors, and this is demonstrated below.
# MNE-Python provides methods to load standard sensor configurations
# (montages) from some vendors, and this is demonstrated below.
# Some handy tutorials for understanding sensor locations, coordinate systems,
# and how to store and view this information in MNE are:
# and how to store and view this information in MNE-Python are:
# :ref:`tut-sensor-locations`, :ref:`plot_source_alignment`, and
# :ref:`ex-eeg-on-scalp`.
#
Expand Down