difference between pick_channels and pick methods

  • MNE version: 1.1.1

Hi,
What is the difference between “picks” and “pick_channels” methods? Both appear to do the same thing (pick a subset of channels). One thing that might differ concerns the ordering of picked channels, I would appreciate some clarification on this.
As far as I understand, “pick_channels” respects the initial ordering (for example, if the initial ordering was [‘Pz’, ‘CPz’], picking channels [‘CPz’, ‘Pz’] will return [‘Pz’, ‘CPz’]), unless one specifies ‘ordered= True’. But how does ordering work with the ‘pick’ method?

pick is a more general do-all function while:

  • pick_channels only selects channels by name
  • pick_types only selects channels by type

With pick you can do either of the 2 above and you can also select by indices. However, the order has to be controlled and provided correctly by the user. Here is an example with different cases I could think of:

import numpy as np

from mne import create_info
from mne.channels import make_standard_montage
from mne.io import RawArray


montage = make_standard_montage("standard_1020")
ch_names = [ch for ch in montage.ch_names][:10]
info = create_info(ch_names, 512, "eeg")
data = np.random.randn(len(ch_names), 4096)
raw = RawArray(data, info)
# >>> raw.ch_names
# ['Fp1', 'Fpz', 'Fp2', 'AF9', 'AF7', 'AF5', 'AF3', 'AF1', 'AFz', 'AF2']

raw_ = raw.copy().pick_channels(["Fp1", "AF7", "Fpz"])
# >>> raw_.ch_names
# ['Fp1', 'Fpz', 'AF7']  -> initial order

raw_ = raw.copy().pick_channels([0, 4, 1])
# >>> raises ValueError  -> does not work with indices

raw_ = raw.copy().pick([0, 4, 1])
# >>> raw_.ch_names
# ['Fp1', 'AF7', 'Fpz']  -> works with indices, ordered 0, 4, 1 as provided.

raw_ = raw.copy().pick(["Fp1", "AF7", "Fpz"])
# >>> raw_.ch_names
# ['Fp1', 'AF7', 'Fpz']

# pick also work with types.
raw.set_channel_types({"Fp1": "eog"})
raw_ = raw.copy().pick("eeg")
# >>> raw_.ch_names
# [Fpz', 'Fp2', 'AF9', 'AF7', 'AF5', 'AF3', 'AF1', 'AFz', 'AF2']

raw_ = raw.copy().pick_types(eeg=True)
# >>> raw_.ch_names
# [Fpz', 'Fp2', 'AF9', 'AF7', 'AF5', 'AF3', 'AF1', 'AFz', 'AF2']
1 Like

Thanks! So if the initial order of my raw object is “AF7”, “Fp1”,“Fpz” and I do:

raw_bis = raw.copy().pick_channels(["Fp1", "AF7", "Fpz"])
raw_bis.get_data()

The order of the raws will be “Fp1”, “AF7”, “Fpz” (and not “AF7”, “Fp1”,“Fpz”), is that correct?

Well no, by default pick_channels does not re-order the channels, except if ordered=True. On the contrary, picks will return the re-ordered channels.

The easiest way to figure it out if you are not sure is to write a small example:

import numpy as np

from mne import create_info
from mne.io import RawArray


info = create_info(["AF7", "Fp1", "Fpz", "other"], 1, "eeg")
data = np.zeros((4, 1))  # 3 channels, 1 sample
data[1, 0] = 1
data[2, 0] = 2
data[3, 0] = 3
raw = RawArray(data, info)

# raw.get_data()
# >>> array([[0.],
#            [1.],
#            [2.],
#            [3.]])

raw_ = raw.copy().pick_channels(["Fp1", "AF7", "Fpz"])
# raw_.get_data()
# >>> array([[0.],
#            [1.],
#            [2.]])
# -> original order

raw_ = raw.copy().pick_channels(["Fp1", "AF7", "Fpz"], ordered=True)
# raw_.get_data()
# >>> array([[1.],
#            [0.],
#            [2.]])
# -> order provided in pick_channels

raw_ = raw.copy().pick(["Fp1", "AF7", "Fpz"])
# raw_.get_data()
# >>> array([[1.],
#            [0.],
#            [2.]])
# -> order provided in pick, equivalent to pick_channels with ordered=True
1 Like

Yes of course sorry I meant
raw_bis = raw.copy().pick(["Fp1", "AF7", "Fpz"])

2 Likes