Skip to content

Commit 5116e47

Browse files
committed
Added function to recompute of events and parameters in exp and labData
1 parent f1cc2f5 commit 5116e47

File tree

2 files changed

+79
-65
lines changed

2 files changed

+79
-65
lines changed

classes/dataStructs/@processedLabData/processedLabData.m

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
%processedLabData methods:
1515
%
1616
% getProcEMGData - accessor for processed EMGs
17-
% getProcEMGList - returns list of processed EMG labels
18-
% getPartialGaitEvents - accessor for specific events
19-
% getEventList - returns list of event labels
20-
% getAngleData - accessor for angle data
21-
% getParam - accessor for adaptation parameters
22-
% getExpParam - accessor for experimental adaptation parameters
23-
% calcAdaptParams - re-computes adaptation parameters
24-
%
17+
% getProcEMGList - returns list of processed EMG labels
18+
% getPartialGaitEvents - accessor for specific events
19+
% getEventList - returns list of event labels
20+
% getAngleData - accessor for angle data
21+
% getParam - accessor for adaptation parameters
22+
% getExpParam - accessor for experimental adaptation parameters
23+
% calcAdaptParams - re-computes adaptation parameters
24+
%
2525
% separateIntoStrides - ?
2626
% separateIntoSuperStrides - ?
2727
% separateIntoDoubleStrides - ?
@@ -30,7 +30,7 @@
3030
% getAlignedField - ?
3131
%
3232
%See also: labData, labTimeSeries, processedEMGTimeSeries, parameterSeries
33-
33+
3434
%%
3535
properties %(SetAccess= private) Cannot set to private, because labData will try to set it when using split()
3636
gaitEvents %labTS
@@ -42,15 +42,15 @@
4242
COMData
4343
jointMomentsData
4444
end
45-
46-
properties (Dependent)
45+
46+
properties (Dependent)
4747
isSingleStride %ever used?
4848
experimentalParams
4949
end
50-
50+
5151
%%
5252
methods
53-
53+
5454
%Constructor:
5555
function this=processedLabData(metaData,markerData,EMGData,GRFData,beltSpeedSetData,beltSpeedReadData,accData,EEGData,footSwitches,events,procEMG,angleData,COPData,COMData,jointMomentsData) %All arguments are mandatory
5656
if nargin<15 %metaData does not get replaced!
@@ -97,55 +97,57 @@
9797
function this=set.angleData(this,angleData)
9898
if isa(angleData,'labTimeSeries') || isempty(angleData)
9999
this.angleData=angleData;
100-
else
100+
else
101101
ME=MException('processedLabData:Constructor','angleData parameter is not a labTimeSeries object.');
102102
throw(ME);
103103
end
104104
end
105105
function this=set.adaptParams(this,adaptData)
106106
if isa(adaptData,'parameterSeries') || isa(adaptData,'labTimeSeries')
107107
this.adaptParams=adaptData;
108-
else
108+
else
109109
ME=MException('processedLabData:Constructor','adaptParams parameter is not a parameterSeries object.');
110110
throw(ME);
111111
end
112112
end
113-
113+
114114
%Access method for fields not defined in raw class.
115115
% function partialProcEMGData=getProcEMGData(this,muscleName)
116116
% partialProcEMGData=this.getPartialData('procEMGData',muscleName);
117117
% end
118-
%
118+
%
119119
% function list=getProcEMGList(this)
120120
% list=this.getLabelList('procEMGData');
121121
% end
122-
%
122+
%
123123
function partialGaitEvents=getPartialGaitEvents(this,eventName)
124124
partialGaitEvents=this.getPartialData('gaitEvents',eventName);
125125
end
126-
%
126+
%
127127
% function list=getEventList(this)
128128
% list=this.getLabelList('gaitEvents');
129129
% end
130-
%
130+
%
131131
% function partialAngleData= getAngleData(this,angleName)
132132
% partialAngleData=this.getPartialData('angleData',angleName);
133133
% end
134-
%
134+
%
135135
% function partialParamData=getParam(this,paramName)
136136
% partialParamData=this.getPartialData('adaptParams',paramName);
137137
% end
138-
%
138+
%
139139
% function partialParamData=getExpParam(this,paramName)
140140
% partialParamData=this.getPartialData('experimentalParams',paramName);
141141
% end
142-
142+
143143
function adaptParams=calcAdaptParams(this)
144-
adaptParams=calcParameters(this);
144+
adaptParams=calcParameters(this);
145145
end
146-
146+
147147
%Modifiers
148148
function reducedThis=reduce(this,eventLabels,N)
149+
%Aligns and resamples all timeseries to the same indexes and puts them all together in a single timeseries
150+
149151
%Define the events that will be used for all further computations
150152
if nargin<2 || isempty(eventLabels)
151153
refLeg=this.metaData.refLeg;
@@ -180,45 +182,54 @@
180182
allTS=allTS.cat(field.getDataAsTS(field.labels).renameLabels([],fieldLabels{end}).synchTo(allTS));
181183
end
182184
end
183-
185+
184186
%Align:
185187
[alignTS,bad]=allTS.align(this.gaitEvents,eventLabels,N);
186-
188+
187189
%Create reduced struct:
188190
reducedThis=reducedLabData(this.metaData,this.gaitEvents,alignTS,bad,reducedFields,fieldPrefixes,this.adaptParams); %Constructor
189191
warning('on','labTS:renameLabels:dont')
190192
end
191-
193+
194+
function newThis=recomputeEvents(this)
195+
%This should be a processedLabData method
196+
%This should force event recomputing too
197+
events = getEvents(this,this.angleData);
198+
this.gaitEvents=events;
199+
this.adaptParams=calcParameters(processedData,subData,eventClass);
200+
newThis=this;
201+
end
202+
192203
%Getters for dependent properties:
193204
function expParams=get.experimentalParams(this)
194205
expParams=calcExperimentalParams(this);
195206
end
196207

