Getting started with mne.Report

This tutorial covers making interactive HTML summaries with mne.Report.

As usual we’ll start by importing the modules we need and loading some example data:

import os
import mne

Before getting started with mne.Report, make sure the files you want to render follow the filename conventions defined by MNE:

Data object

Filename convention (ends with)

raw

-raw.fif(.gz), -raw_sss.fif(.gz), -raw_tsss.fif(.gz), _meg.fif

events

-eve.fif(.gz)

epochs

-epo.fif(.gz)

evoked

-ave.fif(.gz)

covariance

-cov.fif(.gz)

trans

-trans.fif(.gz)

forward

-fwd.fif(.gz)

inverse

-inv.fif(.gz)

Basic reports

The basic process for creating an HTML report is to instantiate the Report class, then use the parse_folder() method to select particular files to include in the report. Which files are included depends on both the pattern parameter passed to parse_folder() and also the subject and subjects_dir parameters provided to the Report constructor.

For our first example, we’ll generate a barebones report for all the .fif files containing raw data in the sample dataset, by passing the pattern *raw.fif to parse_folder(). We’ll omit the subject and subjects_dir parameters from the Report constructor, but we’ll also pass render_bem=False to the parse_folder() method — otherwise we would get a warning about not being able to render MRI and trans files without knowing the subject.

