|
14 | 14 | %processedLabData methods:
|
15 | 15 | %
|
16 | 16 | % 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 | + % |
25 | 25 | % separateIntoStrides - ?
|
26 | 26 | % separateIntoSuperStrides - ?
|
27 | 27 | % separateIntoDoubleStrides - ?
|
|
30 | 30 | % getAlignedField - ?
|
31 | 31 | %
|
32 | 32 | %See also: labData, labTimeSeries, processedEMGTimeSeries, parameterSeries
|
33 |
| - |
| 33 | + |
34 | 34 | %%
|
35 | 35 | properties %(SetAccess= private) Cannot set to private, because labData will try to set it when using split()
|
36 | 36 | gaitEvents %labTS
|
|
42 | 42 | COMData
|
43 | 43 | jointMomentsData
|
44 | 44 | end
|
45 |
| - |
46 |
| - properties (Dependent) |
| 45 | + |
| 46 | + properties (Dependent) |
47 | 47 | isSingleStride %ever used?
|
48 | 48 | experimentalParams
|
49 | 49 | end
|
50 |
| - |
| 50 | + |
51 | 51 | %%
|
52 | 52 | methods
|
53 |
| - |
| 53 | + |
54 | 54 | %Constructor:
|
55 | 55 | function this=processedLabData(metaData,markerData,EMGData,GRFData,beltSpeedSetData,beltSpeedReadData,accData,EEGData,footSwitches,events,procEMG,angleData,COPData,COMData,jointMomentsData) %All arguments are mandatory
|
56 | 56 | if nargin<15 %metaData does not get replaced!
|
|
97 | 97 | function this=set.angleData(this,angleData)
|
98 | 98 | if isa(angleData,'labTimeSeries') || isempty(angleData)
|
99 | 99 | this.angleData=angleData;
|
100 |
| - else |
| 100 | + else |
101 | 101 | ME=MException('processedLabData:Constructor','angleData parameter is not a labTimeSeries object.');
|
102 | 102 | throw(ME);
|
103 | 103 | end
|
104 | 104 | end
|
105 | 105 | function this=set.adaptParams(this,adaptData)
|
106 | 106 | if isa(adaptData,'parameterSeries') || isa(adaptData,'labTimeSeries')
|
107 | 107 | this.adaptParams=adaptData;
|
108 |
| - else |
| 108 | + else |
109 | 109 | ME=MException('processedLabData:Constructor','adaptParams parameter is not a parameterSeries object.');
|
110 | 110 | throw(ME);
|
111 | 111 | end
|
112 | 112 | end
|
113 |
| - |
| 113 | + |
114 | 114 | %Access method for fields not defined in raw class.
|
115 | 115 | % function partialProcEMGData=getProcEMGData(this,muscleName)
|
116 | 116 | % partialProcEMGData=this.getPartialData('procEMGData',muscleName);
|
117 | 117 | % end
|
118 |
| -% |
| 118 | +% |
119 | 119 | % function list=getProcEMGList(this)
|
120 | 120 | % list=this.getLabelList('procEMGData');
|
121 | 121 | % end
|
122 |
| -% |
| 122 | +% |
123 | 123 | function partialGaitEvents=getPartialGaitEvents(this,eventName)
|
124 | 124 | partialGaitEvents=this.getPartialData('gaitEvents',eventName);
|
125 | 125 | end
|
126 |
| -% |
| 126 | +% |
127 | 127 | % function list=getEventList(this)
|
128 | 128 | % list=this.getLabelList('gaitEvents');
|
129 | 129 | % end
|
130 |
| -% |
| 130 | +% |
131 | 131 | % function partialAngleData= getAngleData(this,angleName)
|
132 | 132 | % partialAngleData=this.getPartialData('angleData',angleName);
|
133 | 133 | % end
|
134 |
| -% |
| 134 | +% |
135 | 135 | % function partialParamData=getParam(this,paramName)
|
136 | 136 | % partialParamData=this.getPartialData('adaptParams',paramName);
|
137 | 137 | % end
|
138 |
| -% |
| 138 | +% |
139 | 139 | % function partialParamData=getExpParam(this,paramName)
|
140 | 140 | % partialParamData=this.getPartialData('experimentalParams',paramName);
|
141 | 141 | % end
|
142 |
| - |
| 142 | + |
143 | 143 | function adaptParams=calcAdaptParams(this)
|
144 |
| - adaptParams=calcParameters(this); |
| 144 | + adaptParams=calcParameters(this); |
145 | 145 | end
|
146 |
| - |
| 146 | + |
147 | 147 | %Modifiers
|
148 | 148 | 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 | + |
149 | 151 | %Define the events that will be used for all further computations
|
150 | 152 | if nargin<2 || isempty(eventLabels)
|
151 | 153 | refLeg=this.metaData.refLeg;
|
|
180 | 182 | allTS=allTS.cat(field.getDataAsTS(field.labels).renameLabels([],fieldLabels{end}).synchTo(allTS));
|
181 | 183 | end
|
182 | 184 | end
|
183 |
| - |
| 185 | + |
184 | 186 | %Align:
|
185 | 187 | [alignTS,bad]=allTS.align(this.gaitEvents,eventLabels,N);
|
186 |
| - |
| 188 | + |
187 | 189 | %Create reduced struct:
|
188 | 190 | reducedThis=reducedLabData(this.metaData,this.gaitEvents,alignTS,bad,reducedFields,fieldPrefixes,this.adaptParams); %Constructor
|
189 | 191 | warning('on','labTS:renameLabels:dont')
|
190 | 192 | 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 | + |
192 | 203 | %Getters for dependent properties:
|
193 | 204 | function expParams=get.experimentalParams(this)
|
194 | 205 | expParams=calcExperimentalParams(this);
|
195 | 206 | end
|
196 | 207 |
|
197 | 208 | function b=get.isSingleStride(this)
|
198 |
| - b=isa(this,'strideData'); |
| 209 | + b=isa(this,'strideData'); |
199 | 210 | end
|
200 |
| - |
| 211 | + |
201 | 212 | %Separate into strides!
|
202 | 213 | function [arrayedEvents]=getArrayedEvents(this,eventList)
|
203 | 214 | arrayedEvents=labTimeSeries.getArrayedEvents(this.gaitEvents,eventList);
|
204 | 215 | end
|
205 | 216 | 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 | + |
208 | 219 | [numStrides,initTime,endTime]=getStrideInfo(this,triggerEvent);
|
209 | 220 | steppedDataArray={};
|
210 | 221 | for i=1:numStrides
|
211 | 222 | steppedDataArray{i}=this.split(initTime(i),endTime(i),'strideData');
|
212 | 223 | end
|
213 | 224 | end
|
214 |
| - |
| 225 | + |
215 | 226 | 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 |
217 | 228 | %Determine end event (ex: if triggerEvent='LHS' then we
|
218 |
| - %need 'RHS') |
| 229 | + %need 'RHS') |
219 | 230 | if strcmp(triggerEvent(1),'L')
|
220 | 231 | contraLeg='R';
|
221 |
| - else |
| 232 | + else |
222 | 233 | contraLeg='L';
|
223 | 234 | end
|
224 | 235 | contraLateralTriggerEvent=[contraLeg triggerEvent(2:end)];
|
|
229 | 240 | steppedDataArray{i}=this.split(initTime(i),CendTime(find(CendTime>initTime(i),1,'first')),'strideData');
|
230 | 241 | end
|
231 | 242 | end
|
232 |
| - |
| 243 | + |
233 | 244 | 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
|
234 | 245 | %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 |
236 | 247 | [strideIdxs,initTime,endTime]=getStrideInfo(this,triggerEvent);
|
237 | 248 | steppedDataArray={};
|
238 | 249 | for i=strideIdxs(1:end-1)
|
239 | 250 | steppedDataArray{i}=this.split(initTime(i),endTime(i+1),'strideData');
|
240 | 251 | end
|
241 | 252 | end
|
242 |
| - |
| 253 | + |
243 | 254 | function [numStrides,initTime,endTime]=getStrideInfo(this,triggerEvent,endEvent)
|
244 |
| - |
| 255 | + |
245 | 256 | if nargin<2 || isempty(triggerEvent)
|
246 | 257 | triggerEvent=[this.metaData.refLeg 'HS']; %Using refLeg's HS as default event for striding.
|
247 | 258 | end
|
|
259 | 270 | endTime=arrayedEvents(:,2);
|
260 | 271 | end
|
261 | 272 | numStrides=size(initTime,1);
|
262 |
| - |
| 273 | + |
263 | 274 | % refLegEventList=this.getPartialGaitEvents(triggerEvent);
|
264 | 275 | % refIdxLst=find(refLegEventList==1);
|
265 | 276 | % auxTime=this.gaitEvents.Time;
|
|
274 | 285 | % noEnd=true;
|
275 | 286 | % while i<numStrides && noEnd %This is an infinite loop...
|
276 | 287 | % i=i+1;
|
277 |
| -% aux=auxTime(find(endIdxLst>refIdxLst(i),1,'first')); |
| 288 | +% aux=auxTime(find(endIdxLst>refIdxLst(i),1,'first')); |
278 | 289 | % if ~isempty(aux)
|
279 | 290 | % endTime(i)=aux;
|
280 | 291 | % else
|
|
283 | 294 | % end
|
284 | 295 | % end
|
285 | 296 | end
|
286 |
| - |
| 297 | + |
287 | 298 | function [numSteps,initTime,endTime,initEventSide]=getStepInfo(this,triggerEvent)
|
288 | 299 | if nargin<2 || isempty(triggerEvent)
|
289 | 300 | triggerEvent='HS'; %Using HS as default event for striding.
|
290 | 301 | end
|
291 |
| - |
| 302 | + |
292 | 303 | %Find starting events:
|
293 | 304 | rEventList=this.getPartialGaitEvents(['R' triggerEvent]);
|
294 | 305 | rIdxLst=find(rEventList==1);
|
295 | 306 | lEventList=this.getPartialGaitEvents(['L' triggerEvent]);
|
296 | 307 | lIdxLst=find(lEventList==1);
|
297 |
| - |
| 308 | + |
298 | 309 | auxTime=this.gaitEvents.Time;
|
299 | 310 |
|
300 | 311 | i=0;
|
|
314 | 325 | while noEnd %This is an infinite loop...
|
315 | 326 | i=i+1;
|
316 | 327 | if lastSideRight
|
317 |
| - aux=find(auxTime(lIdxLst)>initTime(i),1,'first'); |
| 328 | + aux=find(auxTime(lIdxLst)>initTime(i),1,'first'); |
318 | 329 | t=auxTime(lIdxLst(aux));
|
319 | 330 | initEventSide{i}='R';
|
320 | 331 | else
|
321 |
| - aux=find(auxTime(rIdxLst)>initTime(i),1,'first'); |
| 332 | + aux=find(auxTime(rIdxLst)>initTime(i),1,'first'); |
322 | 333 | t=auxTime(rIdxLst(aux));
|
323 | 334 | initEventSide{i}='L';
|
324 | 335 | end
|
|
334 | 345 | numSteps=i;
|
335 | 346 | end
|
336 | 347 | end
|
337 |
| - |
| 348 | + |
338 | 349 | function [stridedField,bad,initTime,events]=getStridedField(this,field,events)
|
339 | 350 | warning('This is very slow and has been deprecated. Please don''t use')
|
340 | 351 | if isa(events,'char')
|
|
360 | 371 | %Step 3: slice timeseries
|
361 | 372 | timeBreakpoints=[initTime, intermediateTimes]';
|
362 | 373 | [slicedTS,~,~]=sliceTS(this.(field),[timeBreakpoints(:); endTime(end)],0);
|
363 |
| - |
| 374 | + |
364 | 375 | %Step 4: reshape & set to [] the slices which didn't have
|
365 | 376 | %proper events
|
366 | 377 | stridedField=reshape(slicedTS,N,M)';
|
367 | 378 | end
|
368 |
| - |
| 379 | + |
369 | 380 | function [alignedField,bad]=getAlignedField(this,field,events,alignmentLengths)
|
370 | 381 | [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); |
377 | 382 | end
|
378 | 383 | end
|
379 |
| - |
380 |
| - |
381 |
| -end |
382 | 384 |
|
| 385 | + |
| 386 | +end |
0 commit comments