[FieldTrip] PLV analysis clarification

jan-mathijs schoffelen jan.schoffelen at donders.ru.nl
Wed Mar 16 09:25:03 CET 2011


Dear Matt,

As usual, thanks for your detailed report (although one also shouldn't  
exaggerate ;o) ).
Reading your mail and attachment, it seems there are several features/ 
problems in the code that restrict your analysis.
In the following, I pasted your script and will provide some comments

> =================================================================
> cfg_freq.method = 'wavelet';
> cfg_freq.output = 'powandcsd';
> cfg_freq.channelcmb = {'all','all'}; % 129 channels
>
> --------------------------------------
> ft_freqanalysis
> data_freq =
>         label: {129x1 cell}
>        dimord: 'chan_freq_time'
>          freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>          time: [1x33 double]
>     powspctrm: [129x9x33 double]
>      labelcmb: {8256x2 cell}
>     crsspctrm: [8256x9x33 double]
>           cfg: [1x1 struct]
>
> ft_connectivityanalysis with 'plv'
> data_conn =
>       labelcmb: {8256x2 cell}
>        dimord: 'chan_freq_time'
>     plvspctrm: [8256x9x33 double]
>          freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>          time: [1x33 double]
>           cfg: [1x1 struct]
>
> --------------------------------------
> FAILURE: can't run ft_freqgrandaverage on data_conn because there is  
> no label field

This has indeed been noted by you and posted on bugzilla. We didn't  
find time to work on it yet, but as a general remark  
ft_freqgrandaverage (and ft_timelockgrandaverage and  
ft_sourcegrandaverage) were designed to work on univariate data only,  
i.e. it fails on data which comes out of ft_connectivityanalysis. As  
such there is no other reason for it than a historical one (the  
averaging functions were there long before we started doing serious  
connectivity stuff). Of course it should be possible to combine the  
data into one structure and do statistics later on, although I guess  
the clustering in the channel dimension becomes really complicated.  
Note, also that I pointed out to you that as such ft_XXXgrandaverage  
is not mandatory before calling ft_XXXstatistics, you can also input a  
cell-array of data structures. Yet, this will not help you because  
then you probably encounter a crash later on.

SOLUTION for now: rename plvspctrm into powspctrm and create a label- 
field, e.g. by   for i =1:size(data_conn.labelcmb,1)  
data_conn.label{k} = [data_conn.labelcmb{i,1},'_',data_conn.labelcmb{i, 
2}]; end (and remove the labelcmb field)


>
> --------------------------------------
> FAILURE: can't run ft_singleplotTFR on data_conn
>
> cfg_ft.cohrefchannel = 'E3';
> cfg_ft.channel = 'E60';
> selected 1408 channels for plvspctrm
> ??? Error using ==> ft_channelselection at 72
> data with non-unique channel names is not supported
>
> Error in ==> ft_singleplotTFR at 290
> selchannel = ft_channelselection(cfg.channel, data.label);

The plotting functions keep haunting me. I thought that with my recent  
overhaul I made them somewhat more robust for plotting connectivity  
data.
It would be helpful if you create a bug out of this specific section,  
and add an attachment containing data_conn, and cfg_ft)

