%DK_PSD

%Function to accompany Chapter 6 of Dickter & Kieffaber (2013) EEG Methods

%for Social and Personality Psychology

%Usage:

%> [EEG ALLEEG CURRENTSET com]=DK_PSD(EEG,ALLEEG,CURRENTSET,varargin)

%

% Inputs:

% 1) EEG - EEGlab data structure

%

% Optional inputs:

% 'baseline' - [start stop] Start and End latencies (ms) to use as baseline.

% 'datawindow' - [start stop] Start and End latencies (ms) to use analyze

%

%Output:

% EEG - Abominized EEG dataset converted to the power spectrum

% (uV^2) of the input data set. The form of the new data is Channels X

% Frequencies X Trials. CAUTION: EEG.times and EEG.srate fields modified

% accordingly in order to make available most visualization tools.

%

% ------

% AUTHOR:

% Paul Kieffaber

% Department of Psychology &

% Program in Neuroscience

% College of William & Mary

%

% ------

%

% THIS PROGRAM IS FREE SOFTWARE INTENDED FOR EDUCATIONAL PURPOSES ONLY.

%

% This program is distributed in the hope that it will be useful,

% but WITHOUT ANY WARRANTY; without even the implied warranty of

% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

function [EEG ALLEEG CURRENTSET com]=DK_PSD(EEG,ALLEEG,CURRENTSET,varargin)

datawindow=[EEG.xmin*1000 EEG.xmax*1000]; %default = whole epoch

%Parse optional inputs

for i=1:2:length(varargin)

arg=lower(varargin{i});

val=varargin{i+1};

switch arg

case 'baseline'

if length(val)==2

baseline=val;

else

disp(['baseline argument must be two-element vector [start end]']);

end

case 'datawindow'

if length(val)==2

datawindow=val;

else

disp(['specification of DataWin requires two-element vector [start end]']);

end

end

end

datastart=find(abs(EEG.times-datawindow(1))==min(abs(EEG.times-datawindow(1))));

datastop=find(abs(EEG.times-datawindow(2))==min(abs(EEG.times-datawindow(2))));

%if baseline specified, then use same nfft for both

if exist('baseline')==1

baselinestart=find(abs(EEG.times-baseline(1))==min(abs(EEG.times-baseline(1))));

baselinestop=find(abs(EEG.times-baseline(2))==min(abs(EEG.times-baseline(2))));

nfft=min([2^nextpow2(baselinestop-baselinestart) 2^nextpow2(datastop-datastart)]);

end

%Compute signal PSD

Pxxdata=[];

for i=1:size(EEG.data,3)

for j=1:size(EEG.data,1)

if exist('nfft')==1

[Pxxdata(j,:,i),F] = pwelch(EEG.data(j,datastart:datastop,i),[],[],nfft,EEG.srate);

else

[Pxxdata(j,:,i),F] = pwelch(EEG.data(j,datastart:datastop,i),[],[],[],EEG.srate);

end

end

end

%Compute baseline PSD

if exist('baseline')==1

Pxxbaseline=[];

for i=1:size(EEG.data,3)

for j=1:size(EEG.data,1)

[Pxxbaseline(j,:,i),F] = pwelch(EEG.data(j,baselinestart:baselinestop,i),[],[],nfft,EEG.srate);

end

end

Pxxdata=10*log10(Pxxdata./Pxxbaseline);

end

%Abominize EEG structure in order to make visualization tools available

disp('Frequencies will be stored in ''EEG.times''');

EEG.data=Pxxdata;

EEG.pnts=length(F);

EEG.times=F;

EEG.setname=strcat('PX_',EEG.setname);

EEG.xmin=0;

EEG.xmax=max(F)/1000;

EEG.srate=(length(F)-1)/(max(F)/1000);

[EEG]=eeg_checkset(EEG);

[ALLEEG EEG CURRENTSET] = pop_newset( ALLEEG, EEG, CURRENTSET,'setname',strcat('PX',EEG.setname),'overwrite','off');

eeglab redraw

com=['[EEG LASTCOM]=pop_cpl_powerspectrum(EEG);'];

disp('Spectral decomposition complete....')

disp('WARNING: EEG structure has been modified. Use caution.');