-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalcSpect.m
121 lines (100 loc) · 3.89 KB
/
calcSpect.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
function [S, BL] = calcSpect(S, BL, fRange, Fs, timeWindow, saveEvSpect)
%% [S, BL] = calcSpect(S, BL, fRange, Fs, timeWindow, saveEvSpect)
%
% Function to calculate Z-scored time-frequency spectrogram for series of
% events or entire duration of file. Can normalize Z-score to baseline period
% for comparisons
% Handle input arguments - if not entered
if (nargin < 6); saveEvSpect = 0; end % If true and > 1 tSeries will save all event spectra (Caution - large files)
if (nargin < 5); timeWindow = 30; end % ms
if (nargin < 4); Fs = 20000; end % Hz
if (nargin < 3); fRange = 1:500; end % Hz
% Reset spect structure
S.spect = struct;
% Initialize temporary tSeries cell array structure (to handle both full tSeries and series of events)
if isfield(S,'event') && ~isfield(S,'tSeries')
tSeries = S.event;
elseif isfield(S,'tSeries')
tSeries{1} = S.tSeries;
else
error("no relevant tSeries found for spectogram")
end
% Set spectrogram parameters
nWin = round(3 * timeWindow * Fs / 1000);
nOv = round(0.8 * nWin);
spectSamples = max(cellfun(@length, tSeries));
% Calculate baseline spectrogram (if supplied)
if ~isempty(BL)
if ~isfield(BL,'spect'); BL.spect = struct; end
[~, BL.spect.fRange, BL.spect.tRange, BL.spect.power] = spectrogram(BL.tSeries, nWin, nOv, fRange, Fs, 'yaxis');
pAve = mean(BL.spect.power, 2);
pStd = std(BL.spect.power, 0, 2);
pAve = pAve(:,ones(1, length(BL.spect.tRange)));
pStd = pStd(:,ones(1, length(BL.spect.tRange)));
BL.spect.pZScore = (BL.spect.power - pAve) ./ pStd;
BL.spect = orderStruct(BL.spect);
end
% Count number of valid tSeries to determine size for array initialization:
fTemp = [];
tTemp = [];
ev = 0;
for i = 1:length(tSeries)
if ~isempty(tSeries{i}) && (length(tSeries{i}) == spectSamples)
if isempty(fTemp) % only calculate fTemp and tTemp once at this stage
[~, fTemp, tTemp, ~] = spectrogram(tSeries{i}, nWin, nOv, fRange, Fs, 'yaxis');
end
ev = ev + 1;
end
end
power = zeros(length(fTemp), length(tTemp), ev);
% Spectral Analysis of valid tSeries:
ev = 1;
for i = 1:length(tSeries)
if ~isempty(tSeries{i}) && (length(tSeries{i}) == spectSamples)
[~, S.spect.fRange, S.spect.tRange, power(:,:,ev)] = spectrogram(tSeries{i}, nWin, nOv, fRange, Fs, 'yaxis');
% Normalize to spectrogram unless baseline supplied:
if isempty(BL)
pAve = mean(power, 2);
pStd = std(power, 0, 2);
pAve = pAve(:,ones(1, length(S.spect.tRange)));
pStd = pStd(:,ones(1, length(S.spect.tRange)));
else
pAve = mean(BL.spect.power, 2);
pStd = std(BL.spect.power, 0, 2);
pAve = pAve(:,ones(1, length(S.spect.tRange)));
pStd = pStd(:,ones(1, length(S.spect.tRange)));
end
% Calculate Z-score for each tSeries
pZScore = (power - pAve) ./ pStd;
ev = ev + 1;
end
end
% Calculate and save average spectrogram if more than one tSeries:
if length(tSeries) > 1
% Save all event spectra if option selected:
if saveEvSpect
S.spect.power = power;
S.spect.pZScore = pZScore;
end
S.spect.powerAve = mean(power, 3);
S.spect.pZScoreAve = mean(pZScore, 3);
% % Normalize to average spectrogram unless baseline supplied:
% if isempty(BL)
% pAve = mean(S.spect.powerAve, 2);
% pStd = std(S.spect.powerAve, 0, 2);
% pAve = pAve(:,ones(1, length(S.spect.tRange)));
% pStd = pStd(:,ones(1, length(S.spect.tRange)));
% else
% pAve = mean(BL.spect.power, 2);
% pStd = std(BL.spect.power, 0, 2);
% pAve = pAve(:,ones(1, length(S.spect.tRange)));
% pStd = pStd(:,ones(1, length(S.spect.tRange)));
% end
%
% S.spect.pZScoreAve = (S.spect.powerAve - pAve) ./ pStd;
else % only one tSeries - save spectra
S.spect.power = power;
S.spect.pZScore = pZScore;
end
S.spect = orderStruct(S.spect);
end