> --------------------------------------
> FAILURE: can't run ft_topoplotTFR on data_conn
>
> creating layout from data.elec
> creating layout for egi128 system
> selected 1408 channels for plvspctrm
> Warning: Duplicate x-y data points detected: using average of the z  
> values.
> > In griddata at 108
>   In ft_plot_topo at 146
>   In ft_topoplotER at 747
>   In ft_topoplotTFR at 116
> ??? Error using ==> griddata at 122
> Not enough unique sample points specified.
>
> Error in ==> ft_plot_topo at 146
> [Xi,Yi,Zi] = griddata(chanX', chanY, dat, xi', yi, interpmethod); %  
> interpolate the topographic data
>
> Error in ==> ft_topoplotER at 747
>      
> ft_plot_topo 
> (chanX,chanY,datavector,'interpmethod',cfg.interpolation,...
>
> Error in ==> ft_topoplotTFR at 116
> cfg=ft_topoplotER(cfg, varargin{:});
> =================================================================
> =================================================================

You requested only a single pair to be plotted (1 cohrefchannel and 1  
channel). A topography does not makes sense. FieldTrip does not detect  
this, but the low-level interpolation function starts complaining.

SOLUTION: don't call ft_topoplotTFR if you want to look at 1 TFR only,  
as specified by the cfg. In that case it should be possible to specify  
cfg.interactive = 'yes', allowing you to toggle back and forth between  
topographies and selected sensors.


> =================================================================
> cfg_freq.method = 'wavelet';
> cfg_freq.output = 'fourier'
> cfg_freq.channelcmb = {'E3','E60';'E3','E62';'E11','E60';'E11','E62'};
> cfg_freq.channel = unique(cfg_freq.channelcmb);
>
> have to set keeptapers to 'no' even though (as far as I know) there  
> are no tapers used in wavelets (see ft_freqanalysis line 313)
> cfg_freq.keeptrials = 'no';
> cfg_freq.keeptapers = 'no';
>
> --------------------------------------
> ft_freqanalysis
> data_freq =
>             label: {4x1 cell}
>            dimord: 'chan_freq_time'
>              freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>              time: [1x33 double]
>     fourierspctrm: [4x9x33 double]
>               cfg: [1x1 struct]
>
> --------------------------------------
> FAILURE: can't run ft_connectivityanalysis on data_freq because  
> there is no cumtapcnt field
>
> ??? Reference to non-existent field 'cumtapcnt'.
>
> Error in ==> ft_checkdata>fixcsd at 844
>   sumtapcnt = [0;cumsum(data.cumtapcnt(:))];
>
> Error in ==> ft_checkdata at 594
>     data = fixcsd(data, cmbrepresentation, channelcmb);
>
> Error in ==> univariate2bivariate at 29
>         data    = ft_checkdata(data, 'cmbrepresentation', 'full');
>
> Error in ==> ft_connectivityanalysis at 234
>           [data, powindx, hasrpt] = univariate2bivariate(data,  
> 'fourierspctrm', 'crsspctrm', dtype, 'cmb', cfg.channelcmb);
> =================================================================
> =================================================================

Thanks for noticing this. I never considered anybody to use the  
wavelet method before calling ft_connectivityanalysis. Why would you  
want to use it in the first place if there's mtmconvol ;o) ?

SOLUTION: Don't use wavelet (and post a bug on bugzilla stating this  
specific problem: output to waveletanalysis cannot be processed by  
ft_connectivityanalysis).

> =================================================================
> cfg_freq.method = 'mtmconvol';
> cfg_freq.output = 'powandcsd';
> cfg_freq.channelcmb = {'E3','E60';'E3','E62';'E11','E60';'E11','E62'};
> cfg_freq.channel = unique(cfg_freq.channelcmb);
>
> cfg_freq.keeptrials = 'no';
> cfg_freq.keeptapers = 'no';
> cfg_freq.taper = 'hanning';
>
> --------------------------------------
> ft_freqanalysis
> data_freq =
>         label: {4x1 cell}
>        dimord: 'chan_freq_time'
>          freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>          time: [1x33 double]
>     powspctrm: [4x9x33 double]
>      labelcmb: {4x2 cell}
>     crsspctrm: [4x9x33 double]
>     cumtapcnt: [173x9 double]
>           cfg: [1x1 struct]
>
> ft_connectivityanalysis with 'plv'
> data_conn =
>      labelcmb: {4x2 cell}
>        dimord: 'chan_freq_time'
>     plvspctrm: [4x9x33 double]
>          freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>          time: [1x33 double]
>           cfg: [1x1 struct]
> --------------------------------------
> FAILURE: can't run ft_freqgrandaverage on data_conn because there is  
> no label field
>

See above.

> --------------------------------------
> SUCCESS: ft_singleplotTFR successfully makes a plot
>

Hurrah


> --------------------------------------
> FAILURE: can't run ft_freqstatistics on data_conn because there's no  
> label field
>
> ??? Reference to non-existent field 'label'.
>
> Error in ==> prepare_timefreq_data>forcedimord at 509
>   output.label  = input.label;
>
> Error in ==> prepare_timefreq_data at 87
>   [remember{c}, hascrsspctrm] = forcedimord(varargin{c});
>
> Error in ==> statistics_wrapper at 217
>   [cfg, data] = prepare_timefreq_data(cfg, varargin{:});
>
> Error in ==> ft_freqstatistics at 127
> [stat, cfg] = statistics_wrapper(cfg, varargin{:});
> =================================================================
> =================================================================


See above

> =================================================================
> cfg_freq.method = 'mtmconvol';
> cfg_freq.output = 'fourier';
> cfg_freq.channelcmb = {'E3','E60';'E3','E62';'E11','E60';'E11','E62'};
> cfg_freq.channel = unique(cfg_freq.channelcmb);
>
> cfg_freq.keeptrials = 'no';
> cfg_freq.keeptapers = 'no';
> cfg_freq.taper = 'hanning';
>
> --------------------------------------
> ft_freqanalysis
> data_freq =
>             label: {4x1 cell}
>            dimord: 'chan_freq_time'
>              freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>              time: [1x33 double]
>     fourierspctrm: [4x9x33 double]
>         cumtapcnt: [173x9 double]
>               cfg: [1x1 struct]
>
> --------------------------------------
> FAILURE: can't run ft_connectivityanalysis on data_freq
>
> ??? Subscripted assignment dimension mismatch.
>
> Error in ==> ft_checkdata>fixcsd at 851
>         crsspctrm(p,:,:,m,k) = (tmpdat*tmpdat')./data.cumtapcnt(p);
>
> Error in ==> ft_checkdata at 594
>     data = fixcsd(data, cmbrepresentation, channelcmb);
>
> Error in ==> univariate2bivariate at 29
>         data    = ft_checkdata(data, 'cmbrepresentation', 'full');
>
> Error in ==> ft_connectivityanalysis at 234
>           [data, powindx, hasrpt] = univariate2bivariate(data,  
> 'fourierspctrm', 'crsspctrm', dtype, 'cmb', cfg.channelcmb);
> =================================================================

This seems to be a bug in ft_freqanalysis. It should be very forbidden  
to run ft_freqanalysis with cfg.keeptrials = 'no' and cfg.output =  
'fourier'. Just doesn't make sense. Could  you file this as a bug  
please?


> =================================================================
> =================================================================
> cfg_freq.method = 'mtmconvol';
> cfg_freq.output = 'fourier';
> cfg_freq.channelcmb = {'E3','E60';'E3','E62';'E11','E60';'E11','E62'};
> cfg_freq.channel = unique(cfg_freq.channelcmb);
>
> cfg_freq.keeptrials = 'yes';
> cfg_freq.keeptapers = 'yes';
> cfg_freq.taper = 'hanning';
>
> --------------------------------------
> ft_freqanalysis
> data_freq =
>             label: {4x1 cell}
>            dimord: 'rpttap_chan_freq_time'
>              freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>              time: [1x33 double]
>     fourierspctrm: [4-D double]
>         cumtapcnt: [173x9 double]
>               cfg: [1x1 struct]
>
> ft_connectivityanalysis with 'plv'
> data_conn =
>         label: {4x1 cell}
>        dimord: 'chan_chan_freq_time'
>     plvspctrm: [4-D double]
>          freq: [2.9630 3.7037 4.4444 5.1852 5.9259 6.6667 7.4074  
> 8.1481 8.8889]
>          time: [1x33 double]
>           dof: [173 173 173 173 173 173 173 173 173]
>           cfg: [1x1 struct]
>
> --------------------------------------
> FAILURE: can't run ft_freqgrandaverage on data_conn
>
> ??? Error using ==> ft_freqgrandaverage at 170
> unsupported dimord
>
> --------------------------------------
> SUCCESS: ft_singleplotTFR makes a plot
>
> --------------------------------------
> FAILURE: can't do ft_freqstatistics on data_conn because of  
> chan_chan in dimord
>
> ??? Error using ==> size
> Dimension argument must be a positive integer scalar within indexing  
> range.
>
> Error in ==> prepare_timefreq_data>forcedimord at 540
>     Nchan = size(output.dat, chandim);
>
> Error in ==> prepare_timefreq_data at 87
>   [remember{c}, hascrsspctrm] = forcedimord(varargin{c});
>
> Error in ==> statistics_wrapper at 217
>   [cfg, data] = prepare_timefreq_data(cfg, varargin{:});
>
> Error in ==> ft_freqstatistics at 127
> [stat, cfg] = statistics_wrapper(cfg, varargin{:});
>
> Error in ==> mm_ft_ttestTFR at 228
>   cfg_ana.(vs_str) = eval(sprintf('ft_freqstatistics(cfg_ft, 
> %s);',subj_str));
> =================================================================

Let's keep this one for the next time...

Best,

Jan-Mathijs



More information about the fieldtrip mailing list