ValueError: All picks must be < n_channels (73), got 73

  • MNE Version: 1.5.0
  • Operating System: Windows 10
    I am using Jupyter Notebook.
# imports
import numpy as np
import os
import os.path as op
import matplotlib.pyplot as plt
import mne
import mneflow
import sklearn
import pandas as pd
import torch
from tqdm import tqdm

# Load data
data_path = "C:/Users/Raahul Pathak/Research/Raahul/Thesis-Project/Participant-Information/"
p01 = "p1.bdf"
p02 = "P02.bdf"
p03 = "p3.bdf"
p04 = "P04.bdf"
p05 = "P5.bdf"
p06 = "p6.bdf"
p07 = "p7.bdf"
p08 = "p8.bdf"
p09 = "p9.bdf"
p10 = "p10.bdf"
p11 = "p11.bdf"
p12 = "p12.bdf"

# Create raw info structures
p01_raw = data_path + p01

for i in tqdm(mne.io.read_raw_bdf(p01_raw)):
    pass

This gives me the following error: ValueError: All picks must be < n_channels (73), got 73
Can anyone please help me solve this error?

Can you do:

import mne

data_path = "C:/Users/Raahul Pathak/Research/Raahul/Thesis-Project/Participant-Information/"
p01_raw = data_path + p01
raw = mne.io.read_raw_bdf(p01_raw)
print (raw)
print (raw.info)

and return the 2 prints here.
Then:

for _ in raw:
    pass

And confirm that this last code snippet raises the ValueError. Please also post the full traceback of the error.

Mathieu

import mne
p01_raw = data_path + p01
raw = mne.io.read_raw_bdf(p01_raw)
print (raw)
print (raw.info)

The block above you asked me to run yields the following:

Extracting EDF parameters from C:\Users\Raahul Pathak\Research\Raahul\Thesis-Project\Participant-Information\p1.bdf...
BDF file detected
Setting channel info structure...
Creating raw.info structure...
<RawEDF | p1.bdf, 73 x 595712 (2327.0 s), ~73 kB, data not loaded>
<Info | 7 non-empty values
 bads: []
 ch_names: Fp1, AF7, AF3, F1, F3, F5, F7, FT7, FC5, FC3, FC1, C1, C3, C5, ...
 chs: 72 EEG, 1 Stimulus
 custom_ref_applied: False
 highpass: 0.0 Hz
 lowpass: 52.0 Hz
 meas_date: 2023-03-03 11:50:57 UTC
 nchan: 73
 projs: []
 sfreq: 256.0 Hz

And the for loop you asked me to run still gives the ValueError. Here is the full traceback.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-1b9a2d01e3f2> in <module>
----> 1 for _ in raw:
      2     pass

