-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspectraYW.m
147 lines (129 loc) · 3.2 KB
/
spectraYW.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
function [P,varargout] = spectraYW(varargin)
%This function computes the 2D spectrum
%of an input signal using standard FFT
%for time (along dimension 1), and the
%Maximum Entropy Method implemented with the
%Yule-Walker equations (along dimension 2).
%Data are linear detrended and time windowed with a
%Hanning(NFFT) window
%
%INPUT:
%
% X : signal
% NFFT : number of points to compute the FFT in time.
% Default: 2048
% OV : Number of overlapping points between windows in temporal
% FFT. Default: 1024
% N : order of the Autoregressive model used to
% estimate the spatial spectrum. Default: 4
% tsampfreq : time sampling. Default: 1 s
% ssampfreq : spatial sampling. Default: 1 cm
%
%OUTPUT:
%
% P : Spectrum (complex in general)
% f : time frequency in units of [1/tsampfreq]. To be multiplied by
% 2*pi in order to obtain units of rad/s
% k : spatial frequency (to be multiplied by 2*pi in order
% to obtain rad/cm
%
%USAGE:
%
% [P,f,k]=spectraYW(x,NFFT,OV,N,tsampfreq,ssampfreq);
%
% A. Marinoni, 29/03/2012
def={2048;1024;4;1;1};
variab={'x';'nfft';'ov';'N';'tsampfreq';'ssampfreq'};
switch nargin
case 0
disp('Insufficient number of inputs')
P=[];
return
otherwise
x=varargin{1};
for i=2:nargin
if isempty(varargin{i})
eval(strcat([variab{i},'=[];']));
else
eval(strcat([variab{i},'=',num2str(varargin{i}),';']));
end
end
for i=nargin+1:length(variab)-1
if isempty(def{i-1})
eval(strcat([variab{i},'=[];']));
else
eval(strcat([variab{i},'=',num2str(def{i-1})],';'));
end
end
end
%Checking inputs
for i=1:length(variab)
if ~eval(strcat(['isnumeric(',variab{i},')']))
disp('Incorrect format for ',variab{i})
P=[];
return
end
end
if ndims(x)~=2
disp('Input signal must be two dimensional')
P=[];
return;
end
if ~isreal(x)
disp('Input signal must be real')
P=[];
return;
end
if ov>nfft
disp('Overlap cannot exceed time window length. Forcing nov=nfft/2')
ov=floor(nfft/2);
end
[n1,n2]=size(x);
%Calculating the number of columns of the FFT
ncol=fix((n1-ov)/(nfft-ov));
disp(strcat(['Data divided into ',num2str(ncol),...
' segments of ',num2str((nfft-1)/tsampfreq),' s']))
% Pre-process X
rowindex=1+(0:(ncol-1))*(nfft-ov);
colindex=(1:nfft)';
x=x.*(ones(n1,1)*hann(n2)');
y=[];
disp('Computing temporal FFT')
for j=1:ncol
y=[y x(rowindex(j):rowindex(j)+nfft-1,:)];
end
%Detrend
%y=detrend(y);
%Windowing
win=hann(nfft);
y=y.*(win*ones(1,ncol*n2));
%Compute FFT
z=fft(y,nfft);
z=z(1:ceil(nfft/2),:);
y=0;
for i=1:ncol
y=z(:,1+(j-1)*n2:j*n2)+y;
end
y=y/ncol;
%Time frequency vector
f=[0:nfft-1];
f=f/(nfft-1)*tsampfreq;
f=f(1:ceil(nfft/2));
k=[0:n2-1]/(n2-1)*ssampfreq;
k=k-k(ceil(n2/2));
nf=length(f);
disp('Computing spatial Fourier transform')
%Computing Spatial spectrum and averaging over windows
P=zeros(n2,nf);
for i=1:nf
P(:,i)=pyulear(y(i,:),N,n2,'twosided');
end
%Transposing and averaging
P=P'/ncol;
%Renormalization to compensate for the power of the windows
fac=sum(win)/nfft;
fac2=sum(hann(n2))/n2;
P=P/fac^2/fac2^2;
P=fftshift(P,2);
varargout{1}=f;
varargout{2}=k;