Back to the main page.

Bug 2834 - ft_selectdata/ft_sourceanalysis handling of .crsspctrm when channels have been subselected

Status CLOSED FIXED
Reported 2015-02-10 18:16:00 +0100
Modified 2016-01-15 09:37:58 +0100
Product: FieldTrip
Component: core
Version: unspecified
Hardware: PC
Operating System: Linux
Importance: P5 normal
Assigned to: Jan-Mathijs Schoffelen
URL:
Tags:
Depends on:
Blocks:
See also:

Jens Klinzing - 2015-02-10 18:16:38 +0100

If ft_selectdata is used on frequency-domain data that include a cross-spectral density matrix (data.crsspctrm), a selection of a subset of channels (cfg.channel) will not touch data.crsspctrm. This can lead to problems later eg. if the resulting data is passed to ft_sourceanalysis which does not check for the consistency of channels and data.crsspctrm. Example Code: % Lets say 'tfr' has 275 channels but from looking at the data I % realize that two channels are broken and i want to continue without them. cfg = []; cfg.channel = {'MEG', '-MLF21','-MRO52'}; tfr_sel = ft_selectdata(cfg,tfr); cfg = []; cfg.frequency = 14; cfg.channel = {'MEG', '-MLF21','-MRO52'}; cfg.method = 'dics'; cfg.vol = headmodel; cfg.grid.resolution = 1; source = ft_sourceanalysis(cfg, tfr_sel); This will lead to the following error: Error using svd Input to SVD must not contain NaN or Inf. Error in rank (line 15) s = svd(A); Error in beamformer_dics (line 193) isrankdeficient = (rank(Cf)<size(Cf,1)); Error in ft_sourceanalysis (line 615) dip(i) = beamformer_dics(grid, sens, vol, [], squeeze(Cf(i,:,:)), optarg{:}); The reason is that in ft_sourceanalysis, the function 'prepare_freq_matrices' is called on the data (eg. in line 464) and will return 'Cf' that will include NaNs. The subsequent SVD cannot be performed on data containing NaNs. This could be fixed in ft_selectdata by deleting all rows in data.crsspctrm that relate to removed channels (= rows in data.labelcmb that contain these channel names). Additionally one could check in ft_sourceanalysis whether the number of channels is consistent with the field .crsspctrm. That field should have (numel(tfr.label)^2-numel(tfr.label))/2 columns. The problem should occur on every system but here I used a Linux 64-bit system running Matlab 2013b and today's fieldtrip version.


Jan-Mathijs Schoffelen - 2015-02-11 16:39:14 +0100

Hi Jens, Thanks for the report. I will look into it.


Jan-Mathijs Schoffelen - 2015-02-11 17:03:28 +0100

OK, intermediate update: ft_selectdata supports cfg.channelcmb, so if you're capable to generate the appropriate list, you should be on track :-). However, I can imagine that this is kind of to be expected behavior, in that ft_selectdata with a cfg.channel and with input data that contains both powspctrm and crsspctrm it should also give back a subset of the channelcombinations. So this should work: cfg.channel = ft_channelselection(cfg.channel, freq.label); tmp = repmat(cfg.channel,[1 numel(cfg.channel)]); tmp2 = tmp2'; cfg.channelcmb = [tmp(tril(ones(numel(cfg.channel),1),-1)>0) tmp2(tril(ones(numel(cfg.channel),1),-1)>0)]; freq2 = ft_selectdata(cfg, freq); I will think of a way to implement this more elegantly into ft_selectdata


Jan-Mathijs Schoffelen - 2015-02-11 17:28:16 +0100

[jansch@mentat003 utilities]$ svn diff ft_selectdata.m Index: ft_selectdata.m =================================================================== --- ft_selectdata.m (revision 10210) +++ ft_selectdata.m (working copy) @@ -597,7 +597,7 @@ % str2 = sprintf('mean(%s)', str2); data.label = {str1, str2}; elseif all(isfinite(selchancmb)) - data.labelcmb = data.labelcmb(selchancmb); + data.labelcmb = data.labelcmb(selchancmb,:); elseif numel(selchancmb)==1 && any(~isfinite(selchancmb)) % do nothing elseif numel(selchancmb)>1 && any(~isfinite(selchancmb)) [jansch@mentat003 utilities]$ svn commit -m "bugfix - corrected issue with selection of channelcmb" ft_selectdata.m Sending ft_selectdata.m Transmitting file data . Committed revision 10211.


Jan-Mathijs Schoffelen - 2015-09-15 16:03:36 +0200

I have changed the handling of the data within ft_sourceanalysis (using a revamped version of prepare_freq_matrices): I am not sure whether this would solve the problem, but I suggest to close this one for now, with the option to re-open if the need arises.