197208
function b=get.isSingleStride(this)
198-
b=isa(this,'strideData');
209+
b=isa(this,'strideData');
199210
end
200-
211+
201212
%Separate into strides!
202213
function [arrayedEvents]=getArrayedEvents(this,eventList)
203214
arrayedEvents=labTimeSeries.getArrayedEvents(this.gaitEvents,eventList);
204215
end
205216
function [steppedDataArray,initTime,endTime]=separateIntoStrides(this,triggerEvent) %Splitting into single strides!
206-
%triggerEvent needs to be one of the valid gaitEvent labels
207-
217+
%triggerEvent needs to be one of the valid gaitEvent labels
218+
208219
[numStrides,initTime,endTime]=getStrideInfo(this,triggerEvent);
209220
steppedDataArray={};
210221
for i=1:numStrides
211222
steppedDataArray{i}=this.split(initTime(i),endTime(i),'strideData');
212223
end
213224
end
214-
225+
215226
function [steppedDataArray,initTime,endTime]=separateIntoSuperStrides(this,triggerEvent) %SuperStride= 1.5 strides, the minimum unit we need to get our parameters consistently for an individual stride cycle
216-
%triggerEvent needs to be one of the valid gaitEvent labels
227+
%triggerEvent needs to be one of the valid gaitEvent labels
217228
%Determine end event (ex: if triggerEvent='LHS' then we
218-
%need 'RHS')
229+
%need 'RHS')
219230
if strcmp(triggerEvent(1),'L')
220231
contraLeg='R';
221-
else
232+
else
222233
contraLeg='L';
223234
end
224235
contraLateralTriggerEvent=[contraLeg triggerEvent(2:end)];
@@ -229,19 +240,19 @@
229240
steppedDataArray{i}=this.split(initTime(i),CendTime(find(CendTime>initTime(i),1,'first')),'strideData');
230241
end
231242
end
232-
243+
233244
function [steppedDataArray,initTime,endTime]=separateIntoDoubleStrides(this,triggerEvent) %DoubleStride= 2 full strides, the minimum unit we need to get our parameters consistently for an individual stride cycle
234245
%Version deprecated on Apr 2nd 2015
235-
%triggerEvent needs to be one of the valid gaitEvent labels
246+
%triggerEvent needs to be one of the valid gaitEvent labels
236247
[strideIdxs,initTime,endTime]=getStrideInfo(this,triggerEvent);
237248
steppedDataArray={};
238249
for i=strideIdxs(1:end-1)
239250
steppedDataArray{i}=this.split(initTime(i),endTime(i+1),'strideData');
240251
end
241252
end
242-
253+
243254
function [numStrides,initTime,endTime]=getStrideInfo(this,triggerEvent,endEvent)
244-
255+
245256
if nargin<2 || isempty(triggerEvent)
246257
triggerEvent=[this.metaData.refLeg 'HS']; %Using refLeg's HS as default event for striding.
247258
end
@@ -259,7 +270,7 @@
259270
endTime=arrayedEvents(:,2);
260271
end
261272
numStrides=size(initTime,1);
262-
273+
263274
% refLegEventList=this.getPartialGaitEvents(triggerEvent);
264275
% refIdxLst=find(refLegEventList==1);
265276
% auxTime=this.gaitEvents.Time;
@@ -274,7 +285,7 @@
274285
% noEnd=true;
275286
% while i<numStrides && noEnd %This is an infinite loop...
276287
% i=i+1;
277-
% aux=auxTime(find(endIdxLst>refIdxLst(i),1,'first'));
288+
% aux=auxTime(find(endIdxLst>refIdxLst(i),1,'first'));
278289
% if ~isempty(aux)
279290
% endTime(i)=aux;
280291
% else
@@ -283,18 +294,18 @@
283294
% end
284295
% end
285296
end
286-
297+
287298
function [numSteps,initTime,endTime,initEventSide]=getStepInfo(this,triggerEvent)
288299
if nargin<2 || isempty(triggerEvent)
289300
triggerEvent='HS'; %Using HS as default event for striding.
290301
end
291-
302+
292303
%Find starting events:
293304
rEventList=this.getPartialGaitEvents(['R' triggerEvent]);
294305
rIdxLst=find(rEventList==1);
295306
lEventList=this.getPartialGaitEvents(['L' triggerEvent]);
296307
lIdxLst=find(lEventList==1);
297-
308+
298309
auxTime=this.gaitEvents.Time;
299310

