diff --git a/ft_badchannel.m b/ft_badchannel.m index 49b446dcb3..6fc47b30f7 100644 --- a/ft_badchannel.m +++ b/ft_badchannel.m @@ -104,8 +104,9 @@ % check if the input data is valid for this function data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes'); -% ensure that the configuration is consistent -cfg = ft_checkconfig(cfg, 'required', 'metric'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'required', 'metric'); % ensure that the preproc specific options are located in the cfg.preproc substructure cfg = ft_checkconfig(cfg, 'createsubcfg', {'preproc'}); diff --git a/ft_badsegment.m b/ft_badsegment.m index a39b5ead8b..2cc30e74b0 100644 --- a/ft_badsegment.m +++ b/ft_badsegment.m @@ -103,8 +103,9 @@ % check if the input data is valid for this function data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes'); -% ensure that the configuration is consistent -cfg = ft_checkconfig(cfg, 'required', 'metric'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'required', 'metric'); % ensure that the preproc specific options are located in the cfg.preproc substructure cfg = ft_checkconfig(cfg, 'createsubcfg', {'preproc'}); diff --git a/ft_channelnormalise.m b/ft_channelnormalise.m index 9098ef6793..20039dca78 100644 --- a/ft_channelnormalise.m +++ b/ft_channelnormalise.m @@ -65,6 +65,15 @@ return end +% store the original datatype +dtype = ft_datatype(data); + +% check if the input data is valid for this function +data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes'); + +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.channel = ft_getopt(cfg, 'channel', 'all'); cfg.trials = ft_getopt(cfg, 'trials', 'all', 1); @@ -72,12 +81,6 @@ cfg.demean = ft_getopt(cfg, 'demean', 'yes'); cfg.method = ft_getopt(cfg, 'method', 'perchannel'); % or acrosschannel -% store original datatype -dtype = ft_datatype(data); - -% check if the input data is valid for this function -data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes'); - if ~strcmp(cfg.channel, 'all') || ~strcmp(cfg.trials, 'all') % select channels and trials of interest tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); @@ -85,6 +88,7 @@ % restore the provenance information [cfg, data] = rollback_provenance(cfg, data); end + % initialise some variables nchan = numel(data.label); ntrl = numel(data.trial); diff --git a/ft_componentanalysis.m b/ft_componentanalysis.m index 453c1dc933..4ed6af1bb0 100644 --- a/ft_componentanalysis.m +++ b/ft_componentanalysis.m @@ -185,6 +185,7 @@ data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes'); % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'forbidden', {'detrend'}); cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'predetermined mixing matrix', 'predetermined unmixing matrix'}); diff --git a/ft_connectivityanalysis.m b/ft_connectivityanalysis.m index fc8c48996f..ba3da9c4a4 100644 --- a/ft_connectivityanalysis.m +++ b/ft_connectivityanalysis.m @@ -140,6 +140,9 @@ % check if the input data is valid for this function % data = ft_checkdata(data, 'datatype', {'raw', 'timelock', 'freq', 'source'}); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.feedback = ft_getopt(cfg, 'feedback', 'none'); cfg.channel = ft_getopt(cfg, 'channel', 'all'); diff --git a/ft_connectivityplot.m b/ft_connectivityplot.m index ef69d3b04e..0091d8dd52 100644 --- a/ft_connectivityplot.m +++ b/ft_connectivityplot.m @@ -62,9 +62,10 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); -cfg = ft_checkconfig(cfg, 'renamed', {'color', 'linecolor'}); -cfg = ft_checkconfig(cfg, 'renamed', {'graphcolor', 'linecolor'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); +cfg = ft_checkconfig(cfg, 'renamed', {'color', 'linecolor'}); +cfg = ft_checkconfig(cfg, 'renamed', {'graphcolor', 'linecolor'}); % set the defaults cfg.channel = ft_getopt(cfg, 'channel', 'all'); diff --git a/ft_crossfrequencyanalysis.m b/ft_crossfrequencyanalysis.m index 47bb5f6b8b..97d040defc 100644 --- a/ft_crossfrequencyanalysis.m +++ b/ft_crossfrequencyanalysis.m @@ -12,25 +12,26 @@ % cfg.freqlow = scalar or vector, selection of frequencies for the low frequency data % cfg.freqhigh = scalar or vector, selection of frequencies for the high frequency data % -% Channel selection can be specified according to whether one wants to perform within- or +% Channel selection can be specified according to whether one wants to perform within- or % cross-channel analysis. % -% For within-channel analysis (default), one specifies only a single channel -% selection: +% For within-channel analysis (default), you should specifies only a single channel selection: % cfg.channel = cell-array with selection of channels, see FT_CHANNELSELECTION -% In this case, the "dimord" will be "chan_freqlow_freqhigh" +% In this case, the output "dimord" will be "chan_freqlow_freqhigh" % -% For cross-channel analysis, one specifies two sets: -% cfg.chanlow = cell-array with selection of channels for the phase providing channels from the +% For cross-channel analysis, you should specifies two channel selections: +% cfg.chanlow = cell-array with selection of channels for the phase providing channels from the % freqlow data argument, with wildcards allowed, see FT_CHANNELSELECTION -% cfg.chanhigh = cell-array with selection of channels for the amplitude providing channels from the +% cfg.chanhigh = cell-array with selection of channels for the amplitude providing channels from the % freqhigh data argument, with wildcards allowed, see FT_CHANNELSELECTION -% In this case, the "dimord" will be "chancmb_freqlow_freqhigh" and "label" field will be replaced with -% "labelcmb" (corresponding to the dimension "chancmb") describing the pairs of channel combinations as -% {'chanlow01' 'chanhigh01'; -% 'chanlow01' 'chanhigh02'; -% ... ; -% 'chanlow02' 'chanhigh01'; +% In this case, the output "dimord" will be "chancmb_freqlow_freqhigh" and "label" +% field will be replaced with "labelcmb" (corresponding to the dimension "chancmb") +% describing the pairs of channel combinations as +% {'chanlow01' 'chanhigh01' +% 'chanlow01' 'chanhigh02' +% ... +% 'chanlow02' 'chanhigh01' +% 'chanlow02' 'chanhigh02' % ... % } % N.B.: The order of channels corresponds to their order in the original "label" field @@ -106,6 +107,9 @@ freqlow = ft_checkdata(freqlow, 'datatype', 'freq', 'feedback', 'yes'); freqhigh = ft_checkdata(freqhigh, 'datatype', 'freq', 'feedback', 'yes'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % FIXME the below is a bit hacky but it does the trick if isfield(cfg, 'chanlow') && isfield(cfg, 'chanhigh') docrosschan = true; @@ -125,9 +129,10 @@ ft_error('you should either specify both cfg.chanlow and cfg.chanhigh, or none of these options'); end +% get the defaults cfg.freqlow = ft_getopt(cfg, 'freqlow', 'all'); cfg.freqhigh = ft_getopt(cfg, 'freqhigh', 'all'); -cfg.nphase = ft_getopt(cfg, 'nphase', 20); +cfg.nphase = ft_getopt(cfg, 'nphase', 20); cfg.keeptrials = ft_getopt(cfg, 'keeptrials'); % make selection of frequencies and channels @@ -155,7 +160,7 @@ % prepare the data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% switch cfg.method - + case 'coh' % coherence cohdatas = zeros(ntrial,nchan,numel(LF),numel(HF)); @@ -167,7 +172,7 @@ end end cfcdata = cohdatas; - + case 'plv' % phase locking value plvdatas = zeros(ntrial,nchan,numel(LF),numel(HF)); @@ -179,7 +184,7 @@ end end cfcdata = plvdatas; - + case 'mvl' % mean vector length mvldatas = zeros(ntrial,nchan,numel(LF),numel(HF)); @@ -191,7 +196,7 @@ end end cfcdata = mvldatas; - + case {'mi','pac'} % modulation index pacdatas = zeros(ntrial,nchan,numel(LF),numel(HF),cfg.nphase); @@ -203,7 +208,7 @@ end end cfcdata = pacdatas; - + end % switch method for data preparation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -211,7 +216,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% switch cfg.method - + case 'coh' [ntrial,nchan,nlf,nhf] = size(cfcdata); if strcmp(cfg.keeptrials, 'no') @@ -221,7 +226,7 @@ crsspctrm = abs(cfcdata); dimord = 'rpt_chan_freqlow_freqhigh' ; end - + case 'plv' [ntrial,nchan,nlf,nhf] = size(cfcdata); if strcmp(cfg.keeptrials, 'no') @@ -231,7 +236,7 @@ crsspctrm = abs(cfcdata); dimord = 'rpt_chan_freqlow_freqhigh' ; end - + case 'mvl' [ntrial,nchan,nlf,nhf] = size(cfcdata); if strcmp(cfg.keeptrials, 'no') @@ -241,10 +246,10 @@ crsspctrm = abs(cfcdata); dimord = 'rpt_chan_freqlow_freqhigh' ; end - + case 'mi' [ntrial,nchan,nlf,nhf,nbin] = size(cfcdata); - + if strcmp(cfg.keeptrials, 'yes') dimord = 'rpt_chan_freqlow_freqhigh' ; crsspctrm = zeros(ntrial,nchan,nlf,nhf); @@ -253,7 +258,7 @@ pac = squeeze(cfcdata(k,n,:,:,:)); Q =ones(nbin,1)/nbin; % uniform distribution mi = zeros(nlf,nhf); - + for i=1:nlf for j=1:nhf P = squeeze(pac(i,j,:))/ nansum(pac(i,j,:)); % normalized distribution @@ -262,20 +267,20 @@ end end crsspctrm(k,n,:,:) = mi; - + end end - + else dimord = 'chan_freqlow_freqhigh' ; crsspctrm = zeros(nchan,nlf,nhf); cfcdatamean = reshape(mean(cfcdata,1),[nchan nlf nhf nbin 1]); - + for k =1:nchan pac = squeeze(cfcdatamean(k,:,:,:)); Q =ones(nbin,1)/nbin; % uniform distribution mi = zeros(nlf,nhf); - + for i=1:nlf for j=1:nhf P = squeeze(pac(i,j,:))/ nansum(pac(i,j,:)); % normalized distribution @@ -285,9 +290,9 @@ end crsspctrm(k,:,:) = mi; end - + end % if keeptrials - + case 'pac' [ntrial,nchan,nlf,nhf,nbin] = size(cfcdata); @@ -299,7 +304,7 @@ dimord = 'chan_freqlow_freqhigh_phase' ; crsspctrm = reshape(mean(cfcdata,1),[nchan nlf nhf nbin 1]); crsspctrm(isnan(crsspctrm)) = 0; - + end % if keeptrials end % switch method for actual computation @@ -349,11 +354,11 @@ Nx = sum(~isnan(LFsigtemp(i,:) .* LFsigtemp(i,:))); Ny = sum(~isnan(HFsigtemp(j,:) .* HFsigtemp(j,:))); Nxy = sum(~isnan(LFsigtemp(i,:) .* HFsigtemp(j,:))); - + Px = LFsig(i,:) * ctranspose(LFsig(i,:)) ./ Nx; Py = HFsig(j,:) * ctranspose(HFsig(j,:)) ./ Ny; Cxy = LFsig(i,:) * ctranspose(HFsig(j,:)) ./ Nxy; - + cohdata(i,j) = Cxy / sqrt(Px * Py); end end diff --git a/ft_databrowser.m b/ft_databrowser.m index b993a643db..c2c1a2db81 100644 --- a/ft_databrowser.m +++ b/ft_databrowser.m @@ -162,6 +162,7 @@ hascomp = hasdata && ft_datatype(data, 'comp'); % can be 'raw+comp' or 'timelock+comp' % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'unused', {'comps', 'inputfile', 'outputfile'}); cfg = ft_checkconfig(cfg, 'renamed', {'zscale', 'ylim'}); cfg = ft_checkconfig(cfg, 'renamedval', {'ylim', 'auto', 'maxabs'}); diff --git a/ft_denoise_dssp.m b/ft_denoise_dssp.m index a585c07ccd..70e1bee920 100644 --- a/ft_denoise_dssp.m +++ b/ft_denoise_dssp.m @@ -47,20 +47,22 @@ % check the input data datain = ft_checkdata(datain, 'datatype', {'raw'}); % FIXME how about timelock and freq? -cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); - -% get the options -cfg.trials = ft_getopt(cfg, 'trials', 'all', 1); -cfg.channel = ft_getopt(cfg, 'channel', 'all'); -cfg.sourcemodel = ft_getopt(cfg, 'sourcemodel'); -cfg.dssp = ft_getopt(cfg, 'dssp'); % sub-structure to hold the parameters -cfg.dssp.n_space = ft_getopt(cfg.dssp, 'n_space', 'all'); % number of spatial components to retain from the Gram matrix -cfg.dssp.n_in = ft_getopt(cfg.dssp, 'n_in', 'all'); % dimensionality of the Bin subspace to be used for the computation of the intersection -cfg.dssp.n_out = ft_getopt(cfg.dssp, 'n_out', 'all'); % dimensionality of the Bout subspace to be used for the computation of the intersection -cfg.dssp.n_intersect = ft_getopt(cfg.dssp, 'n_intersect', 0.9); % dimensionality of the intersection -cfg.output = ft_getopt(cfg, 'output', 'original'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); + +% set the defaults +cfg.trials = ft_getopt(cfg, 'trials', 'all', 1); +cfg.channel = ft_getopt(cfg, 'channel', 'all'); +cfg.sourcemodel = ft_getopt(cfg, 'sourcemodel'); +cfg.dssp = ft_getopt(cfg, 'dssp'); % sub-structure to hold the parameters +cfg.dssp.n_space = ft_getopt(cfg.dssp, 'n_space', 'all'); % number of spatial components to retain from the Gram matrix +cfg.dssp.n_in = ft_getopt(cfg.dssp, 'n_in', 'all'); % dimensionality of the Bin subspace to be used for the computation of the intersection +cfg.dssp.n_out = ft_getopt(cfg.dssp, 'n_out', 'all'); % dimensionality of the Bout subspace to be used for the computation of the intersection +cfg.dssp.n_intersect = ft_getopt(cfg.dssp, 'n_intersect', 0.9); % dimensionality of the intersection +cfg.output = ft_getopt(cfg, 'output', 'original'); % select channels and trials of interest, by default this will select all channels and trials tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); diff --git a/ft_denoise_pca.m b/ft_denoise_pca.m index 3194faf58b..dab0e3a86e 100644 --- a/ft_denoise_pca.m +++ b/ft_denoise_pca.m @@ -81,6 +81,9 @@ varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'raw'); end +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.refchannel = ft_getopt(cfg, 'refchannel', 'MEGREF'); cfg.channel = ft_getopt(cfg, 'channel', 'MEG'); @@ -91,7 +94,6 @@ cfg.feedback = ft_getopt(cfg, 'feedback', 'none'); cfg.updatesens = ft_getopt(cfg, 'updatesens', 'yes'); - if istrue(cfg.pertrial) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % iterate over trials diff --git a/ft_denoise_prewhiten.m b/ft_denoise_prewhiten.m index a741e88ce2..1d3e803518 100644 --- a/ft_denoise_prewhiten.m +++ b/ft_denoise_prewhiten.m @@ -62,13 +62,20 @@ return end -% get the defaults -cfg.channel = ft_getopt(cfg, 'channel', 'all'); -cfg.split = ft_getopt(cfg, 'split', 'all'); -cfg.lambda = ft_getopt(cfg, 'lambda', 0); -cfg.kappa = ft_getopt(cfg, 'kappa', []); -cfg.tol = ft_getopt(cfg, 'tol', []); -cfg.realflag = ft_getopt(cfg, 'realflag', true); % for complex-valued crsspctrm +% check if the input data is valid for this function +datain = ft_checkdata(datain, 'datatype', {'raw' 'timelock' 'freq'}, 'haschantype', 'yes', 'haschanunit', 'yes'); +noise = ft_checkdata(noise, 'datatype', { 'timelock' 'freq'}, 'haschantype', 'yes', 'haschanunit', 'yes'); + +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + +% set the defaults +cfg.channel = ft_getopt(cfg, 'channel', 'all'); +cfg.split = ft_getopt(cfg, 'split', 'all'); +cfg.lambda = ft_getopt(cfg, 'lambda', 0); +cfg.kappa = ft_getopt(cfg, 'kappa', []); +cfg.tol = ft_getopt(cfg, 'tol', []); +cfg.realflag = ft_getopt(cfg, 'realflag', true); % for complex-valued crsspctrm cfg.invmethod = ft_getopt(cfg, 'invmethod', 'tikhonov'); % ensure that the input data is correct, the next line is needed for a @@ -76,9 +83,6 @@ % for meggrad data) if isfield(datain, 'hdr'), datain = rmfield(datain, 'hdr'); end -datain = ft_checkdata(datain, 'datatype', {'raw' 'timelock' 'freq'}, 'haschantype', 'yes', 'haschanunit', 'yes'); -noise = ft_checkdata(noise, 'datatype', { 'timelock' 'freq'}, 'haschantype', 'yes', 'haschanunit', 'yes'); - dtype_datain = ft_datatype(datain); % check for allowed input combinations @@ -89,13 +93,14 @@ assert(ft_datatype(noise, 'timelock'), 'noise data should be of datatype ''timelock'''); case 'freq' if ft_datatype(noise, 'freq') - % this is only allowed if both structures have the same singleton - % frequency - assert(numel(noise.freq==1) && numel(datain.freq==1) && isequal(noise.freq,datain.freq), ... + % this is only allowed if both structures have the same singleton frequency + assert(numel(noise.freq)==1 && numel(datain.freq)==1 && isequal(noise.freq,datain.freq), ... 'with both datain and noise of datatype ''freq'', only singleton and equal frequency bins are allowed'); elseif ft_datatype(noise, 'timelock') % this is OK end + otherwise + ft_error('unsupported input data'); end % select channels and trials of interest, by default this will select all channels and trials @@ -153,7 +158,7 @@ tra(sel,sel) = U(:,selS)*diag(sqrt(diagS(selS)))*U(:,selS)'; end %invnoise = ft_inv(noisecov, 'lambda', cfg.lambda, 'kappa', cfg.kappa, 'tolerance', cfg.tol, 'method', cfg.invmethod); - + else % invert the noise covariance matrix invnoise = ft_inv(noisecov, 'lambda', cfg.lambda, 'kappa', cfg.kappa, 'tolerance', cfg.tol, 'method', cfg.invmethod); @@ -162,12 +167,12 @@ %sel = diagS./diagS(1)>1e-12; sel = 1:rank(invnoise); - % the prewhitening projection first rotates to orthogonal channels, % then scales, and then rotates the channels back to (more or less) % their original MEG-channel representation tra = U(:,sel)*diag(sqrt(diagS(sel)))*U(:,sel)'; end + prewhiten = []; prewhiten.tra = tra; prewhiten.labelold = noise.label; diff --git a/ft_denoise_tsr.m b/ft_denoise_tsr.m index 50a026acff..06ab9ef5eb 100644 --- a/ft_denoise_tsr.m +++ b/ft_denoise_tsr.m @@ -113,6 +113,10 @@ varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'raw'); end +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + +% set the defaults cfg.nfold = ft_getopt(cfg, 'nfold', 1); cfg.blocklength = ft_getopt(cfg, 'blocklength', 'trial'); cfg.testtrials = ft_getopt(cfg, 'testtrials', 'all'); diff --git a/ft_detect_movement.m b/ft_detect_movement.m index e738199e8b..03822a12a6 100644 --- a/ft_detect_movement.m +++ b/ft_detect_movement.m @@ -89,16 +89,19 @@ % read from an old *.mat file data = ft_checkdata(data, 'datatype', {'raw'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + +% set the defaults +cfg.method = ft_getopt(cfg, 'method', 'velocity2D'); +cfg.feedback = ft_getopt(cfg, 'feedback', 'yes'); + if isfield(data, 'fsample') fsample = getsubfield(data, 'fsample'); else fsample = 1./(mean(diff(data.time{1}))); end -% set the defaults -cfg.method = ft_getopt(cfg, 'method', 'velocity2D'); -cfg.feedback = ft_getopt(cfg, 'feedback', 'yes'); - % set the defaults for the various microsaccade detection methods switch cfg.method case 'velocity2D' @@ -115,7 +118,7 @@ % Unsupervised clustering method to detect microsaccades. J Vis 14. otherwise ft_error('unsupported option for cfg.method'); -end +end % switch method % select channels and trials of interest, by default this will select all channels and trials tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); @@ -203,9 +206,14 @@ end case 'clustering' - % not implemented yet - end -end + ft_error('not implemented yet'); + % Otero-Millan J, Castro JLA, Macknik SL, Martinez-Conde S (2014) + % Unsupervised clustering method to detect microsaccades. J Vis 14. + + otherwise + ft_error('unsupported option for cfg.method'); + end % switch method +end % for each trial ft_progress('close'); ft_postamble trackconfig diff --git a/ft_dipolefitting.m b/ft_dipolefitting.m index 200bf4288d..b9e984a278 100644 --- a/ft_dipolefitting.m +++ b/ft_dipolefitting.m @@ -147,26 +147,27 @@ data = ft_checkdata(data, 'datatype', {'comp', 'timelock', 'freq'}, 'feedback', 'yes'); % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); -cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); -cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); -cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); +cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); +cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); % get the defaults cfg.channel = ft_getopt(cfg, 'channel', 'all'); -cfg.component = ft_getopt(cfg, 'component', 'all'); % for comp input -cfg.frequency = ft_getopt(cfg, 'frequency'); % for freq input -cfg.latency = ft_getopt(cfg, 'latency', 'all'); % for timeclock input +cfg.component = ft_getopt(cfg, 'component', 'all'); % for comp input +cfg.frequency = ft_getopt(cfg, 'frequency'); % for freq input +cfg.latency = ft_getopt(cfg, 'latency', 'all'); % for timelock input cfg.feedback = ft_getopt(cfg, 'feedback', 'text'); cfg.gridsearch = ft_getopt(cfg, 'gridsearch', 'yes'); cfg.nonlinear = ft_getopt(cfg, 'nonlinear', 'yes'); cfg.symmetry = ft_getopt(cfg, 'symmetry'); cfg.dipfit = ft_getopt(cfg, 'dipfit', []); % the default for this is handled below -cfg = ft_checkconfig(cfg, 'renamed', {'tightgrid', 'tight'}); % this is moved to cfg.sourcemodel.tight by the subsequent createsubcfg -cfg = ft_checkconfig(cfg, 'renamed', {'sourceunits', 'unit'}); % this is moved to cfg.sourcemodel.unit by the subsequent createsubcfg +cfg = ft_checkconfig(cfg, 'renamed', {'tightgrid', 'tight'}); % this is moved to cfg.sourcemodel.tight by the subsequent createsubcfg +cfg = ft_checkconfig(cfg, 'renamed', {'sourceunits', 'unit'}); % this is moved to cfg.sourcemodel.unit by the subsequent createsubcfg % put the low-level options pertaining to the sourcemodel in their own field cfg = ft_checkconfig(cfg, 'createsubcfg', {'sourcemodel'}); diff --git a/ft_dipolesimulation.m b/ft_dipolesimulation.m index 8308a45f66..d579d3619e 100644 --- a/ft_dipolesimulation.m +++ b/ft_dipolesimulation.m @@ -100,11 +100,12 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); -cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); -cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); -cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); +cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); +cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); % for consistency with FT_TIMELOCKSIMULUATION and FT_FREQSIMULATION cfg = ft_checkconfig(cfg, 'createsubcfg', 'dip'); diff --git a/ft_electrodeplacement.m b/ft_electrodeplacement.m index d46d630cbf..a38f6a9193 100644 --- a/ft_electrodeplacement.m +++ b/ft_electrodeplacement.m @@ -132,9 +132,12 @@ % ensure that old and unsupported options are not being relied on by the end-user's script % see http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=2837 -cfg = ft_checkconfig(cfg, 'renamed', {'viewdim', 'axisratio'}); + +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'viewdim', 'axisratio'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'mri', 'volume'}); -cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); +cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); % set the defaults cfg.method = ft_getopt(cfg, 'method'); % volume, headshape, 1020, shaft @@ -1834,4 +1837,3 @@ function cb_scanbutton(hscan, eventdata) setappdata(h, 'opt', opt); cb_redraw(h); - diff --git a/ft_electroderealign.m b/ft_electroderealign.m index 16559d9fb0..134b21667b 100644 --- a/ft_electroderealign.m +++ b/ft_electroderealign.m @@ -172,12 +172,13 @@ end % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'outline'}); cfg = ft_checkconfig(cfg, 'renamed', {'template', 'target'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'realignfiducials', 'fiducial'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'realignfiducial', 'fiducial'}); cfg = ft_checkconfig(cfg, 'renamedval', {'warp', 'homogenous', 'rigidbody'}); cfg = ft_checkconfig(cfg, 'renamedval', {'warp', 'homogeneous', 'rigidbody'}); -cfg = ft_checkconfig(cfg, 'forbidden', 'outline'); % set the defaults cfg.warp = ft_getopt(cfg, 'warp', 'rigidbody'); diff --git a/ft_electrodermalactivity.m b/ft_electrodermalactivity.m index 8161708c1e..11c0a06c98 100644 --- a/ft_electrodermalactivity.m +++ b/ft_electrodermalactivity.m @@ -70,6 +70,9 @@ % check if the input data is valid for this function, the input data must be raw datain = ft_checkdata(datain, 'datatype', 'raw', 'feedback', 'yes'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the default options cfg.channel = ft_getopt(cfg, 'channel', {}); cfg.feedback = ft_getopt(cfg, 'feedback', 'yes'); diff --git a/ft_eventtiminganalysis.m b/ft_eventtiminganalysis.m index f60195e4ae..b02503026f 100644 --- a/ft_eventtiminganalysis.m +++ b/ft_eventtiminganalysis.m @@ -114,17 +114,22 @@ % ensure that the input data is valid for this function data = ft_checkdata(data, 'datatype', {'raw+comp', 'raw'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); -% ensure that the required options are present -cfg = ft_checkconfig(cfg, 'required', {'method'}); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'required', {'method'}); + +% set the defaults cfg.trials = ft_getopt(cfg, 'trials', 'all', 1); % all trials as default cfg.channel = ft_getopt(cfg, 'channel', 'all'); cfg.output = ft_getopt(cfg, 'output', 'model'); + % ensure that the options are valid cfg = ft_checkopt(cfg, 'method', 'char', {'aseo' 'gbve'}); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % the actual computation is done in the middle part %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % select trials of interest tmpcfg = keepfields(cfg, {'trials' 'channel' 'showcallinfo'}); data = ft_selectdata(tmpcfg, data); @@ -141,7 +146,7 @@ fsample = data.fsample; % Sampling Frequency in Hz nchan = numel(data.label); nsample = numel(data.time{1}); %FIXME ASSUMING FIXED TIME AXIS ACROSS ALL TRIALS - + % setting a bunch of options, to be passed on to the lower level function if ~isfield(cfg, 'aseo'), cfg.aseo = []; end cfg.aseo.thresholdAmpH = ft_getopt(cfg.aseo, 'thresholdAmpH', 0.5); @@ -159,14 +164,14 @@ initlatency = ft_getopt(cfg.aseo, 'initlatency', {}); initcomp = ft_getopt(cfg.aseo, 'initcomp', {}); jitter = ft_getopt(cfg.aseo, 'jitter', 0.050); % half temporal width of shift in s - + if isempty(initlatency) && isempty(initcomp) ft_error('for the ASEO method you should supply either an initial estimate of the waveform component, or a set of latencies'); elseif ~isempty(initlatency) % this takes precedence, and should contain per channel the begin and % end points of the subwindows in time, based on which the initial % subcomponents are estimated - + % ensure it to be a cell-array if the input is a matrix if ~iscell(initlatency) initlatency = repmat({initlatency},[1 nchan]); @@ -188,7 +193,7 @@ chandat = cat(1,tmp{:}); chandat = ft_preproc_baselinecorrect(chandat, nearest(data.time{1}, -inf), nearest(data.time{1}, 0)); avgdat = nanmean(chandat, 1); - + % set the initial ERP waveforms according to the preset parameters ncomp = size(initlatency{k},1); initcomp{k} = zeros(nsample, ncomp); @@ -197,7 +202,7 @@ endsmp = nearest(data.time{1},initlatency{k}(m, 2)); if begsmp<1, begsmp = 1; end if endsmp>nsample, endsmp = nsample; end - + tmp = avgdat(begsmp:endsmp)'; initcomp{k}(begsmp:endsmp, m) = tmp; end @@ -222,7 +227,7 @@ for k = 1:numel(data.trial) dataout.trial{k}(:) = nan; end - + % initialize the struct that will contain the output parameters params = struct([]); @@ -231,7 +236,7 @@ % preprocessing data tmp = cellrowselect(data.trial,k); chandat = cat(1,tmp{:}); - + % baseline correction chandat = ft_preproc_baselinecorrect(chandat, nearest(data.time{1}, -inf), nearest(data.time{1}, 0)); @@ -262,125 +267,128 @@ end end -case 'gbve' - ft_hastoolbox('lagextraction', 1); - ft_hastoolbox('eeglab', 1); % because the low-level code might use a specific moving average function from EEGLAB - ft_hastoolbox('cellfunction', 1); - - if ~isfield(cfg, 'gbve'), cfg.gbve = []; end - cfg.gbve.NORMALIZE_DATA = ft_getopt(cfg.gbve, 'NORMALIZE_DATA', true); - cfg.gbve.CENTER_DATA = ft_getopt(cfg.gbve, 'CENTER_DATA', false); - cfg.gbve.USE_ADAPTIVE_SIGMA= ft_getopt(cfg.gbve, 'USE_ADAPTIVE_SIGMA', false); - cfg.gbve.sigma = ft_getopt(cfg.gbve, 'sigma', 0.01:0.01:0.2); - cfg.gbve.distance = ft_getopt(cfg.gbve, 'distance', 'corr2'); - cfg.gbve.alpha = ft_getopt(cfg.gbve, 'alpha', [0 0.001 0.01 0.1]); - cfg.gbve.exponent = ft_getopt(cfg.gbve, 'exponent', 1); - cfg.gbve.use_maximum = ft_getopt(cfg.gbve, 'use_maximum', 1); % consider the positive going peak - cfg.gbve.show_pca = ft_getopt(cfg.gbve, 'show_pca', false); - cfg.gbve.show_trial_number = ft_getopt(cfg.gbve, 'show_trial_number', false); - cfg.gbve.verbose = ft_getopt(cfg.gbve, 'verbose', true); - cfg.gbve.disp_log = ft_getopt(cfg.gbve, 'disp_log', false); - cfg.gbve.latency = ft_getopt(cfg.gbve, 'latency', [-inf inf]); - cfg.gbve.xwin = ft_getopt(cfg.gbve, 'xwin', 1); % default is a bit of smoothing - cfg.gbve.nfold = ft_getopt(cfg.gbve, 'nfold', 5); - - nchan = numel(data.label); - ntrl = numel(data.trial); - - tmin = nearest(data.time{1}, cfg.gbve.latency(1)); - tmax = nearest(data.time{1}, cfg.gbve.latency(2)); - - % initialize the struct that will contain the output parameters - dataout = removefields(data, 'cfg'); - params = struct([]); - for k = 1:nchan - % preprocessing data - options = cfg.gbve; - - fprintf('--- Processing channel %d\n',k); + case 'gbve' + ft_hastoolbox('lagextraction', 1); + ft_hastoolbox('eeglab', 1); % because the low-level code might use a specific moving average function from EEGLAB + ft_hastoolbox('cellfunction', 1); - tmp = cellrowselect(data.trial,k); - chandat = cat(1,tmp{:}); - points = chandat(:,tmin:tmax); + if ~isfield(cfg, 'gbve'), cfg.gbve = []; end + cfg.gbve.NORMALIZE_DATA = ft_getopt(cfg.gbve, 'NORMALIZE_DATA', true); + cfg.gbve.CENTER_DATA = ft_getopt(cfg.gbve, 'CENTER_DATA', false); + cfg.gbve.USE_ADAPTIVE_SIGMA= ft_getopt(cfg.gbve, 'USE_ADAPTIVE_SIGMA', false); + cfg.gbve.sigma = ft_getopt(cfg.gbve, 'sigma', 0.01:0.01:0.2); + cfg.gbve.distance = ft_getopt(cfg.gbve, 'distance', 'corr2'); + cfg.gbve.alpha = ft_getopt(cfg.gbve, 'alpha', [0 0.001 0.01 0.1]); + cfg.gbve.exponent = ft_getopt(cfg.gbve, 'exponent', 1); + cfg.gbve.use_maximum = ft_getopt(cfg.gbve, 'use_maximum', 1); % consider the positive going peak + cfg.gbve.show_pca = ft_getopt(cfg.gbve, 'show_pca', false); + cfg.gbve.show_trial_number = ft_getopt(cfg.gbve, 'show_trial_number', false); + cfg.gbve.verbose = ft_getopt(cfg.gbve, 'verbose', true); + cfg.gbve.disp_log = ft_getopt(cfg.gbve, 'disp_log', false); + cfg.gbve.latency = ft_getopt(cfg.gbve, 'latency', [-inf inf]); + cfg.gbve.xwin = ft_getopt(cfg.gbve, 'xwin', 1); % default is a bit of smoothing + cfg.gbve.nfold = ft_getopt(cfg.gbve, 'nfold', 5); - % perform a loop across alpha values, cross validation - alphas = options.alpha; + nchan = numel(data.label); + ntrl = numel(data.trial); - if length(alphas) > 1 % Use Cross validation error if multiple alphas are specified - best_CVerr = -Inf; - - K = cfg.gbve.nfold; - disp(['--- Running K Cross Validation (K = ',num2str(K),')']); - - block_idx = fix(linspace(1, ntrl, K+1)); % K cross validation - for jj=1:length(alphas) - options.alpha = alphas(jj); - - CVerr = 0; - for kk = 1:K - bidx = block_idx(kk):block_idx(kk+1); - idx = 1:ntrl; - idx(bidx) = []; - - data_k = chandat(idx,:); - points_k = points(idx,:); - [order,lags] = extractlag(points_k,options); - - data_reordered = data_k(order,:); - lags = lags + tmin; - [data_aligned, ~] = perform_realign(data_reordered, data.time{1}, lags); - data_aligned(~isfinite(data_aligned)) = nan; - ep_evoked = nanmean(data_aligned); - ep_evoked = ep_evoked ./ norm(ep_evoked); - - data_k = chandat(bidx,:); - data_norm = sqrt(sum(data_k.^2,2)); - data_k = diag(1./data_norm)*data_k; - data_k(data_norm==0,:) = 0; + tmin = nearest(data.time{1}, cfg.gbve.latency(1)); + tmax = nearest(data.time{1}, cfg.gbve.latency(2)); + + % initialize the struct that will contain the output parameters + dataout = removefields(data, 'cfg'); + params = struct([]); + for k = 1:nchan + % preprocessing data + options = cfg.gbve; + + fprintf('--- Processing channel %d\n',k); + + tmp = cellrowselect(data.trial,k); + chandat = cat(1,tmp{:}); + points = chandat(:,tmin:tmax); + + % perform a loop across alpha values, cross validation + alphas = options.alpha; + + if length(alphas) > 1 % Use Cross validation error if multiple alphas are specified + best_CVerr = -Inf; + + K = cfg.gbve.nfold; + disp(['--- Running K Cross Validation (K = ',num2str(K),')']); + + block_idx = fix(linspace(1, ntrl, K+1)); % K cross validation + for jj=1:length(alphas) + options.alpha = alphas(jj); - for pp=1:length(bidx) - c = xcorr(ep_evoked,data_k(pp,:)); - CVerr = CVerr + max(c(:)); + CVerr = 0; + for kk = 1:K + bidx = block_idx(kk):block_idx(kk+1); + idx = 1:ntrl; + idx(bidx) = []; + + data_k = chandat(idx,:); + points_k = points(idx,:); + [order,lags] = extractlag(points_k,options); + + data_reordered = data_k(order,:); + lags = lags + tmin; + [data_aligned, ~] = perform_realign(data_reordered, data.time{1}, lags); + data_aligned(~isfinite(data_aligned)) = nan; + ep_evoked = nanmean(data_aligned); + ep_evoked = ep_evoked ./ norm(ep_evoked); + + data_k = chandat(bidx,:); + data_norm = sqrt(sum(data_k.^2,2)); + data_k = diag(1./data_norm)*data_k; + data_k(data_norm==0,:) = 0; + + for pp=1:length(bidx) + c = xcorr(ep_evoked,data_k(pp,:)); + CVerr = CVerr + max(c(:)); + end + end + + CVerr = CVerr/ntrl; + + if CVerr > best_CVerr + best_CVerr = CVerr; + best_alpha = alphas(jj); end end - - CVerr = CVerr/ntrl; - - if CVerr > best_CVerr - best_CVerr = CVerr; - best_alpha = alphas(jj); - end + options.alpha = best_alpha; end - options.alpha = best_alpha; - end - - if options.use_maximum - [order,lags] = extractlag( points, options ); - else - [order,lags] = extractlag( -points, options ); - end - disp(['---------- Using alpha = ',num2str(options.alpha)]); - data_reordered = chandat(order,:); - lags = lags + tmin; - [data_aligned] = perform_realign(data_reordered, data.time{1}, lags ); - data_aligned(~isfinite(data_aligned)) = nan; - - [~,order_inv] = sort(order); - lags_no_order = lags(order_inv); - data_aligned = data_aligned(order_inv,:); - params(k).latency = data.time{1}(lags_no_order)'; - switch cfg.output - case 'model' - tmp = mat2cell(data_aligned, ones(1,size(data_aligned,1)), size(data_aligned,2))'; - dataout.trial = cellrowassign(dataout.trial, tmp, k); - case 'residual' - % to be done - error('not yet implemented'); + if options.use_maximum + [order,lags] = extractlag( points, options ); + else + [order,lags] = extractlag( -points, options ); + end + disp(['---------- Using alpha = ',num2str(options.alpha)]); + data_reordered = chandat(order,:); + lags = lags + tmin; + [data_aligned] = perform_realign(data_reordered, data.time{1}, lags ); + data_aligned(~isfinite(data_aligned)) = nan; + + [~,order_inv] = sort(order); + lags_no_order = lags(order_inv); + data_aligned = data_aligned(order_inv,:); + + params(k).latency = data.time{1}(lags_no_order)'; + switch cfg.output + case 'model' + tmp = mat2cell(data_aligned, ones(1,size(data_aligned,1)), size(data_aligned,2))'; + dataout.trial = cellrowassign(dataout.trial, tmp, k); + case 'residual' + % to be done + error('not yet implemented'); + end end - end - -end + + otherwise + ft_error('unsupported method'); + +end % switch method dataout.params = params; dataout.cfg = cfg; diff --git a/ft_freqanalysis.m b/ft_freqanalysis.m index 8251a7ea02..87326c1d69 100644 --- a/ft_freqanalysis.m +++ b/ft_freqanalysis.m @@ -118,7 +118,7 @@ % % % SUPERLET performs time-frequency analysis on any time series trial data using the -% 'wavelet method' based on a frequency-wise combination of Morlet wavelets of varying cycle +% 'wavelet method' based on a frequency-wise combination of Morlet wavelets of varying cycle % widths (see Moca et al. 2019, https://doi.org/10.1101/583732). % cfg.foi = vector 1 x numfoi, frequencies of interest % OR @@ -130,9 +130,9 @@ % deviations of the implicit Gaussian kernel and should % be choosen >= 3; (default = 3) % cfg.superlet.combine = 'additive', 'multiplicative' (default = 'additive') -% determines if cycle numbers of wavelets comprising a superlet +% determines if cycle numbers of wavelets comprising a superlet % are chosen additively or multiplicatively -% cfg.superlet.order = vector 1 x numfoi, superlet order, i.e. number of combined +% cfg.superlet.order = vector 1 x numfoi, superlet order, i.e. number of combined % wavelets, for individual frequencies of interest. % % The standard deviation in the frequency domain (sf) at frequency f0 is @@ -225,27 +225,28 @@ return end -% ensure that the required options are present +% check if the input data is valid for this function +data = ft_checkdata(data, 'datatype', {'raw', 'raw+comp', 'mvar'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); + +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'label', 'channel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'sgn', 'channel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'labelcmb', 'channelcmb'}); +cfg = ft_checkconfig(cfg, 'renamed', {'sgncmb', 'channelcmb'}); +cfg = ft_checkconfig(cfg, 'required', {'method'}); +cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'fft', 'mtmfft'}); +cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'convol', 'mtmconvol'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'latency'}); % see bug 1376 and 1076 +cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'wltconvol', 'wavelet'}); + +% set the defaults cfg.feedback = ft_getopt(cfg, 'feedback', 'text'); cfg.inputlock = ft_getopt(cfg, 'inputlock', []); % this can be used as mutex when doing distributed computation cfg.outputlock = ft_getopt(cfg, 'outputlock', []); % this can be used as mutex when doing distributed computation cfg.trials = ft_getopt(cfg, 'trials', 'all', 1); cfg.channel = ft_getopt(cfg, 'channel', 'all'); -% check if the input data is valid for this function -data = ft_checkdata(data, 'datatype', {'raw', 'raw+comp', 'mvar'}, 'feedback', cfg.feedback, 'hassampleinfo', 'yes'); - -% check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'label', 'channel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'sgn', 'channel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'labelcmb', 'channelcmb'}); -cfg = ft_checkconfig(cfg, 'renamed', {'sgncmb', 'channelcmb'}); -cfg = ft_checkconfig(cfg, 'required', {'method'}); -cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'fft', 'mtmfft'}); -cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'convol', 'mtmconvol'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'latency'}); % see bug 1376 and 1076 -cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'wltconvol', 'wavelet'}); - % select channels and trials of interest, by default this will select all channels and trials tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); data = ft_selectdata(tmpcfg, data); @@ -582,7 +583,7 @@ case 'superlet' % calculate number of wavelets and respective cycle width dependent on superlet order - % equivalent one-liners: + % equivalent one-liners: % multiplicative: cycles = arrayfun(@(order) arrayfun(@(wl_num) cfg.superlet.basewidth*wl_num, 1:order), cfg.superlet.order,'uni',0) % additive: cycles = arrayfun(@(order) arrayfun(@(wl_num) cfg.superlet.basewidth+wl_num-1, 1:order), cfg.superlet.order,'uni',0) cycles = cell(length(cfg.foi),1); diff --git a/ft_freqdescriptives.m b/ft_freqdescriptives.m index edd555c916..68b151e759 100644 --- a/ft_freqdescriptives.m +++ b/ft_freqdescriptives.m @@ -82,8 +82,14 @@ return end +% check if the input data is valid for this function +freq = ft_checkdata(freq, 'datatype', {'freq', 'freqmvar'}, 'feedback', 'yes'); +% get data in the correct representation, it should only have power +freq = ft_checkdata(freq, 'cmbrepresentation', 'sparsewithpow', 'channelcmb', {}); + % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'jacknife', 'jackknife'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'jacknife', 'jackknife'}); % throw warnings for the deprecated options cfg = ft_checkconfig(cfg, 'deprecated', 'biascorrect'); @@ -108,11 +114,6 @@ cfg.latency = ft_getopt(cfg, 'latency', 'all'); cfg.keeptrials = ft_getopt(cfg, 'keeptrials', 'no'); -% check if the input data is valid for this function -freq = ft_checkdata(freq, 'datatype', {'freq', 'freqmvar'}, 'feedback', cfg.feedback); -% get data in the correct representation, it should only have power -freq = ft_checkdata(freq, 'cmbrepresentation', 'sparsewithpow', 'channelcmb', {}); - % determine some specific details of the input data hasrpt = ~isempty(strfind(freq.dimord, 'rpt')) || ~isempty(strfind(freq.dimord, 'subj')); hastim = ~isempty(strfind(freq.dimord, 'time')); diff --git a/ft_freqgrandaverage.m b/ft_freqgrandaverage.m index 9e8778313e..5164fcdd1e 100644 --- a/ft_freqgrandaverage.m +++ b/ft_freqgrandaverage.m @@ -72,9 +72,12 @@ % check if the input data is valid for this function for i=1:length(varargin) - varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'freq', 'feedback', 'no'); + varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'freq', 'feedback', 'no'); end +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.keepindividual = ft_getopt(cfg, 'keepindividual', 'no'); cfg.channel = ft_getopt(cfg, 'channel', 'all'); @@ -83,13 +86,13 @@ cfg.parameter = ft_getopt(cfg, 'parameter', []); if isempty(cfg.parameter) && isfield(varargin{1}, 'powspctrm') - cfg.parameter = 'powspctrm'; + cfg.parameter = 'powspctrm'; elseif isempty(cfg.parameter) - ft_error('you should specify a valid parameter to average'); + ft_error('you should specify a valid parameter to average'); end if ischar(cfg.parameter) - cfg.parameter = {cfg.parameter}; + cfg.parameter = {cfg.parameter}; end Nsubj = length(varargin); @@ -101,131 +104,131 @@ % check whether the input data is suitable if hasrpt - ft_error('the input data of each subject should be an average, use FT_FREQDESCRIPTIVES first'); + ft_error('the input data of each subject should be an average, use FT_FREQDESCRIPTIVES first'); end if hastap - ft_error('multiple tapers in the input are not supported'); + ft_error('multiple tapers in the input are not supported'); end if ischar(cfg.foilim) && strcmp(cfg.foilim, 'all') - fbeg = -inf; - fend = inf; + fbeg = -inf; + fend = inf; else - fbeg = cfg.foilim(1); - fend = cfg.foilim(2); + fbeg = cfg.foilim(1); + fend = cfg.foilim(2); end if ischar(cfg.toilim) && strcmp(cfg.toilim, 'all') - tbeg = -inf; - tend = inf; + tbeg = -inf; + tend = inf; else - tbeg = cfg.toilim(1); - tend = cfg.toilim(2); + tbeg = cfg.toilim(1); + tend = cfg.toilim(2); end % select the data in all inputs for k=1:numel(cfg.parameter) - - % determine which channels, frequencies and latencies are available for all inputs - for i=1:Nsubj - cfg.channel = ft_channelselection(cfg.channel, varargin{i}.label); - if hasfreq - fbeg = max(fbeg, varargin{i}.freq(1 )); - fend = min(fend, varargin{i}.freq(end)); - end - if hastime - tbeg = max(tbeg, varargin{i}.time(1 )); - tend = min(tend, varargin{i}.time(end)); - end + + % determine which channels, frequencies and latencies are available for all inputs + for i=1:Nsubj + cfg.channel = ft_channelselection(cfg.channel, varargin{i}.label); + if hasfreq + fbeg = max(fbeg, varargin{i}.freq(1 )); + fend = min(fend, varargin{i}.freq(end)); + end + if hastime + tbeg = max(tbeg, varargin{i}.time(1 )); + tend = min(tend, varargin{i}.time(end)); + end + end + cfg.foilim = [fbeg fend]; + cfg.toilim = [tbeg tend]; + + % pick the selections + for i=1:Nsubj + if ~isfield(varargin{i}, cfg.parameter{k}) + ft_error('the field %s is not present in data structure %d', cfg.parameter{k}, i); + end + [dum, chansel] = match_str(cfg.channel, varargin{i}.label); + varargin{i}.label = varargin{i}.label(chansel); + + if hasfreq + freqsel = nearest(varargin{i}.freq, fbeg):nearest(varargin{i}.freq, fend); + varargin{i}.freq = varargin{i}.freq(freqsel); end - cfg.foilim = [fbeg fend]; - cfg.toilim = [tbeg tend]; - - % pick the selections - for i=1:Nsubj - if ~isfield(varargin{i}, cfg.parameter{k}) - ft_error('the field %s is not present in data structure %d', cfg.parameter{k}, i); - end - [dum, chansel] = match_str(cfg.channel, varargin{i}.label); - varargin{i}.label = varargin{i}.label(chansel); - - if hasfreq - freqsel = nearest(varargin{i}.freq, fbeg):nearest(varargin{i}.freq, fend); - varargin{i}.freq = varargin{i}.freq(freqsel); - end - if hastime - timesel = nearest(varargin{i}.time, tbeg):nearest(varargin{i}.time, tend); - varargin{i}.time = varargin{i}.time(timesel); - end - % select the overlapping samples in the power spectrum - switch dimord - case 'chan_freq' - varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(chansel,freqsel); - case 'chan_freq_time' - varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(chansel,freqsel,timesel); - case {'rpt_chan_freq' 'rpttap_chan_freq' 'subj_chan_freq'} - varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(:,chansel,freqsel); - case {'rpt_chan_freq_time' 'rpttap_chan_freq_time' 'subj_chan_freq_time'} - varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(:,chansel,freqsel,timesel); - otherwise - ft_error('unsupported dimord'); - end - end % for i = subject + if hastime + timesel = nearest(varargin{i}.time, tbeg):nearest(varargin{i}.time, tend); + varargin{i}.time = varargin{i}.time(timesel); + end + % select the overlapping samples in the power spectrum + switch dimord + case 'chan_freq' + varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(chansel,freqsel); + case 'chan_freq_time' + varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(chansel,freqsel,timesel); + case {'rpt_chan_freq' 'rpttap_chan_freq' 'subj_chan_freq'} + varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(:,chansel,freqsel); + case {'rpt_chan_freq_time' 'rpttap_chan_freq_time' 'subj_chan_freq_time'} + varargin{i}.(cfg.parameter{k}) = varargin{i}.(cfg.parameter{k})(:,chansel,freqsel,timesel); + otherwise + ft_error('unsupported dimord'); + end + end % for i = subject end % for k = parameter % determine the size of the data to be averaged dim = cell(1,numel(cfg.parameter)); for k=1:numel(cfg.parameter) - dim{k} = size(varargin{1}.(cfg.parameter{k})); + dim{k} = size(varargin{1}.(cfg.parameter{k})); end % give some feedback on the screen if strcmp(cfg.keepindividual, 'no') - for k=1:numel(cfg.parameter) - ft_info('computing average %s over %d subjects\n', cfg.parameter{k}, Nsubj); - end + for k=1:numel(cfg.parameter) + ft_info('computing average %s over %d subjects\n', cfg.parameter{k}, Nsubj); + end else - for k=1:numel(cfg.parameter) - ft_info('not computing average, but keeping individual %s for %d subjects\n', cfg.parameter{k}, Nsubj); - end + for k=1:numel(cfg.parameter) + ft_info('not computing average, but keeping individual %s for %d subjects\n', cfg.parameter{k}, Nsubj); + end end % allocate memory to hold the data and collect it for k=1:numel(cfg.parameter) - if strcmp(cfg.keepindividual, 'no') - tmp = zeros(dim{k}); - for s=1:Nsubj - tmp = tmp + varargin{s}.(cfg.parameter{k})./Nsubj; % do a weighted running sum - end - elseif strcmp(cfg.keepindividual, 'yes') - tmp = zeros([Nsubj dim{k}]); - for s=1:Nsubj - tmp(s,:,:,:,:) = varargin{s}.(cfg.parameter{k}); - end + if strcmp(cfg.keepindividual, 'no') + tmp = zeros(dim{k}); + for s=1:Nsubj + tmp = tmp + varargin{s}.(cfg.parameter{k})./Nsubj; % do a weighted running sum + end + elseif strcmp(cfg.keepindividual, 'yes') + tmp = zeros([Nsubj dim{k}]); + for s=1:Nsubj + tmp(s,:,:,:,:) = varargin{s}.(cfg.parameter{k}); end - grandavg.(cfg.parameter{k}) = tmp; + end + grandavg.(cfg.parameter{k}) = tmp; end % collect the output data grandavg.label = varargin{1}.label; grandavg.freq = varargin{1}.freq; if isfield(varargin{1}, 'time') - % remember the time axis - grandavg.time = varargin{1}.time; + % remember the time axis + grandavg.time = varargin{1}.time; end if isfield(varargin{1}, 'labelcmb') - grandavg.labelcmb = varargin{1}.labelcmb; + grandavg.labelcmb = varargin{1}.labelcmb; end if isfield(varargin{1}, 'grad') - ft_warning('discarding gradiometer information because it cannot be averaged'); + ft_warning('discarding gradiometer information because it cannot be averaged'); end if isfield(varargin{1}, 'elec') - ft_warning('discarding electrode information because it cannot be averaged'); + ft_warning('discarding electrode information because it cannot be averaged'); end if strcmp(cfg.keepindividual, 'yes') - grandavg.dimord = ['subj_',varargin{1}.dimord]; + grandavg.dimord = ['subj_',varargin{1}.dimord]; elseif strcmp(cfg.keepindividual, 'no') - grandavg.dimord = varargin{1}.dimord; + grandavg.dimord = varargin{1}.dimord; end % do the general cleanup and bookkeeping at the end of the function diff --git a/ft_freqstatistics.m b/ft_freqstatistics.m index 285f88d337..788cb409db 100644 --- a/ft_freqstatistics.m +++ b/ft_freqstatistics.m @@ -86,17 +86,18 @@ return end -% check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'required', {'method', 'design'}); -cfg = ft_checkconfig(cfg, 'renamed', {'approach', 'method'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'transform'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'trials'}); % this used to be present until 24 Dec 2014, but was deemed too confusing by Robert - % check if the input data is valid for this function for i=1:length(varargin) varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'freq', 'feedback', 'no'); end +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'required', {'method', 'design'}); +cfg = ft_checkconfig(cfg, 'renamed', {'approach', 'method'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'transform'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'trials'}); % this used to be present until 24 Dec 2014, but was deemed too confusing by Robert + % set the defaults cfg.parameter = ft_getopt(cfg, 'parameter'); % default is set below cfg.correctm = ft_getopt(cfg, 'correctm'); diff --git a/ft_globalmeanfield.m b/ft_globalmeanfield.m index 1243ca89c5..aada5ccb67 100644 --- a/ft_globalmeanfield.m +++ b/ft_globalmeanfield.m @@ -73,30 +73,32 @@ return end -% select channels and trials of interest, by default this will select all channels and trials -tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); -datain = ft_selectdata(tmpcfg, datain); -% restore the provenance information -[cfg, datain] = rollback_provenance(cfg, datain); - % ensure that the input data is valid for this function, this will also do % backward-compatibility conversions of old data that for example was % read from an old *.mat file datain = ft_checkdata(datain, 'datatype', {'timelock'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); -% get the options +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + +% set the defaults cfg.method = ft_getopt(cfg, 'method', 'amplitude'); -% ensure that the options are valid -cfg = ft_checkopt(cfg, 'method', 'char', {'amplitude', 'power'}); +% select channels and trials of interest, by default this will select all channels and trials +tmpcfg = keepfields(cfg, {'trials', 'channel', 'tolerance', 'showcallinfo'}); +datain = ft_selectdata(tmpcfg, datain); +% restore the provenance information +[cfg, datain] = rollback_provenance(cfg, datain); -dataout = keepfields(datain,{'avg','time','label','dimord','cfg'}); +dataout = keepfields(datain, {'avg','time','label','dimord','cfg'}); switch cfg.method case 'amplitude' dataout.avg = std(dataout.avg,1); case 'power' dataout.avg = std(dataout.avg,1).^2; + otherwise + ft_error('unsupported method'); end dataout.label = {'gmfp'}; diff --git a/ft_heartrate.m b/ft_heartrate.m index 3fa84ce0c9..7eef53d0f8 100644 --- a/ft_heartrate.m +++ b/ft_heartrate.m @@ -98,9 +98,10 @@ % ensure that users with old scripts are aware of changes cfg = ft_checkconfig(cfg, 'forbidden', 'medianwindow'); -% for backward compatibility -cfg = ft_checkconfig(cfg, 'renamed', {'ectopicbeat_corr', 'ectopicbeatcorrect'}); -cfg = ft_checkconfig(cfg, 'renamed', {'corr_threshold', 'ectopicbeatthreshold'}); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'ectopicbeat_corr', 'ectopicbeatcorrect'}); % for backward compatibility +cfg = ft_checkconfig(cfg, 'renamed', {'corr_threshold', 'ectopicbeatthreshold'}); % for backward compatibility % set the default options cfg.channel = ft_getopt(cfg, 'channel', 'all'); diff --git a/ft_lateralizedpotential.m b/ft_lateralizedpotential.m index a0cc1d1cb4..0fa045c728 100644 --- a/ft_lateralizedpotential.m +++ b/ft_lateralizedpotential.m @@ -90,6 +90,9 @@ avgL = ft_checkdata(avgL, 'datatype', 'timelock'); avgR = ft_checkdata(avgR, 'datatype', 'timelock'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults if ~isfield(cfg, 'channelcmb') cfg.channelcmb = { diff --git a/ft_megplanar.m b/ft_megplanar.m index e2bb01fd54..8379345633 100644 --- a/ft_megplanar.m +++ b/ft_megplanar.m @@ -110,10 +110,12 @@ if ~isfield(data, 'fourierspctrm'), ft_error('freq data should contain Fourier spectra'); end end -cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'pruneratio', 'tolerance'}); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'pruneratio', 'tolerance'}); % set the default configuration cfg.channel = ft_getopt(cfg, 'channel', 'all'); diff --git a/ft_megrealign.m b/ft_megrealign.m index b7fdc96b5d..7e5541ec47 100644 --- a/ft_megrealign.m +++ b/ft_megrealign.m @@ -115,7 +115,14 @@ return end +% store the original datatype +dtype = ft_datatype(data); + +% check if the input data is valid for this function +data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes', 'hassampleinfo', 'yes', 'ismeg', 'yes'); + % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'renamed', {'plot3d', 'feedback'}); cfg = ft_checkconfig(cfg, 'renamedval', {'headshape', 'headmodel', []}); cfg = ft_checkconfig(cfg, 'required', {'inwardshift', 'template'}); @@ -134,12 +141,6 @@ cfg.channel = ft_getopt(cfg, 'channel', 'MEG'); cfg.topoparam = ft_getopt(cfg, 'topoparam', 'rms'); -% store original datatype -dtype = ft_datatype(data); - -% check if the input data is valid for this function -data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes', 'hassampleinfo', 'yes', 'ismeg', 'yes'); - % do realignment per trial pertrial = all(ismember({'nasX';'nasY';'nasZ';'lpaX';'lpaY';'lpaZ';'rpaX';'rpaY';'rpaZ'}, data.label)); diff --git a/ft_multiplotER.m b/ft_multiplotER.m index 605cc54bd3..a221b3f13e 100644 --- a/ft_multiplotER.m +++ b/ft_multiplotER.m @@ -173,17 +173,18 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'cohrefchannel', 'refchannel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'hlim', 'xlim'}); -cfg = ft_checkconfig(cfg, 'renamed', {'matrixside', 'directionality'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vlim', 'ylim'}); -cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); -cfg = ft_checkconfig(cfg, 'renamed', {'graphcolor', 'linecolor'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'cohrefchannel', 'refchannel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hlim', 'xlim'}); +cfg = ft_checkconfig(cfg, 'renamed', {'matrixside', 'directionality'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vlim', 'ylim'}); +cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); +cfg = ft_checkconfig(cfg, 'renamed', {'graphcolor', 'linecolor'}); cfg = ft_checkconfig(cfg, 'renamedval', {'directionality', 'feedback', 'inflow'}); cfg = ft_checkconfig(cfg, 'renamedval', {'directionality', 'feedforward', 'outflow'}); cfg = ft_checkconfig(cfg, 'renamedval', {'zlim', 'absmax', 'maxabs'}); -cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); +cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); % cfg = ft_checkconfig(cfg, 'deprecated', {'xparam'}); % set the defaults diff --git a/ft_multiplotTFR.m b/ft_multiplotTFR.m index 8e100e3d7c..d56ad8cb1a 100644 --- a/ft_multiplotTFR.m +++ b/ft_multiplotTFR.m @@ -179,14 +179,15 @@ data = ft_checkdata(data, 'datatype', 'freq'); % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'cohrefchannel', 'refchannel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'matrixside', 'directionality'}); -cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'cohrefchannel', 'refchannel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'matrixside', 'directionality'}); +cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'}); cfg = ft_checkconfig(cfg, 'renamedval', {'directionality', 'feedback', 'inflow'}); cfg = ft_checkconfig(cfg, 'renamedval', {'directionality', 'feedforward', 'outflow'}); cfg = ft_checkconfig(cfg, 'renamedval', {'zlim', 'absmax', 'maxabs'}); -cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); +cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'newfigure', 'figure'}); % set the defaults cfg.parameter = ft_getopt(cfg, 'parameter', 'powspctrm'); diff --git a/ft_mvaranalysis.m b/ft_mvaranalysis.m index 6c0aba2fea..4f800a861d 100644 --- a/ft_mvaranalysis.m +++ b/ft_mvaranalysis.m @@ -125,8 +125,9 @@ data = ft_checkdata(data, 'datatype', 'raw', 'hassampleinfo', 'yes'); % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); -cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); % set default configuration options cfg.method = ft_getopt(cfg, 'method', 'biosig'); diff --git a/ft_prepare_layout.m b/ft_prepare_layout.m index ad96ea8e7b..0dd56f378b 100644 --- a/ft_prepare_layout.m +++ b/ft_prepare_layout.m @@ -162,9 +162,10 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); -cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); -cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); +cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); +cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % set default configuration options diff --git a/ft_prepare_leadfield.m b/ft_prepare_leadfield.m index 0e2db6c27a..4668940d03 100644 --- a/ft_prepare_leadfield.m +++ b/ft_prepare_leadfield.m @@ -131,13 +131,14 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); -cfg = ft_checkconfig(cfg, 'renamed', {'om', 'openmeeg'}); -cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); -cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); -cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); +cfg = ft_checkconfig(cfg, 'renamed', {'om', 'openmeeg'}); +cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); +cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); +cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); % set the defaults cfg.lbex = ft_getopt(cfg, 'lbex', 'no'); diff --git a/ft_prepare_neighbours.m b/ft_prepare_neighbours.m index e88c95a125..76f6fe978c 100644 --- a/ft_prepare_neighbours.m +++ b/ft_prepare_neighbours.m @@ -105,11 +105,12 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'required', {'method'}); -cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); -cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); -cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); -cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'tri', 'triangulation'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'required', {'method'}); +cfg = ft_checkconfig(cfg, 'renamed', {'elecfile', 'elec'}); +cfg = ft_checkconfig(cfg, 'renamed', {'gradfile', 'grad'}); +cfg = ft_checkconfig(cfg, 'renamed', {'optofile', 'opto'}); +cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'tri', 'triangulation'}); % set the defaults cfg.feedback = ft_getopt(cfg, 'feedback', 'no'); diff --git a/ft_preprocessing.m b/ft_preprocessing.m index 0a5c53f2bc..f9d0daa899 100644 --- a/ft_preprocessing.m +++ b/ft_preprocessing.m @@ -156,7 +156,7 @@ % cfg.export.dataset = string with the output file name % cfg.export.dataformat = string describing the output file format, see FT_WRITE_DATA -% Copyright (C) 2003-2013, Robert Oostenveld, SMI, FCDC +% Copyright (C) 2003-2021, Robert Oostenveld, SMI, FCDC % % This file is part of FieldTrip, see http://www.fieldtriptoolbox.org % for the documentation and details. @@ -200,9 +200,10 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); -cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); -cfg = ft_checkconfig(cfg, 'renamed', {'output', 'export'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); +cfg = ft_checkconfig(cfg, 'renamed', {'output', 'export'}); % set the defaults cfg.method = ft_getopt(cfg, 'method', 'trial'); diff --git a/ft_redefinetrial.m b/ft_redefinetrial.m index 47b271d4a1..4c9eaf2c08 100644 --- a/ft_redefinetrial.m +++ b/ft_redefinetrial.m @@ -113,7 +113,7 @@ size(data.trial, 1) == 1); % check if the input data is valid for this function, this will convert it to raw if needed -data = ft_checkdata(data, 'datatype', {'raw+comp', 'raw'}, 'feedback', cfg.feedback); +data = ft_checkdata(data, 'datatype', {'raw+comp', 'raw'}, 'feedback', 'yes'); % select trials of interest if ~strcmp(cfg.trials, 'all') diff --git a/ft_rejectvisual.m b/ft_rejectvisual.m index 8dde93e94d..d8b756913d 100644 --- a/ft_rejectvisual.m +++ b/ft_rejectvisual.m @@ -134,8 +134,9 @@ data = ft_checkdata(data, 'datatype', {'raw+comp', 'raw'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamedval', {'metric', 'absmax', 'maxabs'}); -cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'absmax', 'maxabs'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamedval', {'metric', 'absmax', 'maxabs'}); +cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'absmax', 'maxabs'}); % resolve some common typing errors cfg = ft_checkconfig(cfg, 'renamed', {'keeptrials', 'keeptrial'}); diff --git a/ft_removetemplateartifact.m b/ft_removetemplateartifact.m index e3064531b2..28476a1021 100644 --- a/ft_removetemplateartifact.m +++ b/ft_removetemplateartifact.m @@ -72,8 +72,11 @@ data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes', 'hassampleinfo', 'yes'); template = ft_checkdata(template, 'datatype', 'timelock'); -% get the options -cfg.channel = ft_getopt(cfg, 'method', data.label); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + +% set the defaults +cfg.channel = ft_getopt(cfg, 'channel', 'all'); cfg.feedback = ft_getopt(cfg, 'method', 'text'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/ft_respiration.m b/ft_respiration.m index cda3c434da..7442d2e478 100644 --- a/ft_respiration.m +++ b/ft_respiration.m @@ -67,12 +67,16 @@ % check if the input data is valid for this function, the input data must be raw datain = ft_checkdata(datain, 'datatype', 'raw', 'feedback', 'yes'); +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the default options cfg.channel = ft_getopt(cfg, 'channel', {}); cfg.envelopewindow = ft_getopt(cfg, 'envelopewindow', []); % in seconds cfg.peakseparation = ft_getopt(cfg, 'peakseparation', 3); % in seconds cfg.feedback = ft_getopt(cfg, 'feedback', 'yes'); cfg.preproc = ft_getopt(cfg, 'preproc', []); + % the expected respiration rate is around 0.40 Hz cfg.preproc.bpfilter = ft_getopt(cfg.preproc, 'bpfilter', 'yes'); cfg.preproc.bpfilttype = ft_getopt(cfg.preproc, 'bpfilttype', 'but'); diff --git a/ft_singleplotER.m b/ft_singleplotER.m index 700c87db40..5d6f79553b 100644 --- a/ft_singleplotER.m +++ b/ft_singleplotER.m @@ -149,6 +149,7 @@ end % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); cfg = ft_checkconfig(cfg, 'renamedval', {'zlim', 'absmax', 'maxabs'}); cfg = ft_checkconfig(cfg, 'renamedval', {'directionality', 'feedforward', 'outflow'}); diff --git a/ft_singleplotTFR.m b/ft_singleplotTFR.m index 23bf7ed3d9..4faefbe36e 100644 --- a/ft_singleplotTFR.m +++ b/ft_singleplotTFR.m @@ -135,6 +135,7 @@ data = ft_checkdata(data, 'datatype', 'freq'); % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); cfg = ft_checkconfig(cfg, 'renamed', {'matrixside', 'directionality'}); cfg = ft_checkconfig(cfg, 'renamedval', {'zlim', 'absmax', 'maxabs'}); diff --git a/ft_sourceanalysis.m b/ft_sourceanalysis.m index bd77548cf8..be4224a781 100644 --- a/ft_sourceanalysis.m +++ b/ft_sourceanalysis.m @@ -174,7 +174,10 @@ baseline = ft_checkdata(baseline, 'datatype', {'timelock', 'freq', 'comp'}, 'feedback', 'yes'); end -% check that the input cfg is valid for this function +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'parallel', 'trials'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'foi', 'toi'}); cfg = ft_checkconfig(cfg, 'renamed', {'toilim', 'latency'}); cfg = ft_checkconfig(cfg, 'renamed', {'foilim', 'frequency'}); cfg = ft_checkconfig(cfg, 'renamed', {'jacknife', 'jackknife'}); @@ -184,8 +187,6 @@ cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'coh_refdip', 'dics'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'dics_cohrefchan', 'dics'}); cfg = ft_checkconfig(cfg, 'renamedval', {'method', 'dics_cohrefdip', 'dics'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'parallel', 'trials'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'foi', 'toi'}); cfg = ft_checkconfig(cfg, 'renamed', {'hdmfile', 'headmodel'}); cfg = ft_checkconfig(cfg, 'renamed', {'vol', 'headmodel'}); cfg = ft_checkconfig(cfg, 'renamed', {'grid', 'sourcemodel'}); diff --git a/ft_stratify.m b/ft_stratify.m index ee2f507589..f2b2850456 100644 --- a/ft_stratify.m +++ b/ft_stratify.m @@ -78,6 +78,9 @@ % dimensionality of input1 (2) = chan x rpt. If nchan>1, do a "double" % stratification +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.method = ft_getopt(cfg, 'method', 'histogram'); cfg.equalbinavg = ft_getopt(cfg, 'equalbinavg', 'yes'); diff --git a/ft_timelockanalysis.m b/ft_timelockanalysis.m index dfd19aba54..7bef59eb8c 100644 --- a/ft_timelockanalysis.m +++ b/ft_timelockanalysis.m @@ -101,6 +101,7 @@ data = ft_checkdata(data, 'datatype', {'raw+comp', 'raw'}, 'feedback', 'yes', 'hassampleinfo', 'yes'); % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'forbidden', {'normalizecov', 'normalizevar'}); cfg = ft_checkconfig(cfg, 'forbidden', {'blcovariance', 'blcovariancewindow'}); cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); diff --git a/ft_timelockbaseline.m b/ft_timelockbaseline.m index 3606c88253..13efa04adc 100644 --- a/ft_timelockbaseline.m +++ b/ft_timelockbaseline.m @@ -65,13 +65,13 @@ end % check if the input data is valid for this function -timelock = ft_checkdata(timelock, 'datatype',... - {'timelock+comp', 'timelock'}, 'feedback', 'yes'); +timelock = ft_checkdata(timelock, 'datatype', {'timelock+comp', 'timelock'}, 'feedback', 'yes'); % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); -cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); -cfg = ft_checkconfig(cfg, 'forbidden', 'baselinetype'); +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blc', 'demean'}); +cfg = ft_checkconfig(cfg, 'renamed', {'blcwindow', 'baselinewindow'}); +cfg = ft_checkconfig(cfg, 'forbidden', 'baselinetype'); % set the defaults cfg.baseline = ft_getopt(cfg, 'baseline', 'no'); diff --git a/ft_timelockgrandaverage.m b/ft_timelockgrandaverage.m index 1806b46c7d..240f1b8fca 100644 --- a/ft_timelockgrandaverage.m +++ b/ft_timelockgrandaverage.m @@ -103,6 +103,9 @@ varargin{i} = ft_checkdata(varargin{i}, 'datatype', 'timelock', 'feedback', 'no'); end +% check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); + % set the defaults cfg.keepindividual = ft_getopt(cfg, 'keepindividual', 'no'); cfg.channel = ft_getopt(cfg, 'channel', 'all'); diff --git a/ft_timelockstatistics.m b/ft_timelockstatistics.m index cccb802dac..ac3e225b58 100644 --- a/ft_timelockstatistics.m +++ b/ft_timelockstatistics.m @@ -78,8 +78,9 @@ end % check if the input cfg is valid for this function -cfg = ft_checkconfig(cfg, 'required', {'method', 'design'}); -cfg = ft_checkconfig(cfg, 'forbidden', {'trials'}); % this used to be present until 24 Dec 2014, but was deemed too confusing by Robert +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); +cfg = ft_checkconfig(cfg, 'forbidden', {'trials'}); % this used to be present until 24 Dec 2014, but was deemed too confusing by Robert +cfg = ft_checkconfig(cfg, 'required', {'method', 'design'}); % check if the input data is valid for this function for i=1:length(varargin) diff --git a/ft_virtualchannel.m b/ft_virtualchannel.m index 2eae20f8b1..16926f60cd 100644 --- a/ft_virtualchannel.m +++ b/ft_virtualchannel.m @@ -1,46 +1,48 @@ function [data_vc] = ft_virtualchannel(cfg, data, source, parcellation) -% FT_VIRTUALCHANNEL creates virtual channel data, combining numeric data -% from a data structure defined at the channel level with spatial filter -% information from a source data structure, and optional parcellation -% information. +% FT_VIRTUALCHANNEL creates virtual channel data, combining numeric data from a data +% structure defined at the channel level with spatial filter information from a +% source data structure, and optional parcellation information. % % Use as % output = ft_virtualchannel(cfg, data, source) -% or +% or % output = ft_virtualchannel(cfg, data, source, parcellation) % -% where the input "data" is a channel level data that contains data that can -% be linearly mapped onto the virtual channel level, e.g. a raw data -% structure obtained with FT_PREPROCESSING, a timelock structure, obtained -% with FT_TIMELOCKANALYSIS, or a freq structure with fourierspectra, -% obtained with FT_FREQANALYSIS. The input "source" is a source structure -% that has been obtained with FT_SOURCEANALYSIS, and which contains spatial -% filter information for at least one dipole location, in the -% source.filter, or source.avg.filter field. The optional input -% "parcellation" is described in detail in FT_DATATYPE_PARCELLATION (2-D) or -% FT_DATATYPE_SEGMENTATION (3-D) and can be obtained from FT_READ_ATLAS or -% from a custom parcellation/segmentation for your individual subject. -% Alternatively, the input "source" can already contain a parcellation. +% where the input "data" is a channel-level data structure that can be linearly +% mapped onto the virtual channel level, e.g. a raw data structure obtained with +% FT_PREPROCESSING, a timelock structure, obtained with FT_TIMELOCKANALYSIS, or a +% freq structure with fourierspectra, obtained with FT_FREQANALYSIS. +% +% The input "source" is a source structure that has been obtained with +% FT_SOURCEANALYSIS, and which contains spatial filter information for at least one +% dipole location, in the source.filter, or source.avg.filter field. +% +% The optional input "parcellation" is described in detail in +% FT_DATATYPE_PARCELLATION (2-D) or FT_DATATYPE_SEGMENTATION (3-D) and can be +% obtained from FT_READ_ATLAS or from a custom parcellation/segmentation for your +% individual subject. Alternatively, the input "source" can already contain a +% parcellation. % % The configuration "cfg" is a structure that should either contain -% cfg.pos = Nx3 matrix containing the dipole positions for the virtual -% channel(s). These positions should match the entries in -% the source.pos field. (default = []) +% cfg.pos = Nx3 matrix containing the dipole positions for the virtual +% channel(s). These positions should match the entries in +% the source.pos field. (default = []) % or -% cfg.parcellation = string, name of the field that is used for the -% parcel labels. (default = []) -% cfg.parcel = string, or cell-array of strings, specifying for which -% parcels to return the output. (default = 'all') +% cfg.parcellation = string, name of the field that is used for the +% parcel labels. (default = []) +% cfg.parcel = string, or cell-array of strings, specifying for which +% parcels to return the output. (default = 'all') % % Moreover, the cfg structure can contain -% cfg.method = string, determines how the components of the specified virtual -% channel(s) are to to be combined. 'svd' (default), 'none', 'pca', -% 'runica', 'fastica', 'dss'. -% cfg.numcomponent = scalar (or 'all'), determines the number of components per virtual -% channel in the output. (default = 1) +% cfg.method = string, determines how the components of the specified virtual +% channel(s) are to to be combined. 'svd' (default), 'none', 'pca', +% 'runica', 'fastica', 'dss'. +% cfg.numcomponent = scalar (or 'all'), determines the number of components per virtual +% channel in the output. (default = 1) % -% See also FT_SOURCEANALYSIS, FT_DATATYPE_PARCELLATION, FT_DATATYPE_SEGMENTATION, FT_SOURCEPARCELLATE, FT_COMPONENTANALYSIS +% See also FT_SOURCEANALYSIS, FT_DATATYPE_PARCELLATION, FT_DATATYPE_SEGMENTATION, +% FT_SOURCEPARCELLATE, FT_COMPONENTANALYSIS % Copyright (C) 2020, Jan-Mathijs Schoffelen and Robert Oostenveld % @@ -80,6 +82,16 @@ return end +% FIXME for now support only raw-type data structures, this should be extended to +% also allow freq (with Fourier) and timelock structures, although the latter is +% probably already covered by the call to checkdata, it should be checked how this is +% done in ft_megplanar. +data = ft_checkdata(data, 'datatype', {'raw', 'raw+comp', 'mvar' 'freq'}, 'feedback', 'yes'); + +% ensure that the source input is a source structure , not a volume structure +% this will also return source.filter, rather than source.avg.filter +source = ft_checkdata(source, 'datatype', 'source', 'inside', 'logical', 'hasunit', 'yes'); + % get the defaults cfg.pos = ft_getopt(cfg, 'pos'); cfg.parcellation = ft_getopt(cfg, 'parcellation'); @@ -111,9 +123,6 @@ ft_error('you should either specify cfg.pos, or a valid cfg.parcellation'); end -% ensure that the source input is a source, not a volume, and this should also return the -% source.filter, rather than source.avg.filter -source = ft_checkdata(source, 'datatype', 'source', 'inside', 'logical', 'hasunit', 'yes'); if ~isfield(source, 'filter') ft_error('the input source needs a ''filter'' field'); % FIXME how about the output of ft_dipolefitting? @@ -123,12 +132,6 @@ isfreq = ft_datatype(data, 'freq'); istlck = ft_datatype(data, 'timelock'); % this will be temporary converted into raw -% FIXME for now support only raw-type data structures, this should be -% extended to also allow freq (with fourier) and timelock structures, -% although the latter is probably already covered by the call to checkdata, -% it should be checked how this is done in ft_megplanar. -data = ft_checkdata(data, 'datatype', {'raw', 'raw+comp', 'mvar' 'freq'}, 'feedback', cfg.feedback); - if isfreq % some restrictions apply to frequency data if ~isfield(data, 'fourierspctrm'), ft_error('freq data should contain Fourier spectra'); end @@ -198,7 +201,7 @@ if ~isempty(transform) parcellation.transform = transform; end - + % ensure that the source and the parcellation are anatomically consistent if ~isalmostequal(source.pos, parcellation.pos, 'abstol', 1000000*eps) ft_error('the source positions are not consistent with the parcellation, please use FT_SOURCEINTERPOLATE'); @@ -213,13 +216,13 @@ nvc = numel(cfg.parcel); - bname = cfg.parcellation; + bname = cfg.parcellation; end % Create a montage for each of the dipoles/parcels, and use ft_apply_montage, -% on the data, followed by a dimensionality reduction step, using -% ft_componentanalysis. Also, keep in mind that this is essentially a +% on the data, followed by a dimensionality reduction step, using +% ft_componentanalysis. Also, keep in mind that this is essentially a % two-step montage application, so keep the individual steps in mind, to be % able to combine it also to the sensor description (which will broadcast % the unmixing to the output data structure, so that it can be used later @@ -268,11 +271,11 @@ % data representation. switch cfg.method case 'svd' - + if ~exist('C', 'var') % create a covariance, or csd matrix that is to be used for the % svd. this needs to be computed only once. - if isfreq + if isfreq tmp = ft_checkdata(data, 'cmbrepresentation', 'fullfast'); C = tmp.crsspctrm; else @@ -348,7 +351,7 @@ tmpdata.label{k} = sprintf('%s_%03d', str, k); end end - label_out{1, i} = tmpdata.label; + label_out{1, i} = tmpdata.label; otherwise ft_error('currently not yet supported'); @@ -398,7 +401,7 @@ % do the general cleanup and bookkeeping at the end of the function ft_postamble debug ft_postamble trackconfig -ft_postamble previous data source parcellation +ft_postamble previous data source parcellation ft_postamble provenance data_vc ft_postamble history data_vc ft_postamble savevar data_vc diff --git a/private/topoplot_common.m b/private/topoplot_common.m index f8f11fa554..9022b870a0 100644 --- a/private/topoplot_common.m +++ b/private/topoplot_common.m @@ -35,6 +35,7 @@ %% Section 1: general cfg handling that is independent from the data % check if the input cfg is valid for this function +cfg = ft_checkconfig(cfg, 'forbidden', {'channels'}); cfg = ft_checkconfig(cfg, 'unused', {'cohtargetchannel'}); cfg = ft_checkconfig(cfg, 'renamed', {'cohrefchannel' 'refchannel'}); cfg = ft_checkconfig(cfg, 'renamed', {'zparam', 'parameter'});