PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/examples/toolboxes/fieldtrip/ft_combineplanar.m

http://brainstream.googlecode.com/
MATLAB | 278 lines | 174 code | 29 blank | 75 comment | 42 complexity | a94584ac2e2dcb5727da8363b6138423 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, LGPL-2.0, GPL-3.0, GPL-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  1. function [data] = ft_combineplanar(cfg, data)
  2. % FT_COMBINEPLANAR computes the planar gradient magnitude over both directions
  3. % combining the two gradients at each sensor to a single positive-valued number.
  4. % This can be done for averaged ERFs or TFRs (i.e. powerspectra).
  5. %
  6. % Use as
  7. % [data] = ft_combineplanar(cfg, data)
  8. % where data contains an averaged planar gradient (either ERF or TFR).
  9. %
  10. % In the case of ERFs, the configuration can contain
  11. % cfg.blc = 'yes' or 'no' (default)
  12. % cfg.blcwindow = [begin end]
  13. %
  14. % After combining the planar data, the planar gradiometer definition does not
  15. % match the data any more and therefore it is removed from the data. With
  16. % cfg.combinegrad = 'yes'
  17. % the function will try to reconstruct the axial gradiometer definition.
  18. %
  19. % See also FT_MEGPLANAR
  20. % Undocumented local options:
  21. % cfg.baseline
  22. % cfg.combinemethod
  23. % cfg.foilim
  24. % cfg.trials
  25. % cfg.inputfile = one can specifiy preanalysed saved data as input
  26. % cfg.outputfile = one can specify output as file to save to disk
  27. % Copyright (C) 2004, Ole Jensen, Robert Oostenveld
  28. %
  29. % This file is part of FieldTrip, see http://www.ru.nl/neuroimaging/fieldtrip
  30. % for the documentation and details.
  31. %
  32. % FieldTrip is free software: you can redistribute it and/or modify
  33. % it under the terms of the GNU General Public License as published by
  34. % the Free Software Foundation, either version 3 of the License, or
  35. % (at your option) any later version.
  36. %
  37. % FieldTrip is distributed in the hope that it will be useful,
  38. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  39. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  40. % GNU General Public License for more details.
  41. %
  42. % You should have received a copy of the GNU General Public License
  43. % along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
  44. %
  45. % $Id: ft_combineplanar.m 1261 2010-06-22 15:09:23Z roboos $
  46. fieldtripdefs
  47. % set the defaults
  48. if ~isfield(cfg, 'blc'), cfg.blc = 'no'; end
  49. if ~isfield(cfg, 'foilim'), cfg.foilim = [-inf inf]; end
  50. if ~isfield(cfg, 'blcwindow'), cfg.blcwindow = [-inf inf]; end
  51. if ~isfield(cfg, 'combinemethod'), cfg.combinemethod = 'sum'; end
  52. if ~isfield(cfg, 'trials'), cfg.trials = 'all'; end
  53. if ~isfield(cfg, 'feedback'), cfg.feedback = 'none'; end
  54. if ~isfield(cfg, 'inputfile'), cfg.inputfile = []; end
  55. if ~isfield(cfg, 'outputfile'), cfg.outputfile = []; end
  56. hasdata = (nargin>1);
  57. if ~isempty(cfg.inputfile)
  58. % the input data should be read from file
  59. if hasdata
  60. error('cfg.inputfile should not be used in conjunction with giving input data to this function');
  61. else
  62. data = loadvar(cfg.inputfile, 'data');
  63. end
  64. end
  65. % check if the input data is valid for this function
  66. data = checkdata(data, 'datatype', {'raw', 'freq', 'timelock'}, 'feedback', 'yes', 'senstype', {'ctf151_planar', 'ctf275_planar', 'neuromag122', 'neuromag306', 'bti248_planar', 'bti148_planar', 'itab153_planar'});
  67. cfg = checkconfig(cfg, 'trackconfig', 'on');
  68. cfg = checkconfig(cfg, 'forbidden', {'combinegrad'});
  69. cfg = checkconfig(cfg, 'deprecated', {'baseline'});
  70. if isfield(cfg, 'baseline')
  71. warning('only supporting cfg.baseline for backwards compatibility, please update your cfg');
  72. cfg.blc = 'yes';
  73. cfg.blcwindow = cfg.baseline;
  74. end
  75. israw = datatype(data, 'raw');
  76. isfreq = datatype(data, 'freq');
  77. istimelock = datatype(data, 'timelock');
  78. try, dimord = data.dimord; end
  79. % select trials of interest
  80. if ~strcmp(cfg.trials, 'all')
  81. error('trial selection has not been implemented yet') % first fix checkdata (see above)
  82. end
  83. % find the combination of horizontal and vertical channels that should be combined
  84. planar = planarchannelset(data);
  85. sel_dH = match_str(data.label, planar(:,1)); % indices of the horizontal channels
  86. sel_dV = match_str(data.label, planar(:,2)); % indices of the vertical channels
  87. lab_dH = data.label(sel_dH);
  88. lab_dV = data.label(sel_dV);
  89. if length(sel_dH)~=length(sel_dV)
  90. error('not all planar channel combinations are complete')
  91. end
  92. % find the other channels that are present in the data
  93. sel_other = setdiff(1:length(data.label), [sel_dH(:)' sel_dV(:)']);
  94. lab_other = data.label(sel_other);
  95. % define the channel names after combining the planar combinations
  96. % they should be sorted according to the order of the planar channels in the data
  97. [dum, sel_planar] = match_str(data.label, planar(:,1));
  98. lab_comb = planar(sel_planar,3);
  99. % perform baseline correction
  100. if strcmp(cfg.blc, 'yes')
  101. if ~(istimelock || israw)
  102. error('baseline correction is only supported for timelocked or raw input data')
  103. end
  104. if ischar(cfg.blcwindow) && strcmp(cfg.blcwindow, 'all')
  105. cfg.blcwindow = [-inf inf];
  106. end
  107. % find the timebins corresponding to the baseline interval
  108. tbeg = nearest(data.time, cfg.blcwindow(1));
  109. tend = nearest(data.time, cfg.blcwindow(2));
  110. cfg.blcwindow(1) = data.time(tbeg);
  111. cfg.blcwindow(2) = data.time(tend);
  112. data.avg = blc(data.avg, tbeg, tend);
  113. end
  114. if isfreq
  115. switch cfg.combinemethod
  116. case 'sum'
  117. if isfield(data, 'powspctrm'),
  118. % compute the power of each planar channel, by summing the horizontal and vertical gradients
  119. dimtok = tokenize(dimord,'_');
  120. catdim = strmatch('chan',dimtok);
  121. if catdim==1,
  122. combined = data.powspctrm(sel_dH,:,:,:) + data.powspctrm(sel_dV,:,:,:);
  123. other = data.powspctrm(sel_other,:,:,:);
  124. elseif catdim==2,
  125. combined = data.powspctrm(:,sel_dH,:,:,:) + data.powspctrm(:,sel_dV,:,:,:);
  126. other = data.powspctrm(:,sel_other,:,:,:);
  127. else
  128. error('unsupported dimension order of frequency data');
  129. end
  130. data.powspctrm = cat(catdim, combined, other);
  131. data.label = cat(1, lab_comb(:), lab_other(:));
  132. else
  133. error('cfg.combinemethod = ''%s'' only works for frequency data with powspctrm', cfg.combinemethod);
  134. end
  135. case 'svd'
  136. if isfield(data, 'fourierspctrm'),
  137. fbin = nearest(data.freq, cfg.foilim(1)):nearest(data.freq, cfg.foilim(2));
  138. Nrpt = size(data.fourierspctrm,1);
  139. Nsgn = length(sel_dH);
  140. Nfrq = length(fbin);
  141. Ntim = size(data.fourierspctrm,4);
  142. %fourier= complex(zeros(Nrpt,Nsgn,Nfrq,Ntim),zeros(Nrpt,Nsgn,Nfrq,Ntim));
  143. fourier= zeros(Nrpt,Nsgn,Nfrq,Ntim)+nan;
  144. progress('init', cfg.feedback, 'computing the svd');
  145. for j = 1:Nsgn
  146. progress(j/Nsgn, 'computing the svd of signal %d/%d\n', j, Nsgn);
  147. for k = 1:Nfrq
  148. dum = reshape(data.fourierspctrm(:,[sel_dH(j) sel_dV(j)],fbin(k),:), [Nrpt 2 Ntim]);
  149. dum = permute(dum, [2 3 1]);
  150. dum = reshape(dum, [2 Ntim*Nrpt]);
  151. timbin = ~isnan(dum(1,:));
  152. dum2 = svdfft(dum(:,timbin),1,data.cumtapcnt);
  153. dum(1,timbin) = dum2;
  154. dum = reshape(dum(1,:),[Ntim Nrpt]);
  155. fourier(:,j,k,:) = transpose(dum);
  156. %for m = 1:Ntim
  157. % dum = data.fourierspctrm(:,[sel_dH(j) sel_dV(j)],fbin(k),m);
  158. % timbin = find(~isnan(dum(:,1)));
  159. % [fourier(timbin,j,k,m)] = svdfft(transpose(dum(timbin,:)),1);
  160. %end
  161. end
  162. end
  163. progress('close');
  164. other = data.fourierspctrm(:,sel_other,fbin,:);
  165. data = rmfield(data,'fourierspctrm');
  166. data.fourierspctrm = cat(2, fourier, other);
  167. data.label = cat(1, lab_comb(:), lab_other(:));
  168. data.freq = data.freq(fbin);
  169. else
  170. error('cfg.combinemethod = ''%s'' only works for frequency data with fourierspctrm', cfg.combinemethod);
  171. end
  172. otherwise
  173. error('cfg.combinemethod = ''%s'' is not supported for frequency data', cfg.combinemethod);
  174. end
  175. elseif (israw || istimelock)
  176. if istimelock,
  177. % convert timelock to raw
  178. data = checkdata(data, 'datatype', 'raw', 'feedback', 'yes');
  179. end
  180. switch cfg.combinemethod
  181. case 'sum'
  182. Nrpt = length(data.trial);
  183. for k = 1:Nrpt
  184. combined = sqrt(data.trial{k}(sel_dH,:).^2 + data.trial{k}(sel_dV,:).^2);
  185. other = data.trial{k}(sel_other,:);
  186. data.trial{k} = [combined; other];
  187. end
  188. data.label = cat(1, lab_comb(:), lab_other(:));
  189. case 'svd'
  190. Nrpt = length(data.trial);
  191. Nsgn = length(sel_dH);
  192. Nsmp = cellfun('size', data.trial, 2);
  193. Csmp = cumsum([0 Nsmp]);
  194. % do a 'fixed orientation' across all trials approach here
  195. % this is different from the frequency case FIXME
  196. tmpdat = zeros(2, sum(Nsmp));
  197. for k = 1:Nsgn
  198. for m = 1:Nrpt
  199. tmpdat(:, (Csmp(m)+1):Csmp(m+1)) = data.trial{m}([sel_dH(k) sel_dV(k)],:);
  200. end
  201. tmpdat2 = abs(svdfft(tmpdat,1));
  202. tmpdat2 = mat2cell(tmpdat2, 1, Nsmp);
  203. for m = 1:Nrpt
  204. if k==1, trial{m} = zeros(Nsgn, Nsmp(m)); end
  205. trial{m}(k,:) = tmpdat2{m};
  206. end
  207. end
  208. for m = 1:Nrpt
  209. other = data.trial{m}(sel_other,:);
  210. trial{m} = [trial{m}; other];
  211. end
  212. data.trial = trial;
  213. data.label = cat(1, lab_comb(:), lab_other(:));
  214. otherwise
  215. error('cfg.combinemethod = ''%s'' is not supported for timelocked or raw data', cfg.combinemethod);
  216. end
  217. if istimelock,
  218. % convert raw to timelock
  219. data = checkdata(data, 'datatype', 'timelock', 'feedback', 'yes');
  220. end
  221. else
  222. error('unsupported input data');
  223. end % which datatype
  224. % remove the fields for which the planar gradient could not be combined
  225. try, data = rmfield(data, 'crsspctrm'); end
  226. try, data = rmfield(data, 'labelcmb'); end
  227. % accessing this field here is needed for the configuration tracking
  228. % by accessing it once, it will not be removed from the output cfg
  229. cfg.outputfile;
  230. % get the output cfg
  231. cfg = checkconfig(cfg, 'trackconfig', 'off', 'checksize', 'yes');
  232. % store the configuration of this function call, including that of the previous function call
  233. try
  234. % get the full name of the function
  235. cfg.version.name = mfilename('fullpath');
  236. catch
  237. % required for compatibility with Matlab versions prior to release 13 (6.5)
  238. [st, i] = dbstack;
  239. cfg.version.name = st(i);
  240. end
  241. cfg.version.id = '$Id: ft_combineplanar.m 1261 2010-06-22 15:09:23Z roboos $';
  242. % remember the configuration details of the input data
  243. try, cfg.previous = data.cfg; end
  244. % remember the exact configuration details in the output
  245. data.cfg = cfg;
  246. % the output data should be saved to a MATLAB file
  247. if ~isempty(cfg.outputfile)
  248. savevar(cfg.outputfile, 'data', data); % use the variable name "data" in the output file
  249. end