Fitting each spike as a dipole ( 1 spike= 1 dipole)

@mmagnuski @agramfort

I have 300 spikes in my recording and I wanted to fit dipoles for each of the spikes ( each spike as one event , not as average). I was able to do it on Brainstorm and the result is shown in the image ( I have only displayed dipoles with GOF>90 here),


where as I am not sure how to do it on MNE. I tried doing it as follows

data = []
   
for ii in event_dict:
    
    evoked = epochs[str(ii)][1:-1].average().crop(0,0.01)
    data.append(evoked.data[:, 0])
evoked = mne.EvokedArray(np.array(data).T, evoked.info, tmin=0.)

dip = mne.fit_dipole(evoked, cov=cov, bem=bem_sol, trans=trans)[0]

But obtained the following warnings and errors.


C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)
C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)
C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)
C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)
C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)
C:\Users\sxb2391\AppData\Local\Temp\ipykernel_26348\2116716511.py:5: RuntimeWarning: evoked object is empty (based on less than 1 epoch)
  evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [39], in <cell line: 9>()
      6     data.append(evoked.data[:, 0])
      7 evoked = mne.EvokedArray(np.array(data).T, evoked.info, tmin=0.)
----> 9 dip = mne.fit_dipole(evoked, cov=cov, bem=bem_sol, trans=trans)[0]

File <decorator-gen-379>:24, in fit_dipole(evoked, cov, bem, trans, min_dist, n_jobs, pos, ori, rank, accuracy, tol, verbose)

File ~\Anaconda3\envs\mne\lib\site-packages\mne\dipole.py:1286, in fit_dipole(evoked, cov, bem, trans, min_dist, n_jobs, pos, ori, rank, accuracy, tol, verbose)
   1284 data = evoked.data
   1285 if not np.isfinite(data).all():
-> 1286     raise ValueError('Evoked data must be finite')
   1287 info = evoked.info
   1288 times = evoked.times.copy()

ValueError: Evoked data must be finite

Is there a way I can fit an individual spikes ( each spike as one evoked) and not just the average of all spikes.

@Subrat_Bastola - I am assuming when you say spikes - these are single epilepsy spikes. If so, I assume you need to fit the covariance independently for each event. This hack seems to work:

import numpy as np
epochs.load_data()
epochs.crop(0.03, 0.06)  #Cropping these for speed

evoked = epochs.average()
dips=[]
for i,_ in enumerate(epochs):
    cov = mne.compute_covariance(epochs[i])
    evoked._data = np.squeeze(epochs[i].get_data())
    dip = mne.fit_dipole(evoked, cov=cov, bem=bem_sol, trans=trans) 
    dips.append(dip)

You can just overwrite the evoked data with each epoch’s data and solve the dipole from there. There may be more subtlety to the dipole solution that I don’t know about - but it does run and you have a list of dipoles as your output.

-Jeff

Hi Jeff, I tried doing exactly what you described, but came across this error.


dips.plot_locations(trans=trans, subject=subject, subjects_dir=subjects_dir, mode='orthoview',coord_frame='mri',idx='gof')

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [34], in <cell line: 1>()
----> 1 dips.plot_locations(trans=trans, subject=subject, subjects_dir=subjects_dir, mode='orthoview',coord_frame='mri',idx='gof')

AttributeError: 'list' object has no attribute 'plot_locations'

How do I display the list of dipoles on my MRI?

I don’t know too much about the dipole structure, but dips is a list of dipole answers. And then to plot the dipole, I think you have to subselect the dipole. I don’t know how you go about plotting them all together - thats probably a question for one of the core devs.

Here is some random dipole data plotted:

thanks @jstout211.Much appreciated

@richard, @agramfort

Is there a way to go about plotting them all together from the list dips, like @jstout211 has shown in the image?