mne-tools / mne-bids

MNE-BIDS is a Python package that allows you to read and write BIDS-compatible datasets with the help of MNE-Python.
https://mne.tools/mne-bids/
BSD 3-Clause "New" or "Revised" License
126 stars 84 forks source link

`read_raw_bids()` tries to process task name without checking if a task exists #1235

Closed aplzr closed 4 months ago

aplzr commented 4 months ago

Description of the problem

Using the latest mne_bids version (v.0.14) I'm trying to load an EEG recording using mne_bids.read_raw_bids(). I'm passing the following BIDSPath to the function:

BIDSPath(
root: [redacted]
datatype: eeg
basename: sub-K9HC7HN_ses-20210414_eeg.vhdr)

As you can see there is no task entity in the basename, which as I understand is legal according to the BIDS spec.

Calling read_raw_bids with this BIDSPath results in an error with the following stack trace:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[126], line 1
----> 1 mne_bids.read_raw_bids(bids_path=bids_paths[-3])

File <decorator-gen-361>:12, in read_raw_bids(bids_path, extra_params, verbose)

File c:\Users\pzr\development\nemo\data_exploration\.venv\Lib\site-packages\mne_bids\read.py:841, in read_raw_bids(bids_path, extra_params, verbose)
    828 raw = _read_raw(
    829     raw_path,
    830     electrode=None,
   (...)
    834     **extra_params,
    835 )
    837 # Try to find an associated events.tsv to get information about the
    838 # events in the recorded data
    839 if (
    840     bids_path.subject == "emptyroom" and bids_path.task == "noise"
--> 841 ) or bids_path.task.startswith("rest"):
    842     on_error = "ignore"
    843 else:

AttributeError: 'NoneType' object has no attribute 'startswith'

In line 841 a string operation is applied to bids_path.task, but because it is not actually a str but None, the attribute error is raised.

I can't open a pull request at the moment and I'm also not sure if I'm overlooking anything as this is the first time working with BIDS, but I have a suggestion for a fix:

Changing line 841 from

) or bids_path.task.startswith("rest"):

to

) or (bids_path.task and bids_path.task.startswith("rest")):

resolves the problem and I can load the data.

Steps to reproduce

Use mne_bids.read_raw_bids() to load a BIDS dataset that does not contain task information (i.e. whose filenames do not contain a task entity).

Expected results

The dataset is loaded from disk.

Actual results

An attribute error is raised.

Additional information

Platform             Windows-10-10.0.19045-SP0
Python               3.12.2 (tags/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]
Executable           c:\Users\pzr\development\nemo\data_exploration\.venv\Scripts\python.exe
CPU                  Intel64 Family 6 Model 158 Stepping 13, GenuineIntel (8 cores)
Memory               15.8 GB

Core
├☑ mne               1.6.1 (latest release)
├☑ numpy             1.26.4 (OpenBLAS 0.3.23.dev with 8 threads)
├☑ scipy             1.12.0
├☑ matplotlib        3.8.3 (backend=module://matplotlib_inline.backend_inline)
├☑ pooch             1.8.1
└☑ jinja2            3.1.3

Numerical (optional)
├☑ sklearn           1.4.1.post1
├☑ nibabel           5.2.1
├☑ pandas            2.2.1
└☐ unavailable       numba, nilearn, dipy, openmeeg, cupy

Visualization (optional)
├☑ pyvista           0.43.3 (OpenGL 4.5.0 - Build 31.0.101.2115 via Intel(R) UHD Graphics 630)
├☑ pyvistaqt         0.11.0
├☑ vtk               9.3.0
├☑ qtpy              2.4.1 (PyQt5=5.15.2)
├☑ ipywidgets        8.1.2
└☐ unavailable       ipympl, pyqtgraph, mne-qt-browser, trame_client, trame_server, trame_vtk, trame_vuetify

Ecosystem (optional)
├☑ mne-bids          0.14
└☐ unavailable       mne-nirs, mne-features, mne-connectivity, mne-icalabel, mne-bids-pipeline
welcome[bot] commented 4 months ago

Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴🏽‍♂️

sappelhoff commented 4 months ago

Thanks for the report!

Just to clarify: My understanding of the filename template table for EEG in the BIDS specification is, that the task entity is NOT optional, see screenshot:

image

What makes you think that not having a task entity is a legitimate formatting according to the spec? :-)

aplzr commented 4 months ago

I thought I had read somewhere in the BIDS docs that only subject and session are mandatory, but it seems I was wrong and it's actually subject and task. Also I might have inadvertently put some (apparently undeserved) trust into the source of my data, since I was told that adherence to the BIDS spec is important to them.

Thanks for pointing me in the right direction. I will update my recordings with a (dummy) task.

hoechenberger commented 4 months ago

@sappelhoff I think we should fail earlier or provide a better error message either way...

sappelhoff commented 4 months ago

I agree that mne-bids should provide a more helpful error message for this