Back to the main page.
Bug 2653 - ft_preprocessing returns NaNs if bsfilter is combined with precision = 'single'
Status | CLOSED FIXED |
Reported | 2014-07-16 18:00:00 +0200 |
Modified | 2015-02-11 10:40:18 +0100 |
Product: | FieldTrip |
Component: | core |
Version: | unspecified |
Hardware: | Macintosh |
Operating System: | Mac OS |
Importance: | P5 minor |
Assigned to: | Robert Oostenveld |
URL: | |
Tags: | |
Depends on: | |
Blocks: | |
See also: |
Anne Urai - 2014-07-16 18:00:27 +0200
If, in calling ft_preprocessing, cfg.precision = 'single' and cfg.bsfilter = 'yes', the output contains only NaNs in data.trial. This was not the case in older versions of FieldTrip, and might have something to do with a lower-level Matlab function. No warning is output, so it took me a while to figure this out. Would be great if a warning was given, or even the script aborted, if those two input arguments are used together. Thanks!
Robert Oostenveld - 2014-07-17 09:38:59 +0200
Hi Anne, thanks for reporting. I can reproduce it with: ---- data1 = []; data1.trial{1} = randn(2,10000); data1.time{1} = (1:10000)/1000; data1.label = {'1';'2'}; cfg = []; cfg.precision = 'single'; cfg.bsfilter = 'yes'; cfg.bsfreq = [40 60]; data2 = ft_preprocessing(cfg, data1); cfg = []; cfg.bsfilter = 'yes'; cfg.bsfreq = [40 60]; data3 = ft_preprocessing(cfg, data2); ---- In data2 it is still file, I guess because the conversion to single is done after filtering. The data3 contains nans, which I suppose is because the filter function cannot deal with single precision. I traced it down to filter_with_correction, which is called in ft_preproc_bandpassfilter. This then in turn calls fieldtrip/external/signal/filtfilt.m. This is a drop-in replacement function for the Mathworks signal processing toolbox, i.e. it allows to filter independent of that toolbox being present. If I remove the external/signal toolbox, I get this: >> rmpath /Users/roboos/matlab/fieldtrip/external/signal >> data3 = ft_preprocessing(cfg, data2); preprocessing 73 [nchans, nsamples] = size(dat); Error using filtfilt (line 81) Input arguments must be 'double'. Error in filtfilt (line 81) error(message('signal:filtfilt:NotSupported')); Error in filter_with_correction (line 63) filt = filtfilt(B, A, dat')'; Error in ft_preproc_bandstopfilter (line 268) filt = filter_with_correction(B,A,dat,dir); Error in preproc (line 330) dat = ft_preproc_bandstopfilter(dat, fsample, cfg.bsfreq(i,:), cfg.bsfiltord, cfg.bsfilttype, cfg.bsfiltdir, cfg.bsinstabilityfix, cfg.bsfiltdf, cfg.bsfiltwintype, cfg.bsfiltdev, cfg.plotfiltresp); Error in ft_preprocessing (line 355) [dataout.trial{i}, dataout.label, dataout.time{i}, cfg] = preproc(data.trial{i}(rawindx,:), data.label(rawindx), data.time{i}, cfg, begpadding, endpadding); ---- So the Mathworks version simply refuses to work on single precision data, whereas the drop-in replacement does allow it and fails numerically. I suggest we solve this by changing all ft_preproc_xxxfilter functions so that they always work with double precision. This is also done in ft_spectest_mtmfft, where at the end there is function [tap] = double_dpss(a, b, varargin) tap = dpss(double(a), double(b), varargin{:}); Here we could do something similar.
Robert Oostenveld - 2014-07-17 09:45:42 +0200
(In reply to Robert Oostenveld from comment #1) mac011> svn commit preproc/ Sending preproc/private/filter_with_correction.m Transmitting file data . Committed revision 9738. It now works.