spm_eeg_contrast.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. function D = spm_eeg_contrast(S)
  2. % Compute contrasts over trials or trial types
  3. % FORMAT D = spm_eeg_contrast(S)
  4. %
  5. % S - optional input struct
  6. % fields of S:
  7. % D - filename of EEG mat-file with epoched data
  8. % c - contrast matrix, each row computes a contrast of the data
  9. % label - cell array of labels for the contrasts, the same size as
  10. % number of rows in c
  11. % weighted - flag whether average should be weighted by number of
  12. % replications (yes (1), no (0))
  13. % prefix - prefix for the output file [default: 'w']
  14. %
  15. % Output:
  16. % D - EEG data struct (also written to disk)
  17. %__________________________________________________________________________
  18. %
  19. % spm_eeg_contrast computes contrasts of data, over epochs of data. The
  20. % input is a single MEEG file. The argument c must have dimensions
  21. % Ncontrasts X Nepochs, where Ncontrasts is the number of contrasts and
  22. % Nepochs the number of epochs, i.e. each row of c contains one contrast
  23. % vector. The output is a M/EEG file with Ncontrasts epochs. The typical
  24. % use is to compute, for display purposes, contrasts like the difference or
  25. % interaction between trial types in channel space.
  26. %__________________________________________________________________________
  27. % Copyright (C) 2008-2017 Wellcome Trust Centre for Neuroimaging
  28. % Stefan Kiebel, Rik Henson
  29. % $Id: spm_eeg_contrast.m 7132 2017-07-10 16:22:58Z guillaume $
  30. SVNrev = '$Rev: 7132 $';
  31. %-Startup
  32. %--------------------------------------------------------------------------
  33. spm('FnBanner', mfilename, SVNrev);
  34. spm('FigName','M/EEG Contrast'); spm('Pointer','Watch');
  35. %-Get MEEG object
  36. %--------------------------------------------------------------------------
  37. if ~isfield(S, 'prefix'), S.prefix = 'w'; end
  38. if ~isfield(S, 'weighted'), S.weighted = 0; end
  39. if ~(isfield(S, 'c') && isfield(S, 'label') && numel(S.label)==size(S.c, 1))
  40. error('Invalid contrast specification.');
  41. end
  42. D = spm_eeg_load(S.D);
  43. %-Compute contrasts
  44. %--------------------------------------------------------------------------
  45. c = S.c;
  46. Ncontrasts = size(c, 1);
  47. % Pad with zeros as in the contrast manager
  48. if size(c, 2) ~= D.ntrials
  49. error('The number of columns in the contrast matrix does not match the number of trials.');
  50. end
  51. if ~isempty(D.repl)
  52. weighted = S.weighted;
  53. else
  54. weighted = 0;
  55. end
  56. if strncmp(D.transformtype, 'TF', 2)
  57. Dnew = clone(D, [S.prefix fname(D)], [D.nchannels D.nfrequencies D.nsamples Ncontrasts]);
  58. else
  59. Dnew = clone(D, [S.prefix fname(D)],[D.nchannels D.nsamples Ncontrasts]);
  60. end
  61. spm_progress_bar('Init', Ncontrasts, 'Contrasts computed');
  62. if Ncontrasts > 100, Ibar = floor(linspace(1, Ncontrasts, 100));
  63. else Ibar = 1:Ncontrasts; end
  64. for i = 1:Ncontrasts
  65. if weighted
  66. p = find(c(i,:) == 1);
  67. if ~isempty(p)
  68. r = D.repl(p);
  69. c(i,p) = r/sum(r);
  70. end
  71. p = find(c(i,:) == -1);
  72. if ~isempty(p)
  73. r = D.repl(p);
  74. c(i,p) = -r/sum(r);
  75. end
  76. end
  77. disp(['Contrast ', mat2str(i),': ', mat2str(c(i,:),3)])
  78. if strncmp(D.transformtype, 'TF', 2)
  79. d = zeros(D.nchannels, D.nfrequencies, D.nsamples);
  80. for j = 1:D.nchannels
  81. for f = 1:D.nfrequencies
  82. d(j, f, :) = c(i,:) * spm_squeeze(D(j, f, :, :), [1 2 4])';
  83. end
  84. end
  85. Dnew(1:Dnew.nchannels, 1:D.nfrequencies, 1:Dnew.nsamples, i) = d;
  86. else
  87. d = zeros(D.nchannels, D.nsamples);
  88. for j = 1:D.nchannels
  89. d(j, :) = c(i,:) * squeeze(D(j, :, :))';
  90. end
  91. Dnew(1:Dnew.nchannels, 1:Dnew.nsamples, i) = d;
  92. end
  93. newrepl(i) = sum(D.repl(find(c(i,:)~=0)));
  94. if any(Ibar == i), spm_progress_bar('Set', i); end
  95. end
  96. spm_progress_bar('Clear');
  97. %-
  98. %--------------------------------------------------------------------------
  99. Dnew = conditions(Dnew, ':', S.label);
  100. Dnew = trialonset(Dnew, ':', []);
  101. Dnew = trialtag(Dnew, ':', []);
  102. Dnew = badtrials(Dnew, ':', 0);
  103. Dnew = repl(Dnew, ':', newrepl);
  104. Dnew = type(Dnew, 'evoked');
  105. % remove previous source reconsructions
  106. if isfield(Dnew,'inv')
  107. Dnew = rmfield(Dnew,'inv');
  108. end
  109. %-Save new M/EEG data
  110. %--------------------------------------------------------------------------
  111. D = Dnew;
  112. D = D.history('spm_eeg_contrast', S);
  113. save(D);
  114. %-Cleanup
  115. %--------------------------------------------------------------------------
  116. spm('FigName','M/EEG Contrast: done'); spm('Pointer','Arrow');