/spm12/spm_eeg_average_TF.m

https://bitbucket.org/matthewbrett/spm-versions · Objective C · 205 lines · 171 code · 34 blank · 0 comment · 41 complexity · 93c96e5bd81f32afb69a0f71413e5df1 MD5 · raw file

  1. function D = spm_eeg_average_TF(S)
  2. % Average each channel over trials or trial types, for time-frequency data
  3. % FORMAT D = spm_eeg_average_TF(S)
  4. %
  5. % S - optional input struct
  6. % fields of S:
  7. % S.D - MEEG object or filename of M/EEG mat-file with epoched TF data
  8. % S.circularise - flag that indicates whether average is straight (0) or
  9. % vector (1) of phase angles.
  10. % S.robust - (optional) - use robust averaging (only for power)
  11. % .savew - save the weights in an additional dataset
  12. % .bycondition - compute the weights by condition (1,
  13. % default) or from all trials (0)
  14. % .ks - offset of the weighting function (default: 3)
  15. %
  16. % Output:
  17. % D - MEEG object (also written to disk).
  18. %__________________________________________________________________________
  19. % Copyright (C) 2008-2012 Wellcome Trust Centre for Neuroimaging
  20. % Stefan Kiebel
  21. % $Id: spm_eeg_average_TF.m 6180 2014-09-17 15:45:11Z vladimir $
  22. SVNrev = '$Rev: 6180 $';
  23. %-Startup
  24. %--------------------------------------------------------------------------
  25. spm('FnBanner', mfilename, SVNrev);
  26. spm('FigName','M/EEG TF averaging'); spm('Pointer','Watch');
  27. if ~isfield(S, 'circularise'), S.circularise = 0; end
  28. %-Configure robust averaging
  29. %--------------------------------------------------------------------------
  30. if isstruct(S.robust)
  31. if ~isfield(S.robust, 'savew'), S.robust.savew = 0; end
  32. if ~isfield(S.robust, 'bycondition'), S.robust.bycondition = 0; end
  33. if ~isfield(S.robust, 'ks'), S.robust.ks = 3; end
  34. robust = 1;
  35. savew = S.robust.savew;
  36. bycondition = S.robust.bycondition;
  37. ks = S.robust.ks;
  38. removebad = S.robust.removebad;
  39. else
  40. robust = 0;
  41. end
  42. %-Get MEEG object
  43. %--------------------------------------------------------------------------
  44. D = spm_eeg_load(S.D);
  45. %-Check data type
  46. %--------------------------------------------------------------------------
  47. if ~strcmp(D.type, 'single')
  48. error('This function can only be applied to single trial data');
  49. end
  50. if ~strncmp(D.transformtype, 'TF', 2) % TF and TFphase
  51. error('This function can only be applied to time-frequency data.');
  52. end
  53. if strcmp(D.transformtype, 'TFphase')
  54. if ~isequal(S.robust, 0)
  55. warning('Robust averaging is not applicable to phase data and will not be used.');
  56. S.robust = 0;
  57. end
  58. plv = S.circularise;
  59. end
  60. %-Generate new MEEG object with new files
  61. %--------------------------------------------------------------------------
  62. Dnew = clone(D, [S.prefix fname(D)], [D.nchannels D.nfrequencies D.nsamples D.nconditions]);
  63. if robust && savew
  64. Dw = clone(D, ['W' fname(D)]);
  65. end
  66. cl = D.condlist;
  67. ni = zeros(1,D.nconditions);
  68. for i = 1:D.nconditions
  69. w = indtrial(D, deblank(cl{i}), 'GOOD');
  70. ni(i) = length(w);
  71. if ni(i) == 0
  72. warning('%s: No trials for trial type %s', D.fname, cl{i});
  73. end
  74. end
  75. goodtrials = indtrial(D, cl, 'GOOD');
  76. if robust && removebad
  77. bad = badsamples(D, ':', ':', ':');
  78. end
  79. spm_progress_bar('Init', D.nsamples, 'Samples completed');
  80. if D.nsamples > 100, Ibar = floor(linspace(1, D.nsamples, 100));
  81. else Ibar = [1:D.nsamples]; end
  82. for j = 1:D.nsamples
  83. if robust && ~bycondition
  84. Y = D(:, :, j, goodtrials);
  85. if removebad
  86. ibad = reshape(bad(:, j, goodtrials), [size(bad, 1), 1, 1, length(goodtrials)]);
  87. ibad = repmat(ibad, [1, D.nfrequencies, 1, 1]);
  88. Y(ibad) = NaN;
  89. end
  90. [Y, W1] = spm_robust_average(Y, 4, ks);
  91. if savew
  92. Dw(:, :, j, goodtrials) = W1;
  93. end
  94. W = zeros([D.nchannels D.nfrequencies 1 D.ntrials]);
  95. W(:, :, 1, goodtrials) = W1;
  96. end
  97. for i = 1:D.nconditions
  98. w = indtrial(D, deblank(cl{i}), 'GOOD');
  99. if isempty(w)
  100. continue;
  101. end
  102. %-Straight average
  103. %------------------------------------------------------------------
  104. if ~strcmp(D.transformtype, 'TFphase')
  105. if ~robust
  106. Dnew(:, :, j, i) = mean(D(:, :, j, w), 4);
  107. else
  108. if bycondition
  109. Y = D(:, :, j, w);
  110. if removebad
  111. ibad = reshape(bad(:, j, w), [size(bad, 1), 1, 1, length(w)]);
  112. ibad = repmat(ibad, [1, D.nfrequencies, 1, 1]);
  113. Y(ibad) = NaN;
  114. end
  115. [Y, W] = spm_robust_average(Y, 4, ks);
  116. Dnew(:, :, j, i) = Y;
  117. if savew
  118. Dw(:, :, j, w) = W;
  119. end
  120. else
  121. X = D(:, :, j, w);
  122. X(isnan(X)) = 0;
  123. Dnew(:, :, j, i) = ...
  124. sum(W(:, :, 1, w).*X, 4)./sum(W(:, :, 1, w), 4);
  125. end
  126. end
  127. %-Vector average (eg PLV for phase)
  128. %------------------------------------------------------------------
  129. else
  130. tmp = D(:, :, j, w);
  131. tmp = exp(sqrt(-1)*tmp);
  132. if plv
  133. Dnew(:, :, j, i) = abs(mean(tmp,4));
  134. else
  135. Dnew(:, :, j, i) = angle(mean(tmp,4));
  136. end
  137. end
  138. end
  139. if ismember(j, Ibar), spm_progress_bar('Set', j); end
  140. end
  141. spm_progress_bar('Clear');
  142. Dnew = type(Dnew, 'evoked');
  143. %-Update some header information
  144. %--------------------------------------------------------------------------
  145. Dnew = conditions(Dnew, ':', cl);
  146. Dnew = repl(Dnew, ':', ni);
  147. %-Display averaging statistics
  148. %--------------------------------------------------------------------------
  149. fprintf('%s: Number of replications per contrast:', Dnew.fname); %-#
  150. s = [];
  151. for i = 1:D.nconditions
  152. s = [s sprintf('average %s: %d trials', cl{i}, ni(i))];
  153. if i < D.nconditions
  154. s = [s ', '];
  155. else
  156. s = [s '\n'];
  157. end
  158. end
  159. fprintf(s); %-#
  160. %-Save new evoked M/EEG dataset
  161. %--------------------------------------------------------------------------
  162. Dnew = Dnew.history('spm_eeg_average', S);
  163. save(Dnew);
  164. if robust && savew
  165. Dw = Dw.history('spm_eeg_average', S);
  166. save(Dw);
  167. end
  168. D = Dnew;
  169. %-Cleanup
  170. %--------------------------------------------------------------------------
  171. spm('FigName','M/EEG TF averaging: done'); spm('Pointer', 'Arrow');