-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRemoveBaselineAcc.m
236 lines (183 loc) · 10.1 KB
/
RemoveBaselineAcc.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
%RemoveBaselineAcc
%This script removes the tailored baseline acceleration from each trial. By
%default, this script performs this as done in Kurtzer 2020, based on the
%lateral acceleration only. However, this script can also include other
%variables, such as lateral position and heading to better match the
%trajectories.
%
%The algorithm steps through each trial that is marked as included. For
%each non-baseline trial, the algorithm ranks the baseline trials based on
%similarity to the trial in question The most similar baseline
%trajectories are averaged and this average is removed from the trial in
%question.
%
%Before running this script, the data should be loaded into the MATLAB
%workspace, in a variable named "data"
%pull something from all included trials to determine total number of
%trials that are included:
n_exp = length(data.subject(1).exp);
n_sub = length(data.subject);
try
temp = pullData(data, [1:n_sub],[1:n_exp],'Perturb','included','condition');
catch
temp = pullData(data, [1:12],[1:2],'Perturb','included','condition');
end
header = {'Subject','Experiment','Condition','Trial','Dir 1','Dir 2','RT 1','RT 2'};
outdata = nan(length(temp), length(header));
outdata = num2cell(outdata);
outcount = 1;
tx = 0.0; %time to look for RT
win = 90; %window size to look at
thresh = 6; %threshold for maximum tolerable score
targx_coord = [-5, -3, -1, 1, 3, 5]; %x location of targets
targx_coord = [-10:1:10]; %x location of targets
yy = 20; %y location of targets
r = 0.75; %radius of target
for sn = 1:n_sub
disp(['Processing Subject ', num2str(sn)]);
for en = 1:length(data.subject(1).exp)
%assemble a matrix of headings and x postions at +100 ms from
%baseline trials:
en_b = en;
ts_b = pullData(data, sn, en_b, 1, 'included','Time_rel_Cue');
xs_b = pullData(data, sn, en_b, 1, 'included','Right_HandX');
heads_b = pullData(data, sn, en_b, 1, 'included','Heading');
diff_heads_b = pullData(data, sn, en_b, 1, 'included','Change in Heading smoothed');
xacc_b = pullData(data, sn, en_b, 1, 'included','Right_HandX_Acc');
% xacc_b = pullData(data, sn, en_b, 1, 'included','Xacc_nobaseline');
xacc_bns = pullData(data, sn, en_b, 1, 'included','Right_HandX_Acc');
% xacc_bns = pullData(data, sn, en_b, 1, 'included','Xacc_nobaseline');
factors = cell(length(ts_b),3);
norm_factors = zeros(2,3);
lengths = nan(1,length(xs_b)); %vector containing lengths of each baseline trial
start_inds = nan(1,length(xs_b)); %vector containing t = 0 points of each baseline trial
%assemble a cell of all the timepoints of baseline trials to
%consider. While doing this, identify the max and min of each data
%type for normalization purposes.
for ii = 1:length(ts_b)
[~,ind] = min(abs(ts_b{ii}-tx));
factors{ii,1} = xs_b{ii}(ind+[1:win]);
factors{ii,2} = heads_b{ii}(ind+[1:win]);
factors{ii,3} = xacc_b{ii}(ind+[1:win]);
for jj = 1:3
if max(factors{ii,jj}) > norm_factors(1,jj)
norm_factors(1,jj) = max(factors{ii,jj});
end
if min(factors{ii,jj}) < norm_factors(2,jj)
norm_factors(2,jj) = min(factors{ii,jj});
end
end
lengths(ii) = length(xs_b{ii});
start_inds(ii) = ind-tx*1000-100; %start ind is taken as 100 ms BEFORE the t = 0
end
%normalize the data:
[ntrials, nfacs] = size(factors);
for ii = 1:ntrials
for jj = 1:nfacs
factors{ii,jj} = (factors{ii,jj} - norm_factors(2,jj))./(norm_factors(1,jj)-norm_factors(2,jj));
end
end
%now pull all the non-baseline trials:
conds = 2:length(data.subject(sn).exp(en).condition);
% conds = 1:length(data.subject(sn).exp(en).condition);
% conds = 1;
trial_type = 'all';
[ts, listing] = pullData(data, sn, en, conds, trial_type,'Time_rel_Cue');
xs = pullData(data, sn, en, conds, trial_type,'Right_HandX');
ys = pullData(data, sn, en, conds, trial_type,'Right_HandY');
% heads = pullData(data, sn, en, conds, trial_type,'Heading');
heads = pullData(data, sn, en, conds, trial_type,'Right_HandX_Vel');
diffheads = pullData(data, sn, en, conds, trial_type,'Change in Heading smoothed');
xaccs = pullData(data, sn, en, conds, trial_type,'Right_HandX_Acc_smoothed');
xaccsns = pullData(data, sn, en, conds, trial_type,'Right_HandX_Acc');
%copy over the subject, exp, cond, trial info:
outdata(outcount+[1:length(listing)],1:4) = num2cell(listing);
%step thru each trial and remove the average baseline acceleration:
for ii = 1:length(ts)
sn = listing(ii,1);
en = listing(ii,2);
cn = listing(ii,3);
tn = listing(ii,4);
%initialize data:
% data.subject(sn).exp(en).condition(cn).Xacc_nobaseline{tn} = [];
% data.subject(sn).exp(en).condition(cn).RTInd(tn,1:2) = {NaN,NaN};
[~,ind] = min(abs(ts{ii}-tx)); %time = 100 ms
a = xs{ii}(ind+[1:win]);
b = heads{ii}(ind+[1:win]);
c = xaccs{ii}(ind+[1:win]);
%normalize this data the same as baseline data:
a = (a - norm_factors(2,1))/(norm_factors(1,1)-norm_factors(2,1));
b = (b - norm_factors(2,2))/(norm_factors(1,2)-norm_factors(2,2));
c = (c - norm_factors(2,3))/(norm_factors(1,3)-norm_factors(2,3));
%calculate "match" scores:
scores = nan(ntrials,1);
for jj = 1:ntrials
% scores(jj) = sum(sqrt((1.*(a-factors{jj,1})).^2 + 1.*(b-factors{jj,2}).^2 + 1*(c-factors{jj,3}).^2)); %This caluclation incorporates all factors (x position, heading, and x acc)
scores(jj) = sum(sqrt((mean(c)-mean(factors{jj,3})).^2));
end
%sort scores in ascending order:
[scores_sorted, sort_ind] = sort(scores);
scores_keep = zeros(size(scores_sorted));
%Two ways to identify best matches:
%Method 1 (default): keep top 10 best scores:
if cn == 1
scores_keep(2:11) = 1; %skip the first one, as that is the trial in question (don't want to use the same trial for the average)
else
scores_keep(1:10) = 1;
end
%Method 2: keep top scores under a certain threshold: (not
%currently used)
% scores_keep = scores_sorted < thresh;
%If there are less than 3 similar trials, skip this trial and exclude it:
if sum(scores_keep) < 3
disp(['Not enough matching baseline S',num2str(sn), ' E', num2str(en), ' C', num2str(cn), ' T', num2str(tn)])
data.subject(sn).exp(en).condition(cn).IsIncluded{tn} = false;
data.subject(sn).exp(en).condition(cn).RTInd(tn,:) = {[];[]};
continue
elseif sum(scores_keep) > 30
%if there are more than 30 similar trials, take only the 30
%best matching trials: (this is only for METHOD 2 above,
%and will do nothing in Method 1, as by definition the top
%10 matches are included)
scores_keep = scores_keep(1:30);
end
avg_data = nan(sum(scores_keep),max(lengths),4);
ys_b = pullData(data, sn, en_b, 1, 'included','Right_HandY');
for jj = 1:sum(scores_keep)
thisind = sort_ind(jj);
% plot(ax1,xs_b{thisind},ys_b{thisind},'k');
% plot(ax2,ts_b{thisind},xs_b{thisind},'k');
temp = xs_b{thisind}(start_inds(thisind):end); %data for this baseline trial to include in avg
avg_data(jj,1:length(temp),2) = temp;
% plot(ax3,ts_b{thisind},xacc_b{thisind},'k');
temp = xacc_bns{thisind}(start_inds(thisind):end); %data for this baseline trial to include in avg
avg_data(jj,1:length(temp),3) = temp;
% plot(ax4,ts_b{thisind},diff_heads_b{thisind},'k');
temp = diff_heads_b{thisind}(start_inds(thisind):end); %data for this baseline trial to include in avg
avg_data(jj,1:length(temp),4) = temp;
% plot(ax5, ts_b{thisind}, ys_b{thisind},'k');
end
avg_data_old = avg_data;
std_data = nanstd(avg_data);
avg_data = nanmean(avg_data);
avg_data = reshape(avg_data,max(lengths),4);
std_data = reshape(std_data,max(lengths),4);
%trim data to same size:
lens = [length(avg_data(:,3)),length(xaccs{ii}(ind-tx*1000+1:end))];
enpt = min(lens);
%subtract the average acceleration from this trial's
%acceleration:
newacc = xaccsns{ii};
newacc(ind-tx*1000-100+[1:enpt]) = newacc(ind-tx*1000-100+[1:enpt]) - avg_data(1:enpt,3);
if cn ~= 1
%also demean the trial acceleration in this window:
newacc = newacc - mean(newacc(ind+[0:win]));
end
%save this new acceleration:
data.subject(sn).exp(en).condition(cn).Xacc_nobaseline{tn} = newacc;
outcount = outcount+1;
end
end
end
disp('');
disp('Processing Complete');