The Info data structure#

This tutorial describes the mne.Info data structure, which keeps track of various recording details, and is attached to Raw, Epochs, and Evoked objects.

We will begin by loading the Python modules we need, and loading the same example data we used in the introductory tutorial:

# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = (
    sample_data_folder / "MEG" / "sample" / "sample_audvis_filt-0-40_raw.fif"
)
raw = mne.io.read_raw_fif(sample_data_raw_file)

As seen in the introductory tutorial, when a Raw object is loaded, an Info object is created automatically, and stored in the raw.info attribute:

print(raw.info)

However, it is not strictly necessary to load the Raw object in order to view or edit the Info object; you can extract all the relevant information into a stand-alone Info object using mne.io.read_info():

info = mne.io.read_info(sample_data_raw_file)
print(info)

As you can see, the Info object keeps track of a lot of information about:

  • the recording system (gantry angle, HPI details, sensor digitizations, channel names, …)

  • the experiment (project name and ID, subject information, recording date, experimenter name or ID, …)

  • the data (sampling frequency, applied filter frequencies, bad channels, projectors, …)

The complete list of fields is given in the API documentation.

Querying the Info object#

The fields in a Info object act like Python dictionary keys, using square brackets and strings to access the contents of a field:

print(info.keys())
print()  # insert a blank line
print(info["ch_names"])

Most of the fields contain int, float, or list data, but the chs field bears special mention: it contains a list of dictionaries (one dict per channel) containing everything there is to know about a channel other than the data it recorded. Normally it is not necessary to dig into the details of the chs field — various MNE-Python functions can extract the information more cleanly than iterating over the list of dicts yourself — but it can be helpful to know what is in there. Here we show the keys for the first channel’s dict:

print(info["chs"][0].keys())

Obtaining subsets of channels#

It is often useful to convert between channel names and the integer indices identifying rows of the data array where those channels’ measurements are stored. The Info object is useful for this task; two convenience functions that rely on the mne.Info object for picking channels are mne.pick_channels() and mne.pick_types(). pick_channels() minimally takes a list of all channel names and a list of channel names to include; it is also possible to provide an empty list to include and specify which channels to exclude instead:

print(mne.pick_channels(info["ch_names"], include=["MEG 0312", "EEG 005"]))

print(mne.pick_channels(info["ch_names"], include=[], exclude=["MEG 0312", "EEG 005"]))

pick_types() works differently, since channel type cannot always be reliably determined from channel name alone. Consequently, pick_types() needs an Info object instead of just a list of channel names, and has boolean keyword arguments for each channel type. Default behavior is to pick only MEG channels (and MEG reference channels if present) and exclude any channels already marked as “bad” in the bads field of the Info object. Therefore, to get all and only the EEG channel indices (including the “bad” EEG channels) we must pass meg=False and exclude=[]:

print(mne.pick_types(info, meg=False, eeg=True, exclude=[]))

Note that the meg and fnirs parameters of pick_types() accept strings as well as boolean values, to allow selecting only magnetometer or gradiometer channels (via meg='mag' or meg='grad') or to pick only oxyhemoglobin or deoxyhemoglobin channels (via fnirs='hbo' or fnirs='hbr', respectively).

A third way to pick channels from an Info object is to apply regular expression matching to the channel names using mne.pick_channels_regexp(). Here the ^ represents the beginning of the string and . character matches any single character, so both EEG and EOG channels will be selected:

print(mne.pick_channels_regexp(info["ch_names"], "^E.G"))

pick_channels_regexp() can be especially useful for channels named according to the 10-20 system (e.g., to select all channels ending in “z” to get the midline, or all channels beginning with “O” to get the occipital channels). Note that pick_channels_regexp() uses the Python standard module re to perform regular expression matching; see the documentation of the re module for implementation details.

Warning

Both pick_channels() and pick_channels_regexp() operate on lists of channel names, so they are unaware of which channels (if any) have been marked as “bad” in info['bads']. Use caution to avoid accidentally selecting bad channels.

Obtaining channel type information#

Sometimes it can be useful to know channel type based on its index in the data array. For this case, use mne.channel_type(), which takes an Info object and a single integer channel index:

print(mne.channel_type(info, 25))

To obtain several channel types at once, you could embed channel_type() in a list comprehension, or use the get_channel_types() method of a Raw, Epochs, or Evoked instance:

picks = (25, 76, 77, 319)
print([mne.channel_type(info, x) for x in picks])
print(raw.get_channel_types(picks=picks))

Alternatively, you can get the indices of all channels of all channel types present in the data, using channel_indices_by_type(), which returns a dict with channel types as keys, and lists of channel indices as values:

ch_idx_by_type = mne.channel_indices_by_type(info)
print(ch_idx_by_type.keys())
print(ch_idx_by_type["eog"])

Dropping channels from an Info object#

If you want to modify an Info object by eliminating some of the channels in it, you can use the mne.pick_info() function to pick the channels you want to keep and omit the rest:

print(info["nchan"])
eeg_indices = mne.pick_types(info, meg=False, eeg=True)
print(mne.pick_info(info, eeg_indices)["nchan"])

We can also get a nice HTML representation in IPython like this:

info

By default, pick_info() will make a copy of the original Info object before modifying it; if you want to modify it in-place, include the parameter copy=False.

Estimated memory usage: 0 MB

Gallery generated by Sphinx-Gallery