Code covered by the BSD License  

Highlights from
Power spectral estimation with error bars

image thumbnail
from Power spectral estimation with error bars by Rune W Berg
Power spectral estimation using multitaper, single or multiple traces and estimating error bars.

Power_multi_traces(trace_a,num_win,dt,paddingtimes)
function c = Power_multi_traces(trace_a,num_win,dt,paddingtimes)

%   This procedure calculates the averaged single-sided power spectral density with proper normalization, so
%   that if the signal is given in volts, the value is truely the power (with unit resistance). The output unit is (input trace unit)^2/Hz.
%   It uses multiple tapers to window the data, and thereafter performs
%   a padding. The procedure is inspired by the procedure from the chronux.org software 
%	package.
% 
%   The bandwidth of the spectrum 2W is determined by the relation:
%   2W =(2K-1)/T where N is the number of spectral estimates (num_win) and T 
%   is total length of the trace in time. So for instance, 5 windows and 2 sec trace gives
%   a bandwidth of 4.5 Hz.
%
%   The averaging is taken over both the trials (2nd dimension of trace_a) and
%   over multiple tapers (estimates of spectrum for a single trial).
%   These different estimates of the spectrum is also use to
%   calculate standard error of the estimates by boot strap technique.
% 
%	INPUT:
%  	"trace_a" is the array or matrix containing the trace that is the basis for
%	spectral estimation. The each row is a trial and each column is a data point sample
% 	at a period of "dt".  trace_a can be one-dimensional in the special case of a single
%	recording trace. Multiple traces give a better estimate but stationarity is required.
%	"num_win" is the number of tapers - 5-10 is usually good. 
%	"paddingtimes" gives you an artificial increase in spectral resolution- 5-10 times 
%	is usually good. This value slows down the estimation. 
%  
%   OUTPUT:
%   c(:,1) = frequency base
%   c(:,2) = averaged power spectral density (single sided) Unit is [(input trace unit)^2/Hz].
%   c(:,3) = standard error as a function of frequency. 2*SE provides a 95%
%   confidence limit.
%
%   Rune W. Berg, 2009
%   rune@berg-lab.net    
%	www.berg-lab.net
%
%	References:
%
%	Berg RW, Whitmer D, Kleinfeld D. Exploratory whisking by rat is not phase locked to the hippocampal theta rhythm. J Neurosci 2006;26:6518–22.
%	Thomson DJ (1982) Spectral estimation and harmonic analysis. Proc IEEE 70:1055–1096. 
%	Percival DB, Walden AT (1993) Spectral analysis for physical applications: multitaper and conventional univariate techniques, Chap 6. Cambridge,UK: Cambridge UP.
%	Jarvis MR, Mitra PP (2001) Sampling properties of the spectrum and coherency of sequences of action potentials. Neural Comput 13:717–749.
%



if size(trace_a,2) > size(trace_a,1)  %Assuming more data points than traces
    trace_a=trace_a';
end

npp=size(trace_a,1);
np_traces=size(trace_a,2);
windows=dpss(npp,num_win/2);  % Defining window functions, using discrete prolate spherical sequences (Percival and Walden 1998).
fs=1./(dt);fmax=1./(2*dt)   ;% Maximum frequency with unit is Hz

for j=1:np_traces
    trace_b(:,j)=trace_a(:,j)-mean(trace_a(:,j)); % Removing off-set
end

for j=1:np_traces
    % Loop for spectral averaging over windows
    for i=1:num_win
        aa=fft(padding(trace_b(:,j).*windows(:,i),paddingtimes));
        bb=conj(aa);                            %Complex conjugation
        u=sum(windows(:,i).*windows(:,i)) ;     %/npp;  % the mean square of the window function (power from window).
    %    norm_a=fs*u*npp*paddingtimes/2  ;      %Normalization.  fs = sampling freq and u is the window,
        norm_a=u*npp*paddingtimes/2  ;          %Normalization.  fs = sampling freq and u is the window,                                                      %and the factor of 2 is for single sided power.
        pow_a(:,i+(j-1)*num_win)= aa.*bb/norm_a;              %np is length, which is increased when padding,  
    end
end

newnpp=size(pow_a,1);               % Length of padded power spectrum 
df=fmax./(round((newnpp/2)-1));     % Frequency resolution.
n_estimates=np_traces*num_win;

% Total mean power spectral density (power per frequency).
px=sum(pow_a,2)/(size(pow_a,2)*df);

% Delete one array spectrum:

baseset=1:n_estimates;

for k=1:n_estimates    
    setN=find(k~=baseset);
    pow_deleteone(:,k)=sum(pow_a(:,setN),2)/(n_estimates-1);
end

%  Calulating the standard error of the power spectral estimate (boot strap):

for ii=1:newnpp
    sigma_px(ii)=sqrt(((n_estimates-1)/n_estimates)*sum( (pow_deleteone(ii,:) - px(ii)).^2,2));
end

pxx=px(1:round(newnpp/2))   ;    % Disregarding the negative frequencies.
freqa=0:round((newnpp/2)-1);     % The frequency vector
sigma_px2=sigma_px(1:round(newnpp/2));

freq=freqa*df;  % Defining frequency trace with proper resolution, df.
c(:,1)=freq;
c(:,2)=pxx;
c(:,3)=sigma_px2';


function out=padding(xx,ntimes)
% this function add zeros around the trace xx, so that is is ntimes the
% original length. The mean of the trace is also removed.
% Rune W. Berg 2008

xx=xx-mean(xx); np=length(xx); xxp(1:np)=xx;
if ntimes > 0
    xxp(np+1:ntimes*np)=0;
end
out=xxp;

Contact us at files@mathworks.com