-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdelayEmbedData.m
More file actions
157 lines (139 loc) · 5.63 KB
/
delayEmbedData.m
File metadata and controls
157 lines (139 loc) · 5.63 KB
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
148
149
150
151
152
153
154
155
function [delayedTrace, embeddedTime] = delayEmbedData(activityTrace, delayTime, delayCount, useDerivative, useZScore, smoothSigma, shouldDetrend, verbose)
% findPhaseSpace : This function pre-processes a multivariate time series
% datastream and applies delay embedding in an effort to reconstruct phase
% space.
%
% INPUT :
% activityTrace : n by t time series data where n are the number of
% dimensions and t are the temporally sequenced observations
% delayTime : Integer. Number of times to delay embed
% delayCount : Integer. Number of timesteps to delay per embedding
% useDerivative (optional) : Logical (Default 0). Toggles appending of the derivatives of the time series data to the delay embedded space
% useZScore (optional) : Logical (Default 0). Toggles zscoring of the delayed data (both activity and derivatives)
% shouldDetrend (optional) : Logical (Default 0). Toggles detrending of the data prior to delay embedding
% smoothSigma (optional) : Positive double (Default 0). Sigma of Gaussian (in timesteps) of smoothing kernel to be applied to the data
% verbose (optional) : Logical (Default 0). Toggles drawing of intermediate steps
%
% OUTPUT :
% delayedTrace : Delay embedding of activity trace. Size of this trace is:
% (n * delayCount * [2 if useDerivative is true]) by
% (t - delayCount * delayTime - [1 if useDerivative is true]).
% Rows of this matrix are order from top to bottom as:
% activity(1:n,t), derivative(1,:n,t) if useDerivative is true,
% activity(1:n,t-1*delayTime), derivative(1,:n,t-1*delayTime) if useDerivative is true,
% etc until:
% activity(1:n,t-delayCount*delayTime), derivative(1,:n,t-delayCount*delayTime) if useDerivative is true,
% embeddedTime: The total time offset induced by the embedding. delayTime * delayCount + useDerivative
% This can be used to convert from the original timesteps, t, to delay
% embedded timesteps, tao, by: t = tao - embeddedTime
%
% Copyright (C) 2019 Proekt Lab
% Written by Connor Brennan.
% University of Pennsylvania, 2019
% This file is part of functions for Brennan and Proekt. eLife 2019.
%
% This script is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This script 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. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this script. If not, see <http://www.gnu.org/licenses/>.
%% Default options
if ~exist('verbose') || isempty(verbose)
DISPLAY = 0;
else
DISPLAY = verbose;
end
%Preprocessing options
if ~exist('useDerivative') || isempty(useDerivative) %Should the phase space be appended with the derivatives?
USE_DERIVATIVES = 1;
else
USE_DERIVATIVES = useDerivative;
end
if ~exist('useZScore') || isempty(useZScore) %Should the data be zscored before delay embedding?
USE_ZSCORE = 0;
else
USE_ZSCORE = useZScore;
end
if ~exist('shouldDetrend') || isempty(shouldDetrend) %Should the data be detrended?
DETREND = 0;
else
DETREND = shouldDetrend;
end
if ~exist('smoothSigma') || isempty(smoothSigma)%Amount of smoothing to apply to the time series
SMOOTH_SIGMA = 0;
else
SMOOTH_SIGMA = smoothSigma;
end
%Delay embedding options
DELTA_T = delayTime;
NUM_T = delayCount;
%% Start method
neuronData = activityTrace;
if DETREND
neuronDataDetrended = detrend(neuronData);
else
neuronDataDetrended = neuronData;
end
if SMOOTH_SIGMA > 0
sigma = SMOOTH_SIGMA;
x = floor(-3*sigma):floor(3*sigma);
filterSize = numel(x);
gaussian = exp(-x.^2/(2*sigma^2))/(2*sigma^2*pi)^0.5;
filteredTrace = neuronDataDetrended;
filteredTrace = cat(2, repmat(filteredTrace(:,1),[1,filterSize]), filteredTrace, repmat(filteredTrace(:,end),[1,filterSize]));
filteredTrace = convn(filteredTrace, gaussian, 'same');
neuronDataDetrended = filteredTrace(:,filterSize+1:end-filterSize);
end
neuronDataDiff = [];
if USE_DERIVATIVES
filteredTrace = diff(neuronDataDetrended,1,2);
neuronDataDiff(:,:) = [zeros(size(neuronDataDetrended,1)), filteredTrace];
end
%%
embeddedTime = NUM_T*DELTA_T + USE_DERIVATIVES;
stateSpace = [];
index = 1;
for i = 1 + embeddedTime:size(neuronDataDetrended, 2)
thisVector = [];
for j = 0:NUM_T
thisVector = [thisVector; neuronDataDetrended(:,i - j*DELTA_T)];
if USE_DERIVATIVES
thisVector = [thisVector; neuronDataDiff(:,i - j*DELTA_T)];
end
end
stateSpace(:,index) = thisVector;
index = index + 1;
end
if USE_ZSCORE
stateSpace = zscore(stateSpace, 0, 2);
end
delayedTrace = stateSpace;
if DISPLAY
figure(3);
clf;
[~, pcaScores] = pca(delayedTrace', 'NumComponents', 3);
startPCA = 1;
score = pcaScores(:,startPCA:startPCA+2);
indices = 1:size(score,1);
% vectors = [];
% for i = 1:size(score, 1)-1
% vectors(i,:) = score(i + 1,:) - score(i,:);
% end
% vectors(size(score, 1),:) = [0, 0, 0];
hold on;
% quiver3(score(indices,1),score(indices,2),score(indices,3),vectors(:,1),vectors(:,2),vectors(:,3),3);
plot3(score(indices,1),score(indices,2),score(indices,3));
colormap(jet(256));
caxis([1 8])
xlabel('DPCA 1');
ylabel('DPCA 2');
zlabel('DPCA 3');
title('PCA of delay embedded data');
end