300311
i=0;
@@ -314,11 +325,11 @@
314325
while noEnd %This is an infinite loop...
315326
i=i+1;
316327
if lastSideRight
317-
aux=find(auxTime(lIdxLst)>initTime(i),1,'first');
328+
aux=find(auxTime(lIdxLst)>initTime(i),1,'first');
318329
t=auxTime(lIdxLst(aux));
319330
initEventSide{i}='R';
320331
else
321-
aux=find(auxTime(rIdxLst)>initTime(i),1,'first');
332+
aux=find(auxTime(rIdxLst)>initTime(i),1,'first');
322333
t=auxTime(rIdxLst(aux));
323334
initEventSide{i}='L';
324335
end
@@ -334,7 +345,7 @@
334345
numSteps=i;
335346
end
336347
end
337-
348+
338349
function [stridedField,bad,initTime,events]=getStridedField(this,field,events)
339350
warning('This is very slow and has been deprecated. Please don''t use')
340351
if isa(events,'char')
@@ -360,23 +371,16 @@
360371
%Step 3: slice timeseries
361372
timeBreakpoints=[initTime, intermediateTimes]';
362373
[slicedTS,~,~]=sliceTS(this.(field),[timeBreakpoints(:); endTime(end)],0);
363-
374+
364375
%Step 4: reshape & set to [] the slices which didn't have
365376
%proper events
366377
stridedField=reshape(slicedTS,N,M)';
367378
end
368-
379+
369380
function [alignedField,bad]=getAlignedField(this,field,events,alignmentLengths)
370381
[alignedField,bad]=this.(field).align(this.gaitEvents,events,alignmentLengths);
371-
%originalDurations=[]; %This is now within the alignedTS
372-
%initTime=[]; %This is now within the alignedTS
373-
374-
%error('This function has been deprecated. Needs to be updated to using the new labTS.align()')
375-
%[stridedField,bad,initTime,events]=getStridedField(this,field,events);
376-
%[alignedField,originalDurations]=labTimeSeries.stridedTSToAlignedTS(stridedField(~bad,:),alignmentLengths);
377382
end
378383
end
379-
380-
381-
end
382384

385+
386+
end

classes/dataStructs/experimentData.m

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,10 @@
283283
end
284284
allTrialModels=m;
285285
end
286-
286+
287287
function this=checkMarkerHealth(this,refTrial)
288288
disp(['Checking marker health...'])
289-
289+
290290
%First: build models
291291
[allTrialModels,modelScore,badFlag]=extractMarkerModels(this);
292292

@@ -303,7 +303,7 @@
303303
try %If there is a model
304304
mm=allTrialModels{refTrial};
305305
fprintf(['Using trial ' num2str(refTrial) ' to train outlier detection model...\n'])
306-
mm.seeModel;
306+
mm.seeModel;
307307
catch
308308
%nop
309309
end
@@ -329,8 +329,8 @@
329329
end
330330
disp(['Outlier data added in Quality field']);
331331
end
332-
333-
332+
333+
334334
function this=computeAngles(this)%added by Digna
335335
for trial=1:length(this.data)
336336
disp(['Computing angles for trial ' num2str(trial) '...'])
@@ -470,7 +470,7 @@
470470
this.data{t}.adaptParams=this.data{t}.adaptParams.replaceParams(newParams);
471471
end
472472
end
473-
473+
474474
function this=flushAndRecomputeParameters(this,eventClass,initEventSide)
475475
%FLUSHANDRECOMPUTEPARAMETERS recomputes adaptParams for all labData
476476
%objects in experimentData.data
@@ -496,6 +496,16 @@
496496
end
497497
end
498498

499+
function this=recomputeEvents(this,eventClass,initEventSide)
500+
%RECOMPUTEEVENTS recomputes events AND parameters for all trials,
501+
%with default options.
502+
%See also: processedLabData.recomputeEvents
503+
trials=cell2mat(this.metaData.trialsInCondition);
504+
for t=trials
505+
this.data{t}=recomputeEvents(this.data{t}); %This recomputes events AND recomputes parameters (otherwise parameters will not correspond to the new events)
506+
end
507+
end
508+
499509
function stridedExp=splitIntoStrides(this,refEvent)
500510
%This might not be used?
501511
if ~this.isStepped && this.isProcessed

0 commit comments

Comments
 (0)