path = mne.datasets.sample.data_path(verbose=False)
report = mne.Report(verbose=True)
report.parse_folder(path, pattern='*raw.fif', render_bem=False)
report.save('report_basic.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Iterating over 3 potential files (this may take some time)
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif
Opening raw data file /home/circleci/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
Isotrak not found
    Read a total of 3 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
    Range : 19800 ... 85867 =     32.966 ...   142.965 secs
Ready.
Current compensation grade : 0
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_filt-0-40_raw.fif
Opening raw data file /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_filt-0-40_raw.fif...
    Read a total of 4 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
        Average EEG reference (1 x 60)  idle
    Range : 6450 ... 48149 =     42.956 ...   320.665 secs
Ready.
Current compensation grade : 0
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif
Opening raw data file /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
    Read a total of 3 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
    Range : 25800 ... 192599 =     42.956 ...   320.670 secs
Ready.
Current compensation grade : 0
Saving report to location /home/circleci/project/tutorials/misc/report_basic.html
Rendering : Table of Contents
raw
 ... ernoise_raw.fif
 ... sample_audvis_filt-0-40_raw.fif
 ... sample_audvis_raw.fif

This report yields a textual summary of the Raw files selected by the pattern. For a slightly more useful report, we’ll ask for the power spectral density of the Raw files, by passing raw_psd=True to the Report constructor. Let’s also refine our pattern to select only the filtered raw recording (omitting the unfiltered data and the empty-room noise recordings):

pattern = 'sample_audvis_filt-0-40_raw.fif'
report = mne.Report(verbose=True, raw_psd=True)
report.parse_folder(path, pattern=pattern, render_bem=False)
report.save('report_raw_psd.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Iterating over 1 potential files (this may take some time)
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_filt-0-40_raw.fif
Opening raw data file /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_filt-0-40_raw.fif...
    Read a total of 4 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
        Average EEG reference (1 x 60)  idle
    Range : 6450 ... 48149 =     42.956 ...   320.665 secs
Ready.
Current compensation grade : 0
Effective window size : 13.639 (s)
Effective window size : 13.639 (s)
Effective window size : 13.639 (s)
Saving report to location /home/circleci/project/tutorials/misc/report_raw_psd.html
Rendering : Table of Contents
raw
 ... sample_audvis_filt-0-40_raw.fif

This time we’ll pass a specific subject and subjects_dir (even though there’s only one subject in the sample dataset) and remove our render_bem=False parameter so we can see the MRI slices, with BEM contours overlaid on top if available. Since this is computationally expensive, we’ll also pass the mri_decim parameter for the benefit of our documentation servers, and skip processing the .fif files:

subjects_dir = os.path.join(path, 'subjects')
report = mne.Report(subject='sample', subjects_dir=subjects_dir, verbose=True)
report.parse_folder(path, pattern='', mri_decim=25)
report.save('report_mri_bem.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Iterating over 0 potential files (this may take some time)
Rendering BEM
Saving report to location /home/circleci/project/tutorials/misc/report_mri_bem.html
Rendering : Table of Contents
mri
 ... bem

Now let’s look at how Report handles Evoked data (we’ll skip the MRIs to save computation time):

pattern = 'sample_audvis-no-filter-ave.fif'
report = mne.Report(verbose=True)
report.parse_folder(path, pattern=pattern, render_bem=False)
report.save('report_evoked.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Iterating over 1 potential files (this may take some time)
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis-no-filter-ave.fif
Saving report to location /home/circleci/project/tutorials/misc/report_evoked.html
Rendering : Table of Contents
evoked
 ... sample_audvis-no-filter-ave.fif

To render whitened Evoked files with baseline correction, add the noise covariance file. This will display ERP/F plots for both the original and whitened Evoked objects, but scalp topomaps only for the original.

cov_fname = os.path.join(path, 'MEG', 'sample', 'sample_audvis-cov.fif')
report = mne.Report(cov_fname=cov_fname, verbose=True)
report.parse_folder(path, pattern=pattern, render_bem=False)
report.save('report_evoked_whitened.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
    366 x 366 full covariance (kind = 1) found.
    Read a total of 4 projection items:
        PCA-v1 (1 x 102) active
        PCA-v2 (1 x 102) active
        PCA-v3 (1 x 102) active
        Average EEG reference (1 x 60) active
Iterating over 1 potential files (this may take some time)
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis-no-filter-ave.fif
Computing data rank from covariance with rank=None
    Using tolerance 4.7e-14 (2.2e-16 eps * 59 dim * 3.6  max singular value)
    Estimated rank (eeg): 58
    EEG: rank 58 computed from 59 data channels with 1 projector
Computing data rank from covariance with rank=None
    Using tolerance 1.8e-13 (2.2e-16 eps * 203 dim * 3.9  max singular value)
    Estimated rank (grad): 203
    GRAD: rank 203 computed from 203 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 2.5e-14 (2.2e-16 eps * 102 dim * 1.1  max singular value)
    Estimated rank (mag): 99
    MAG: rank 99 computed from 102 data channels with 3 projectors
    Created an SSP operator (subspace dimension = 4)
Computing data rank from covariance with rank={'eeg': 58, 'grad': 203, 'mag': 99, 'meg': 302}
    Setting small MEG eigenvalues to zero (without PCA)
    Setting small EEG eigenvalues to zero (without PCA)
    Created the whitener using a noise covariance matrix with rank 360 (4 small eigenvalues omitted)
Computing data rank from covariance with rank=None
    Using tolerance 4.7e-14 (2.2e-16 eps * 59 dim * 3.6  max singular value)
    Estimated rank (eeg): 58
    EEG: rank 58 computed from 59 data channels with 1 projector
Computing data rank from covariance with rank=None
    Using tolerance 1.8e-13 (2.2e-16 eps * 203 dim * 3.9  max singular value)
    Estimated rank (grad): 203
    GRAD: rank 203 computed from 203 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 2.5e-14 (2.2e-16 eps * 102 dim * 1.1  max singular value)
    Estimated rank (mag): 99
    MAG: rank 99 computed from 102 data channels with 3 projectors
    Created an SSP operator (subspace dimension = 4)
Computing data rank from covariance with rank={'eeg': 58, 'grad': 203, 'mag': 99, 'meg': 302}
    Setting small MEG eigenvalues to zero (without PCA)
    Setting small EEG eigenvalues to zero (without PCA)
    Created the whitener using a noise covariance matrix with rank 360 (4 small eigenvalues omitted)
Computing data rank from covariance with rank=None
    Using tolerance 4.7e-14 (2.2e-16 eps * 59 dim * 3.6  max singular value)
    Estimated rank (eeg): 58
    EEG: rank 58 computed from 59 data channels with 1 projector
Computing data rank from covariance with rank=None
    Using tolerance 1.8e-13 (2.2e-16 eps * 203 dim * 3.9  max singular value)
    Estimated rank (grad): 203
    GRAD: rank 203 computed from 203 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 2.5e-14 (2.2e-16 eps * 102 dim * 1.1  max singular value)
    Estimated rank (mag): 99
    MAG: rank 99 computed from 102 data channels with 3 projectors
    Created an SSP operator (subspace dimension = 4)
Computing data rank from covariance with rank={'eeg': 58, 'grad': 203, 'mag': 99, 'meg': 302}
    Setting small MEG eigenvalues to zero (without PCA)
    Setting small EEG eigenvalues to zero (without PCA)
    Created the whitener using a noise covariance matrix with rank 360 (4 small eigenvalues omitted)
Computing data rank from covariance with rank=None
    Using tolerance 4.7e-14 (2.2e-16 eps * 59 dim * 3.6  max singular value)
    Estimated rank (eeg): 58
    EEG: rank 58 computed from 59 data channels with 1 projector
Computing data rank from covariance with rank=None
    Using tolerance 1.8e-13 (2.2e-16 eps * 203 dim * 3.9  max singular value)
    Estimated rank (grad): 203
    GRAD: rank 203 computed from 203 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 2.5e-14 (2.2e-16 eps * 102 dim * 1.1  max singular value)
    Estimated rank (mag): 99
    MAG: rank 99 computed from 102 data channels with 3 projectors
    Created an SSP operator (subspace dimension = 4)
Computing data rank from covariance with rank={'eeg': 58, 'grad': 203, 'mag': 99, 'meg': 302}
    Setting small MEG eigenvalues to zero (without PCA)
    Setting small EEG eigenvalues to zero (without PCA)
    Created the whitener using a noise covariance matrix with rank 360 (4 small eigenvalues omitted)
Saving report to location /home/circleci/project/tutorials/misc/report_evoked_whitened.html
Rendering : Table of Contents
evoked
 ... sample_audvis-no-filter-ave.fif (whitened)
 ... sample_audvis-no-filter-ave.fif

If you want to actually view the noise covariance in the report, make sure it is captured by the pattern passed to parse_folder(), and also include a source for an Info object (any of the Raw, Epochs or Evoked .fif files that contain subject data also contain the measurement information and should work):

pattern = 'sample_audvis-cov.fif'
info_fname = os.path.join(path, 'MEG', 'sample', 'sample_audvis-ave.fif')
report = mne.Report(info_fname=info_fname, verbose=True)
report.parse_folder(path, pattern=pattern, render_bem=False)
report.save('report_cov.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Iterating over 1 potential files (this may take some time)
Rendering : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis-cov.fif
    366 x 366 full covariance (kind = 1) found.
    Read a total of 4 projection items:
        PCA-v1 (1 x 102) active
        PCA-v2 (1 x 102) active
        PCA-v3 (1 x 102) active
        Average EEG reference (1 x 60) active
Computing data rank from covariance with rank=None
    Using tolerance 2.5e-14 (2.2e-16 eps * 102 dim * 1.1  max singular value)
    Estimated rank (mag): 102
    MAG: rank 102 computed from 102 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 1.8e-13 (2.2e-16 eps * 203 dim * 3.9  max singular value)
    Estimated rank (grad): 203
    GRAD: rank 203 computed from 203 data channels with 0 projectors
Computing data rank from covariance with rank=None
    Using tolerance 4.7e-14 (2.2e-16 eps * 59 dim * 3.6  max singular value)
    Estimated rank (eeg): 59
    EEG: rank 59 computed from 59 data channels with 0 projectors
Saving report to location /home/circleci/project/tutorials/misc/report_cov.html
Rendering : Table of Contents
covariance
 ... sample_audvis-cov.fif

Adding custom plots to a report

The python interface has greater flexibility compared to the command line interface. For example, custom plots can be added via the add_figs_to_section() method:

# generate a custom plot:
fname_evoked = os.path.join(path, 'MEG', 'sample', 'sample_audvis-ave.fif')
evoked = mne.read_evokeds(fname_evoked,
                          condition='Left Auditory',
                          baseline=(None, 0),
                          verbose=True)
fig = evoked.plot(show=False)

# add the custom plot to the report:
report.add_figs_to_section(fig, captions='Left Auditory', section='evoked')
report.save('report_custom.html')

Out:

Reading /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis-ave.fif ...
    Read a total of 4 projection items:
        PCA-v1 (1 x 102) active
        PCA-v2 (1 x 102) active
        PCA-v3 (1 x 102) active
        Average EEG reference (1 x 60) active
    Found the data of interest:
        t =    -199.80 ...     499.49 ms (Left Auditory)
        0 CTF compensation matrices available
        nave = 55 - aspect type = 100
Projections have already been applied. Setting proj attribute to True.
Applying baseline correction (mode: mean)
Saving report to location /home/circleci/project/tutorials/misc/report_custom.html
Rendering : Table of Contents
covariance
 ... sample_audvis-cov.fif
evoked
 ... Left Auditory

Managing report sections

The MNE report command internally manages the sections so that plots belonging to the same section are rendered consecutively. Within a section, the plots are ordered in the same order that they were added using the add_figs_to_section() command. Each section is identified by a toggle button in the top navigation bar of the report which can be used to show or hide the contents of the section. To toggle the show/hide state of all sections in the HTML report, press t.

Note

Although we’ve been generating separate reports in each example, you could easily create a single report for all .fif files (raw, evoked, covariance, etc) by passing pattern='*.fif'.

Editing a saved report

Saving to HTML is a write-only operation, meaning that we cannot read an .html file back as a Report object. In order to be able to edit a report once it’s no longer in-memory in an active Python session, save it as an HDF5 file instead of HTML:

report.save('report.h5', overwrite=True)
report_from_disk = mne.open_report('report.h5')
print(report_from_disk)

Out:

Saving report to location /home/circleci/project/tutorials/misc/report.h5
Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
<Report | 2 items | MNE Report for ...data/MNE-sample-data
 ... sample_audvis-cov.fif
 ... Left Auditory
>

This allows the possibility of multiple scripts adding figures to the same report. To make this even easier, mne.Report can be used as a context manager:

with mne.open_report('report.h5') as report:
    report.add_figs_to_section(fig,
                               captions='Left Auditory',
                               section='evoked',
                               replace=True)
    report.save('report_final.html')

Out:

Embedding : jquery.js
Embedding : jquery-ui.min.js
Embedding : bootstrap.min.js
Embedding : jquery-ui.min.css
Embedding : bootstrap.min.css
Saving report to location /home/circleci/project/tutorials/misc/report_final.html
Rendering : Table of Contents
covariance
 ... sample_audvis-cov.fif
evoked
 ... Left Auditory
Saving report to location /home/circleci/project/tutorials/misc/report.h5

With the context manager, the updated report is also automatically saved back to report.h5 upon leaving the block.

Total running time of the script: ( 0 minutes 44.766 seconds)

Estimated memory usage: 264 MB

Gallery generated by Sphinx-Gallery