Reproducing Exercises for Analyzing Neural Time Series Data

Hi Mike. My coworker and I are currently working through all of the exercises in this book. One problem that we run into is in confirming our answers. The problems often ask the reader to pick an electrode, trial, or frequency and then do the work. The solution sheet presents an answer, but without indicating which specific value was selected for the variables. This makes it difficult to confirm that our models are correct. We like to be certain about our understanding before moving to each next chapter.

Could you supply the values for the trials, electrodes, etc for each question in the solution manual?

For now, we’re on Chapter 15, the Short-Time FFT. Our topographic plots match the solution, but our time-power plots do not.

  1. Which electrode and frequency did you use?
  2. How did you scale your answers so they are aligned on the Y axis? In our case, the short-Time FFT, wavelet FFT, and filter-Hilbert all have similar topographic features, but do not have similar scale. In the book you say “scaling might be different because no baseline normalization has been applied”, but your plots do show some kind of normalizing effect.

Thanks for the help.

For example, I can normalize after the fact for drawing my graph, but I assume this isn’t really desired:

stfft_power = squeeze(tf(electrode,freq2plotidx,:))’; % short-time FFT
mmp = mean(morlet_power,2)’; % morlet wavelet FFT
mhp = mean(hilbert_power,2)’; % filter-hilbert

% normalize each by it’s mean and plot them
hold on

Hi Brandon. I sympathize with your concern, and it’s something that, well, I wouldn’t say I regret about the book, but I have since made my exercises less open to interpretation.

For chapter 15, I see that I used electrode 47 (FCz). I also z-scored the power time series to make sure the three lines were in the same scale. The point of normalizing here was for visual inspection, to show that the three methods produce qualitatively similar results (could be even closer if parameters are carefully tuned).

I hope that helps. Feel free to post with more questions.

Yeah, that helps thanks.

The book is great!

Hi Mike-

Similar question for chapter 14: could you post the electrode, trial, and filter type (also, which frequencies if not 5 and 25)?



Oops, somehow this slipped off the radar for 8 days. Sorry!

I used electrode FCz (#47). Trial 1. The filter was eegfilt (from the eeglab toolbox) with a 4 Hz width (+/-2 Hz around 2 and 25 Hz). I hope that’s enough info!

Thanks, and thanks for your great book!

How about the selected electrode in chapter 12 answers? I am assuming these are the averaged ERPs (question 3)?

I used electrode POz.

1 Like

Great, thanks a lot!

Hi again! With regard to the same exercise as above, I can’t seem to get the outputs shown in the solutions pdf.
Just as a dummy test on a single trial (the question calls for averaging across trials) I changed the frequency in figure 12.5 and plotted it using the code below:

% EEG data from one trial (electrode POz)
eegdata = squeeze(,:,10));

% create wavelet
time = -1:1/EEG.srate:1;
f = 2; % frequency of sine wave in Hz
sine_wave = exp(1i*2*pi*f.*time);
s = 4.5/(2*pi*f); 
gaussian_win = exp(-time.^2./(2*s^2));
wavelet = sine_wave .* gaussian_win;
% half of the wavelet size, useful for chopping off edges after convolution.
halfwaveletsize = ceil(length(wavelet)/2);

% convolve with data
% compute Gaussian
n_conv = length(wavelet) + EEG.pnts - 1;

fft_w = fft(wavelet,n_conv);
fft_e = fft(eegdata,n_conv);
% sqrt... is an empirical scaling factor that works here
ift   = ifft(fft_e.*fft_w,n_conv)*sqrt(s)/10; 
wavelet_conv_data = real(ift(halfwaveletsize:end-halfwaveletsize+1));

% now plot all the pieces

hold on
set(gca,'xlim',[-200 1000],'ydir','r')
xlabel('Time (ms)'), ylabel('Voltage (\muV)')


Isn’t this supposed to something like:


I would really appreciate it if you, or any of the other members could point me into the right direction. Thanks! :grinning:

This is what I am getting for the exercise based on the same logic.

Btw, for convolutions is it also the same when averaging, as in it doesn’t matter if you convolve them trials individually then average vs average and then convolve?

1 Like

Hmm, so I ran my code and it seems to reproduce yours exactly.

My guess is that at some point after the book was published, I changed something in the code and forgot to change it back. Oops :wink:

Anyway, it means your code was correct. Apologies for the anxiety I might have caused :stuck_out_tongue:


Oh phew! Thanks a lot for recomputing, this will now put me at ease. No problem, it made me go over the code several times so I have a better idea of the code now :slightly_smiling_face::upside_down_face:

Hello again @MikeXCohen, In chapter 13 do you remember which trial was used to compute the results?


Looks like I used trial #98.

1 Like

Hi, sorry to bug you again about this, but which frequency did you use to make the plot found in the answers for chapter 15? (the plot where all three time-frequency methods are shown)

Don’t apologize :wink:

For the first question, I used 6 and 10 Hz. For the second question I used 6 Hz.

1 Like

Hi Mike-

Sorry to interrupt, I come into similar question for chapter 16:

  1. May I ask what is the post-processing(I mean: log10,zscore, etc?) method used for plotting the Power/SNR?
  2. Are the displayed result get average from all trials, or only from a specific trial number?



Hi Bai.

  1. In my code, I computed dB (10log_10) relative to a baseline of -300 to 0 ms. SNR was not post-processed; just the mean power divided by the std power (over trials).
  2. Averaged over all trials.

If you’re having trouble matching the results shown in the screenshots I provided for my answer, feel free to include your screenshots and/or code and/or a description of what you did. Sometimes the differences are simply due to parameter selections and not errors in your solution.