Back to the main page.

Bug 2364 - If first channel is filled with NaNs complete output of ft_freqanalysis is NaN

Status CLOSED FIXED
Reported 2013-11-05 18:54:00 +0100
Modified 2015-02-11 10:40:47 +0100
Product: FieldTrip
Component: specest
Version: unspecified
Hardware: All
Operating System: Linux
Importance: P3 normal
Assigned to: Robert Oostenveld
URL:
Tags:
Depends on:
Blocks:
See also:

Joscha Schmiedt - 2013-11-05 18:54:47 +0100

If the first channel of a dataset has been filled with NaNs, e.g., as a result of ft_rejectvisual with cfg.keepchannel = 'nan', the output of ft_freqanalysis is NaN for all channels. This does not happen for channels 2:end. Code for reproducing: nTrials = 20; data = []; data.fsample = 256; data.trial = arrayfun(@(x) rand(10, 512), 1:nTrials, 'UniformOutput', false); data.time = repmat({(0:length(data.trial{1})-1)/data.fsample}, [1, nTrials]); data.label = cellfun(@num2str, num2cell(1:10), 'UniformOutput', false); for iTrial = 1:nTrials data.trial{iTrial}(1,:) = nan; end cfg = []; cfg.method = 'wavelet'; cfg.width = 2; cfg.foilim = [10 50]; cfg.toi = 0:0.01:2; tf = ft_freqanalysis(cfg, data); fprintf('number of non-nans for wavelet method: %i\n', sum(~isnan(tf.powspctrm(:)))) cfg = []; cfg.method = 'mtmconvol'; cfg.taper = 'hanning'; cfg.foi = 10:50; cfg.t_ftimwin = 2./cfg.foi; cfg.toi = 0:0.01:2; tf = ft_freqanalysis(cfg, data); sum(~isnan(tf.powspctrm(:))) fprintf('number of non-nans for mtmconvol method: %i\n', sum(~isnan(tf.powspctrm(:))))


Joscha Schmiedt - 2013-11-05 19:18:47 +0100

It seems to be enough if one value in the first channel is NaN. This has been tested with ft_freqanalysis 8625 2013-10-23 09:50:42Z roevdmei


Robert Oostenveld - 2014-10-07 12:36:27 +0200

(In reply to Joscha Schmiedt from comment #1) Given the increased support in artefact handling allowing the channel value to be represented as nan in case the channel is bad, this is bad. Looking at the low-level code, these seem to be OK fat = squeeze(ft_specest_mtmfft(data.trial{1}, data.time{1}, 'taper', 'hanning')) fat = squeeze(ft_specest_mtmconvol(data.trial{1}, data.time{1}, 'taper', 'hanning', 'timwin', 0.5))


Robert Oostenveld - 2014-10-07 12:51:13 +0200

the problem is with line 598 in ft_freqanalysis, where acttboi = squeeze(~isnan(spectrum(1,1,foiind(ifoi),:))); it looks at the first channel to (I guess) determine time bins of interest.


Robert Oostenveld - 2014-10-07 13:00:58 +0200

I changed the code, rather than looking at the first channel, it now uses all(isnan(..)) mac011> svn commit test/test_bug2364.m ft_freqanalysis.m Sending ft_freqanalysis.m Adding test/test_bug2364.m Transmitting file data .. Committed revision 9883.


Jim Herring - 2014-11-10 13:29:17 +0100

As discussed with Robert during lunch, this fix now results in single-channel data (e.g. virtual channel data) to result in nans as reported by various users.


Robert Oostenveld - 2014-11-10 14:30:52 +0100

data1 = []; data1.label = {'1'}; data1.time = {(1:1000)/1000} data1.trial = {randn(1,1000)} data2 = []; data2.label = {'1', '2'}; data2.time = {(1:1000)/1000} data2.trial = {randn(2,1000)} data2.trial{1}(1,:) = data1.trial{1}; cfg = []; cfg.method = 'wavelet'; cfg.width = 2; cfg.foilim = [10 50]; cfg.toi = 0:0.01:2 tf1 = ft_freqanalysis(cfg, data1); tf2 = ft_freqanalysis(cfg, data2); assert(isequal(tf1.powspctrm(1,:,:), tf2.powspctrm(1,:,:))) confirms the problem.


Robert Oostenveld - 2014-11-10 14:45:50 +0100

(In reply to Robert Oostenveld from comment #6) in ft_freqanalysis there is at line 602 now this acttboi = ~all(isnan(squeeze(spectrum(1,:,foiind(ifoi),:))), 1); which prior to change 9883 used to be acttboi = squeeze(~isnan(spectrum(1,1,foiind(ifoi),:))); In the example I just gave, they are different. However, I don't understand what the code is doing (yet).


Robert Oostenveld - 2014-11-10 14:48:49 +0100

... but it is clear that the problem is in the squeeze K>> size(spectrum(1,:,foiind(ifoi),:)) ans = 1 1 1 101 K>> size(squeeze(spectrum(1,:,foiind(ifoi),:))) ans = 101 1 Here with nchan>1 the first dimension would map onto channels after the squeeze. I have to go now, will pick this up later.


Jim Herring - 2014-11-10 15:11:49 +0100

Perhaps something like the following is more appropriate: temp = size(spectrum(1,:,foiind(ifoi),:)); spectrum = reshape(spectrum(1,:,foiind(ifoi),:),temp(2),temp(4)); as we wish to squeeze out the first and third dimension, while keeping the 2nd and 4th.


Jim Herring - 2014-11-12 16:05:48 +0100

The following works but there might be a more elegant solution: temp = size(spectrum(1,:,foiind(ifoi),:)); acttboi = ~all(isnan(reshape(spectrum(1,:,foiind(ifoi),:),temp(2),temp(4))), 1); nacttboi = sum(acttboi);


Robert Oostenveld - 2014-11-13 13:32:44 +0100

this fixes the regression error, keeping the fix for the first issue intact. mac011> svn commit specest/ft_specest_wavelet.m ft_freqanalysis.m test/ Sending ft_freqanalysis.m Sending specest/ft_specest_wavelet.m Sending test/test_bug2364.m Transmitting file data ... Committed revision 9963.


Robert Oostenveld - 2014-12-10 18:00:14 +0100

*** Bug 2757 has been marked as a duplicate of this bug. ***


Robert Oostenveld - 2014-12-10 18:01:17 +0100

I just noticed single channel mtmfft to fail. Fs = 1000; time = (1:Fs)/Fs; signal = randn(size(time)); data = []; data.time{1} = time; data.trial{1} = signal; data.label = 'A1'; cfg = []; cfg.taper = 'boxcar'; cfg.method = 'mtmfft'; cfg.foilim = [0 500]; freq = ft_freqanalysis(cfg, data); Error using reshape To RESHAPE the number of elements must not change. Error in ft_freqanalysis (line 649) powspctrm(:,ifoi,acttboi) = powspctrm(:,ifoi,acttboi) + (reshape(mean(powdum,1),[nchan 1 nacttboi]) ./ ntrials);


Robert Oostenveld - 2014-12-10 18:04:36 +0100

sorry, my bad. It turned out that the error was due to data.label = 'A1'; rather than data.label = {'A1'}; causing a channel count mismatch.


Robert Oostenveld - 2015-02-11 10:40:47 +0100

Closed several bugs that were recently resolved. Please reopen if you are not happy with the resolution.