How to get the peak value of each channel in mne

I would like to ask if there is a way to get the peak value of each channel in mne.
I am using mne’s evoke get_peak function to get the peak, but this seems to return only the largest one among all channels, is there any way to get the peak of each channel in a certain time period?

N100 = evoked_roi.get_peak(tmin = 0.1,tmax = 0.2,
time_as_index = True,
return_amplitude=True)

I’m looking forward to your reply. Thank you very much for your help!

  • MNE-Python version: MNE 0.22.0
  • operating system: mac 10.14.6, jupyter lab 3.0.5

If you use

foobar = evoked_roi.get_data(picks=[:], start=1, stop=3)

you’ll get a matrix consisting of (channels x samples) in range start to stop.

next step would be to use either scipy (scipy.signal.find_peaks) if you want to find multiple peaks or numpy if you want to find only one peak, so for instance :

numpy.argmax(foobar, axis=1)

this should return a vector consisting of the indices of the samples containing the maximum values per channel.

This is how I would approach this, maybe somebody knows a more elegant solution or there is something that comes out of the box with mne?

Hope that helps.

Thank you very much for your reply!

It seems that the evoke object has no get_data parameter, I used evoke_roi.data[:,100:150] to get the data. (The Evoked data structure: evoked/averaged data — MNE 0.23.dev0 documentation)
But the two methods you mentioned: scipy.signal.find_peaks and numpy.argmax seem to extract peaks from one-dimensional data.
The webpage of scipy.signal.find_peaks says that This function takes a 1-D array and finds all local maxima by simple comparison of neighboring values.
(scipy.signal.find_peaks — SciPy v1.6.0 Reference Guide)

You are right that scipy.signal.find_peaks operates on 1D data. But numpy.argmax can take arrays of any shape, and has an axis parameter, so @RuKrei’s second suggestion should work as long as you’re only interested in the (index of the) single highest value per channel.

(Aside: the .get_data() method is for Raw and Epochs objects, Evokeds are usually much smaller (in terms of memory) so Evoked data is always automatically preloaded into RAM. That is why it has a .data attribute instead of a .get_data() method.)

Thank you very much for your reply!
I have two questions about the function of numpy.argmax and would like to ask you.
The first is that it seems impossible to get the peak value of each channel.
I use code
peak = np.argmax(evoke2_roi[150:200]) (50 time points and 11 channels)
But it returns only one value, not the peak value of all channels. I also tried adding axis=0, or axis=1, but they all reported errors.
The error is as follows
peak = np.argmax(evoke2_roi[150:200], axis=0)
Shape of passed values is (11, 1), indices imply (50, 11)
peak = np.argmax(evoke2_roi[150:200], axis=1)
Shape of passed values is (50, 1), indices imply (50, 11)
I find it strange, it seems that the code in the official interface can run normally.numpy.argmin — NumPy v1.20 Manual
Another problem is that the np.argmax function seems to only return the time point corresponding to the peak, but it does not return the peak.

I don’t think that can really be the code you’re using, since the part evoke2_roi[150:200] should already fail (Evoked object is not subscriptable). Unless evoke2_roi is already a NumPy array? In which case probably it should say evoke2_roi[:, 150:200] (note the extra : saying to keep all channels, and apply the slice across the time axis). So assuming your evoke2_roi is a NumPy array:

time_of_interest = evoke2_roi[:, 150:200]
indices = np.argmax(time_of_interest, axis=1)
peak_values = time_of_interest[:, indices]

Thank you very much for your help, this is indeed working and very effective!