Using MNE with 3D visualization on a headless server

Hello. We’ve been trying various ways to get mne-python working on a headless server (HPC cluster), we still can’t get it to work. If someone could help us out, we’d appreciate it!

First of all, we’ve built a docker container with something like this

FROM continuumio/anaconda3
RUN pip3 install mne==1.0.3 pyvista nibabel

RUN apt-get update && apt-get -y install libgl1 mesa-utils libgl1-mesa-glx xvfb

Then, we run the following test code through docker.

$ cat test.py
import os
import mne
import pyvista as pv
from pathlib import Path
os.environ["MNE_3D_OPTION_ANTIALIAS"] = "false"

from pyvista.utilities import xvfb
xvfb.start_xvfb()
mne.viz.set_3d_backend("notebook")

data_path = Path(mne.datasets.sample.data_path(verbose=False))
sample_dir = data_path / 'MEG' / 'sample'
subjects_dir = data_path / 'subjects'

raw_path = sample_dir / 'sample_audvis_filt-0-40_raw.fif'

print("----------------1")
report = mne.Report(title='BEM example')
print("----------------2")
report.add_bem(
    subject='sample', subjects_dir=subjects_dir, title='MRI & BEM',
    decim=20,
    width=256
)

trans_path = sample_dir / 'sample_audvis_raw-trans.fif'

print("----------------3")
report.add_trans(
    trans=trans_path, info=raw_path, subject='sample',
    subjects_dir=subjects_dir, alpha=1.0, title='Coregistration'


)

print("----------------4")
fwd_path = sample_dir / 'sample_audvis-meg-oct-6-fwd.fif'
report.add_forward(forward=fwd_path, title='Forward solution')

report.save('report_mri_and_bem.html', overwrite=True)
$ python3 test.py
Using notebook 3d backend.

----------------1
Embedding : jquery-3.6.0.min.js
Embedding : bootstrap.bundle.min.js
Embedding : bootstrap.min.css
Embedding : bootstrap-table/bootstrap-table.min.js
Embedding : bootstrap-table/bootstrap-table.min.css
Embedding : bootstrap-table/bootstrap-table-copy-rows.min.js
Embedding : bootstrap-table/bootstrap-table-export.min.js
Embedding : bootstrap-table/tableExport.min.js
Embedding : bootstrap-icons/bootstrap-icons.mne.min.css
Embedding : highlightjs/highlight.min.js
Embedding : highlightjs/atom-one-dark-reasonable.min.css
----------------2
Using surface: /root/mne_data/MNE-sample-data/subjects/sample/bem/inner_skull.surf
Using surface: /root/mne_data/MNE-sample-data/subjects/sample/bem/outer_skull.surf
Using surface: /root/mne_data/MNE-sample-data/subjects/sample/bem/outer_skin.surf
----------------3
    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
Using lh.seghead for head surface.
Getting helmet for system 306m
Channel types::	grad: 203, mag: 102, eeg: 59
/opt/conda/lib/python3.9/site-packages/pyvista/plotting/plotting.py:5001: UserWarning: Not within a jupyter notebook environment.
Ignoring ``jupyter_backend``.
  warnings.warn(

After displaying the last message, mne_python simply sits doing nothing particular on the server (according to glances/htop).

If I switch the container to use FROM python:3.10 as the base image, mne_python simply fails to install while building the docker container… but I am not sure which base image I should be using in this case.

Thank you!

Hello, the recommended way for installing on a headless server is described here:

https://mne.tools/stable/install/advanced.html#installing-to-a-headless-server

Best wishes,
Richard

3 Likes

If you want a working example and are not easily intimidated by complex installs :slight_smile: , you can also look at the Circle CI install script which has to work every pull request for it to be green: mne-python/config.yml at main · mne-tools/mne-python · GitHub

1 Like

For a usage inside docker, the best ressource available AFAIK is mne-docker but it might not be up to date.

For reference, I will also describe the standard procedure to use mne-python on a remote server using conda and jupyter notebook, without docker:

  1. (on server) clone mne-python:

git clone https://github.com/mne-tools/mne-python.git

  1. (on server) create a conda environment from server_environment.yml:

conda env create -f server_environment.yml

  1. (on server) activate the environment:

conda activate mne

  1. (on server) start jupyter notebook in “no browser” mode:

jupyter notebook --no-browser --port=8889

  1. (on client) ssh forwarding:

ssh -N -f -L localhost:8888:localhost:8889 username@your_remote_host_name

  1. (on web browser - on client) in the address bar:

localhost:8888

Here is a gist to showcase the features available.

Further consideration: those steps could be automated inside a docker container too.

2 Likes