Back to the main page.

Bug 3458 - padding in ft_specest_mtmconvol

Reported 2018-10-14 17:23:00 +0200
Modified 2019-04-19 12:32:53 +0200
Product: FieldTrip
Component: specest
Version: unspecified
Hardware: PC
Operating System: Linux
Importance: P5 normal
Assigned to: Jan-Mathijs Schoffelen
Depends on:
See also:

Nir Ofir - 2018-10-14 17:23:36 +0200

Created attachment 873 Example data with 2 trials and a single channel Hi, First, does padding make sense with TFR analysis? Seems to me like this enables the user to compute the PSD of a purely padded data, which isn't too reasonable. Say I have 2 trials, one 0.5 sec long and the other 2.1 sec long, and I use windows of 0.25 sec and maxperlen zero/mirror padding for the TFR analysis, then I end up with many time points in the TFR of the short trial that contain no real data (and if I use zero padding, then the TFR should only be zeros...). Second, the way ft_specest_mtmconvol is written right now doesn't use the padded data. While the data is padded before the fft is computed (line 290 for tap_chan_freq_time dimord, or line 333 for chan_time_freqtap dimord), later lines make sure that only time points with corresponding real data are outputted: nsamplefreqoi = timwin(ifreqoi) .* fsample; reqtimeboiind = find((timeboi >= (nsamplefreqoi ./ 2)) & (timeboi < (ndatsample - (nsamplefreqoi ./2)))); reqtimeboi = timeboi(reqtimeboiind); % compute datspectrum*wavelet, if there are reqtimeboi's that have data dum = fftshift(ifft(datspectrum .* repmat(wltspctrm{ifreqoi}(itap,:),[nchan 1]), [], 2),2); % fftshift is necessary to implement zero-phase/acyclic/acausal convolution (either here, or the wavelet should be wrapped around sample=0) tmp = complex(nan(nchan,ntimeboi),nan(nchan,ntimeboi)); tmp(:,reqtimeboiind) = dum(:,reqtimeboi); (lines 304+ for tap_chan_freq_time dimord, or lines 346 for chan_time_freqtap dimord) The result is that the time points for which there is no data (as mentioned in the comment in the code) contain NaNs, and not the result of the convolution of the padded data. I'm attaching a data example with 2 trials, one 1.5 sec long, and the other 3.1 sec long. Running the following code shows that the resultant powspctrm really contains NaNs where you would expect them based on ft_specest_mtmconvol. winlength = 0.25; cfg = []; cfg.method = 'mtmconvol'; cfg.output = 'pow'; cfg.foi = 1/winlength:100; cfg.taper = 'dpss'; cfg.tapsmofrq = 5; cfg.t_ftimwin = ones(1,length(cfg.foi))*winlength; cfg.toi = 'all'; cfg.keeptrials = 'yes'; freq = ft_freqanalysis(cfg, data); My suggestion is to not allow padding at all when using mtmconvol (spectral interpolation is anyway done by choosing the foi here, and not by padding). Thanks! Nir

Jan-Mathijs Schoffelen - 2018-11-20 12:32:47 +0100

the padding in mtmconvol is needed to enable the correct application of the algorithmic trick to get the TFR. The trick is to apply a multiplication in the frequency domain (multiplying the Fourier transform of the (padded and tapered) data with the Fourier transform of the 'wavelets'). With variable length trials, data need to be padded with zeros (any other padtype does not make sense in my opinion) to ensure correct scaling etc. Subsequently, only the TFR data points are returned for which the original data contained data samples in the entire shifting time window. The rest will be NaN. It is a misconception that that padding enables to generate data points (TFR) in which there was no actual data present.