Skip to content

mne.compute_rank does not return information for all valid channel types #11540

@tsbinns

Description

@tsbinns

Description of the problem

mne.compute_rank calls mne.io.pick._picks_by_type to find the channels to compute the rank for.

_picks_by_type only returns channels of types given in the variable _DATA_CH_TYPES_SPLIT which does not include types such as 'misc', 'emg', etc..., meaning information is not returned for all valid channel types.

mne-python/mne/io/pick.py

Lines 837 to 862 in 3bf04ed

def _picks_by_type(info, meg_combined=False, ref_meg=False, exclude='bads'):
"""Get data channel indices as separate list of tuples.
Parameters
----------
%(info_not_none)s
meg_combined : bool | 'auto'
Whether to return combined picks for grad and mag.
Can be 'auto' to choose based on Maxwell filtering status.
ref_meg : bool
If True include CTF / 4D reference channels
exclude : list of str | str
List of channels to exclude. If 'bads' (default), exclude channels
in info['bads'].
Returns
-------
picks_list : list of tuples
The list of tuples of picks and the type string.
"""
_validate_type(ref_meg, bool, 'ref_meg')
exclude = _check_info_exclude(info, exclude)
if meg_combined == 'auto':
meg_combined = _mag_grad_dependent(info)
picks_list = []
picks_list = {ch_type: list() for ch_type in _DATA_CH_TYPES_SPLIT}

mne-python/mne/io/pick.py

Lines 939 to 943 in 3bf04ed

_VALID_CHANNEL_TYPES = (
'eeg', 'grad', 'mag', 'seeg', 'eog', 'ecg', 'resp', 'emg', 'dipole', 'gof',
'bio', 'ecog', 'dbs') + _FNIRS_CH_TYPES_SPLIT + ('misc', 'csd')
_DATA_CH_TYPES_SPLIT = (
'mag', 'grad', 'eeg', 'csd', 'seeg', 'ecog', 'dbs') + _FNIRS_CH_TYPES_SPLIT

If this behaviour is intended, perhaps it could at least be noted in the documentation of compute_rank that information will not be returned for certain channel types, or raised as a warning message that channels of valid types not marked as 'bads' were dropped.

Steps to reproduce

import numpy as np
import mne

rand = np.random.RandomState(44)

n_channels = 3
n_times = 50
data = rand.random((n_channels, n_times))

info = mne.create_info(
    ch_names=[str(i) for i in range(n_channels)],
    sfreq=256,
    ch_types=['misc' for _ in range(n_channels)])

raw = mne.io.RawArray(data, info)

rank_dict = mne.compute_rank(raw)
rank_sum = sum(rank_dict.values())

assert np.linalg.matrix_rank(data) == n_channels  # expected rank (3)

Link to data

No response

Expected results

rank_dict == {'misc': 3}
rank_sum == 3

Actual results

rank_dict == {}
rank_sum = 0

Additional information

Platform: Windows-10-10.0.22621-SP0
Python: 3.11.0 | packaged by conda-forge | (main, Oct 25 2022, 06:12:32) [MSC v.1929 64 bit (AMD64)]
Executable: C:\Users\User\anaconda3\envs\mne_ssd\python.exe
CPU: Intel64 Family 6 Model 140 Stepping 1, GenuineIntel: 8 cores
Memory: 47.7 GB

mne: 1.4.dev0
numpy: 1.24.2 {MKL 2022.1-Product with 4 threads}
scipy: 1.10.0
matplotlib: 3.6.3 {backend=TkAgg}

sklearn: 1.2.1
numba: Not found
nibabel: Not found
nilearn: Not found
dipy: Not found
openmeeg: Not found
cupy: Not found
pandas: 1.5.3
pyvista: 0.38.1 {OpenGL 4.5.0 - Build 31.0.101.3889 via Intel(R) Iris(R) Xe Graphics}
pyvistaqt: 0.9.1
ipyvtklink: Not found
vtk: 9.2.5
qtpy: Not found
ipympl: Not found
pyqtgraph: Not found
pooch: v1.6.0

mne_bids: Not found
mne_nirs: Not found
mne_features: Not found
mne_qt_browser: Not found
mne_connectivity: Not found
mne_icalabel: Not found

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions