eeg_rpsd.m 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. function [psdmed, psdvar, psdkrt] = eeg_rpsd(EEG, nfreqs, pct_data)
  2. % clean input cutoff freq
  3. nyquist = floor(EEG.srate / 2);
  4. if ~exist('nfreqs', 'var') || isempty(nfreqs)
  5. nfreqs = nyquist;
  6. elseif nfreqs > nyquist
  7. nfreqs = nyquist;
  8. end
  9. if ~exist('pct_data', 'var') || isempty(pct_data)
  10. pct_data = 100;
  11. end
  12. % setup constants
  13. ncomp = size(EEG.icaweights, 1);
  14. n_points = min(EEG.pnts, EEG.srate);
  15. window = hamming(n_points)';
  16. cutoff = floor(EEG.pnts / n_points) * n_points;
  17. index = bsxfun(@plus, ceil(0:n_points / 2:cutoff - n_points), (1:n_points)');
  18. rng(0)
  19. n_seg = size(index, 2) * EEG.trials;
  20. subset = randperm(n_seg, ceil(n_seg * pct_data / 100)); % need to improve this
  21. rng('shuffle')
  22. try
  23. %% slightly faster but high memory use
  24. % calculate windowed spectrums
  25. temp = reshape(EEG.icaact(:, index, :), [ncomp size(index) .* [1 EEG.trials]]);
  26. temp = bsxfun(@times, temp(:, :, subset), window);
  27. temp = fft(temp, n_points, 2);
  28. temp = abs(temp).^2;
  29. temp = temp(:, 2:nfreqs + 1, :) * 2 / (EEG.srate*sum(window.^2));
  30. if nfreqs == nyquist
  31. temp(:, end, :) = temp(:, end, :) / 2; end
  32. % calculate outputs
  33. psdmed = db(median(temp, 3));
  34. psdvar = db(var(temp, [], 3), 'power');
  35. psdkrt = db(kurtosis(temp, [], 3)/4);
  36. catch
  37. %% lower memory but slightly slower
  38. psdmed = zeros(ncomp, nfreqs);
  39. psdvar = zeros(ncomp, nfreqs);
  40. psdkrt = zeros(ncomp, nfreqs);
  41. for it = 1:ncomp
  42. % calculate windowed spectrums
  43. temp = reshape(EEG.icaact(it, index, :), [1 size(index) .* [1 EEG.trials]]);
  44. temp = bsxfun(@times, temp(:, :, subset), window);
  45. temp = fft(temp, n_points, 2);
  46. temp = temp .* conj(temp);
  47. temp = temp(:, 2:nfreqs + 1, :) * 2 / (EEG.srate*sum(window.^2));
  48. if nfreqs == nyquist
  49. temp(:, end, :) = temp(:, end, :) / 2; end
  50. psdmed(it, :) = db(median(temp, 3));
  51. psdvar(it, :) = db(var(temp, [], 3), 'power');
  52. psdkrt(it, :) = db(kurtosis(temp, [], 3)/4);
  53. end
  54. end
  55. end