c:\users\raahul pathak\appdata\local\programs\python\python39\lib\site-packages\mne\io\base.py in __getitem__(self, item)
    840 
    841         """  # noqa: E501
--> 842         return self._getitem(item)
    843 
    844     def _getitem(self, item, return_times=True):

c:\users\raahul pathak\appdata\local\programs\python\python39\lib\site-packages\mne\io\base.py in _getitem(self, item, return_times)
    843 
    844     def _getitem(self, item, return_times=True):
--> 845         sel, start, stop = self._parse_get_set_params(item)
    846         if self.preload:
    847             data = self._data[sel, start:stop]

c:\users\raahul pathak\appdata\local\programs\python\python39\lib\site-packages\mne\io\base.py in _parse_get_set_params(self, item)
    776             )
    777 
--> 778         sel = _picks_to_idx(self.info, item[0])
    779 
    780         if isinstance(item[1], slice):

c:\users\raahul pathak\appdata\local\programs\python\python39\lib\site-packages\mne\io\pick.py in _picks_to_idx(info, picks, none, exclude, allow_empty, with_ref_meg, return_kind, picks_on)
   1302         raise ValueError("All picks must be >= %d, got %r" % (-n_chan, orig_picks))
   1303     if (picks >= n_chan).any():
-> 1304         raise ValueError(
   1305             "All picks must be < n_%s (%d), got %r" % (picks_on, n_chan, orig_picks)
   1306         )

ValueError: All picks must be < n_channels (73), got 73

I can reproduce on main with:

import numpy as np
from mne import create_info
from mne.io import RawArray


info = create_info(["EEG1", "EEG2", "STI1"], 1000, ["eeg", "eeg", "stim"])
data = np.random.randn(3, 1000)
raw = RawArray(data, info)
for _ in raw:
    pass

Will look into it,

Mathieu

1 Like

Thank you. Please let me know if you find anything. It would be greatly appreciated.

@mscheltienne, if it helps, it is not just p01 that is an issue. I believe it is all of them because I just tried to do the same with p02 and the same ValueError showed up with the same number of channels it stopped at.

What is this supposed to do? Raw does not implement the iterator protocol. It’s not clear what the OP is trying to do, but it looks like the loop should be over the different paths and not over raw objects.

1 Like

Do you mean what is the overall function of the network/algorithm I am trying to write? Or why I am trying to read in the files?

So a for loop on a raw object is definitely weird and should likely be prevented. I haven’t look at the code yet, if there is a usecase I am missing which iterates on the raw. But if that’s correct, then it should fail with a better error/message anyway.

@Raahul You are indeed not interating on the path but on the loaded p01_raw object. Try:

participants = [p01, p02, ...]
for participant in tqdm(participants):
    raw = mne.io.read_raw_bdf(participant )

agreed, and I’m not sure it should. The only reasonable thing I can think of would be iterating over channels but that seems like a big can of worms and is already possible without too much convoluted code (for ch in raw.info['ch_names'] followed by ch_data = raw.get_data(picks=ch), or directly with for ch_data in raw.get_data()).

Definitely, it should raise a TypeError: 'Raw' object is not iterable.

1 Like

When you say p01, p02, … in the participants array, do you mean the number of picks in a single bdf file, or the number of bdf files? I have twelve bdf files total and each one has tens of thousands to hundreds of thousands of picks.

“p01_raw” is just a naming scheme I gave to the raw bdf file I was trying to import/read in from my local machine. I am trying to read in a raw bdf file so I can use mne to pre-process, segment it, etc on it.

This is all the code I have run recently to do try to read in the bdf file. I want to give you guys an updated version of my code without any comments. This is before I try the participants thing because I am unsure of what exactly you mean by p01, p02, …

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import mne as mne
import os.path as op
from tqdm import tqdm

p01 = "C:/Users/Raahul Pathak/Research/Raahul/Thesis-Project/Participant-Information/p1.bdf"

for i in tqdm(mne.io.read_raw_bdf(p01)):
    pass

in your latest code snippet, p01 is a string variable pointing to a filename. then you load the file using mne.io.read_raw_bdf(p01), and then you pass the result of that (which will be a Raw object) to tqdm(). I can only guess that what you want to do is show a progress bar for the loading progress? That will not work. What happens now is that all of the file loading happens before tqdm() even looks at what you’ve passed to it.

Now, tqdm() expects an iterable object, and Raw objects are not iterable. The code ought to fail in the way @cbrnr indicated above. The fact that it does not fail doesn’t mean that what you’re trying to do is possible. It means that either there’s a subtle bug in MNE (Raw has a vacuous __iter__ method when it shouldn’t) or there’s a bug in TQDM (it should raise an error when passed a non-iterable, but it doesn’t).

instead of your for-loop, please just do

raw = mne.io.read_raw_bdf(p01)
# subsequent preprocessing steps go here

Yes. That is right. I want to view a a progress bar as to how much of the bdf file has been loaded/read in. I’ve already tried strictly doing the last code snippit you propose. But, I’ll try it again and let it run for longer this time. I’ll let it run for half-an-hour to an hour and I will touch base with you.

how big is the file?? You can pass preload=False to the read_raw_bdf function to skip loading the data into memory, that should almost always be fast.

The only reasonable thing I can think of would be iterating over channels but that seems like a big can of worms and is already possible without too much convoluted code (for ch in raw.info['ch_names'] followed by ch_data = raw.get_data(picks=ch), or directly with for ch_data in raw.get_data()).

That was my thought, some iteration over channels. Raw objects can be indexed, raw[1, :] will return the data array of the first channel and associated times (shape (1, n_samples), shape (n_samples,)). Thus, a for loop should maybe iterate on the first dimension similar to a numpy array?

But I agree that this use case should probably not be supported and simply raise a TypeError.

Between the twelve files I am trying load in, they range between 79,000 kilobytes to 130,000 kilobytes.

Where do I put the preload=False statement in the read_raw_bdf statement? Plus, I thought it defaulted to False, thus didn’t need to be manually set to False.

ah yes, you are right that preload=False is the default. Can you share a link to download one of the problematic files? Also just to rule out anything unexpected, please post the results of mne.sys_info() so we know what all your software versions are.

mne.sys_info() yields the below:

Platform             Windows-10-10.0.19045-SP0
Python               3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)]
Executable           c:\users\raahul pathak\appdata\local\programs\python\python39\python.exe
CPU                  AMD64 Family 23 Model 113 Stepping 0, AuthenticAMD (24 cores)
Memory               15.9 GB

I don’t know what’s going on. The below works for me in an IPython interpreter:

In [1]: import mne
In [2]: %timeit raw = mne.io.read_raw_bdf("p1.bdf", verbose=False)
3.26 ms ± 434 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

and if I actually load the data:

In [1]: import mne
In [2]: %timeit raw = mne.io.read_raw_bdf("p1.bdf", verbose=False, preload=True)
484 ms ± 2.99 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

note that I’m setting verbose=False just to suppress extra output other than the timings.

Can you run mne.sys_info() again? It should show a lot more than what you’ve provided; it doesn’t even show the version of MNE you’re running (much less other dependencies like numpy, scipy, etc)