-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDTDisplacementData.m
331 lines (300 loc) · 14.7 KB
/
DTDisplacementData.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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
classdef DTDisplacementData < handle
properties (SetAccess = private, Hidden = false)
m_specimen;
end
properties (SetAccess = private, Hidden = true)
m_displacementTroch; % displacement of the trochanter
m_displacementHammer; % displacement of the impact hammer
m_displacementTrochFilt; % displacement of the trochanter, filtered
m_displacementHammerFilt; % displacement of the hammer, filtered
m_timeDisplacement; % time of the values in displacement camera time
m_time;
m_timeStart = 0; % time of the first data point, experiment time
m_sampleRate = 0; % camera sample rate in Hz
m_filterCutoff = 500; % filter cutoff frequency in Hz
m_filterOrder = 2; % butterworth filter order. Must be even, odd orders will be increased by 1
m_fileName = ''; % the raw TEMA data file
end % properties
methods
% Constructor
function DTDD = DTDisplacementData(specimen)
% The constructor to create a drop tower displacement data
% object. The only input is a specimen object. See Specimen.m
% for details on the creation of a specimen object.
%
% DTDD = DTDisplacementData(specimen)
%
DTDD.m_specimen = specimen;
end
function o = GetSpecimen(DTDD)
% A function to get the specimen object associated with the
% DT Displacment Data object at creation time.
%
% Specimen = DTDD.GetSpecimen()
%
o = DTDD.m_specimen;
end
function SetFileName(DTDD,file)
% A function to set the name of the displacement data file.
%
% DTDD.SetFileName(file)
%
if ~strcmp(DTDD.m_fileName,file)
if ~exist(file,'file')
error('DropTowerDisplacement:DataAvailability','The specified displacement file for %s does not exist.\n',DTDD.GetSpecimen().GetSpecimenName());
end
DTDD.m_fileName = file;
end
end
function o = GetFileName(DTDD)
% A funtion to get the name of the file containing the drop
% tower displacement data.
%
% Name = DTDD.GetFileName()
%
o = DTDD.m_fileName;
end
function SetTimeStart(DTDD,time)
% A function to set the displacement data in seconds. In some
% cases the first data point of the displacement data will
% not line up with the trigger (ie experiment time) and this
% value is used to correct for that offset.
%
% DTDD.SetTimeStart(time)
%
if DTDD.m_timeStart ~= time
DTDD.m_timeStart = time;
end
end
function o = GetTimeStart(DTDD)
% A function to get the time of the first data point in the
% displacement data in terms of time post trigger. The value is
% in seconds
%
% Time = DTDD.GetTimeStart()
%
o = DTDD.m_timeStart;
end
function SetSampleRate(DTDD,rate)
% A function to set the sampling rate of the displacement
% data in Hz.
%
% DTDD.SetSampleRate(rate)
%
if DTDD.m_sampleRate ~= rate
DTDD.m_sampleRate = rate;
end
end
function o = GetSampleRate(DTDD)
% A function to get the sample rate of the displacement data in
% Hz.
%
% Rate = DTDD.GetSampleRate()
%
o = DTDD.m_sampleRate;
end
function ReadFile(DTDD)
% A function to read the specifed file containing the
% displcement data. Time should be in ms and the displacement
% in mm.
%
% DTDD.ReadFile()
%
if isempty(DTDD.m_fileName)
error('DropTowerDisplacement:DataAvailability','File read was called for %s when no file name has been set.\n',DTDD.GetSpecimen().GetSpecimenName());
end
% read the file
data = importdata(DTDD.m_fileName,'\t');
% find the shortest data filed
validData = ~isnan(data.data);
startIndex = max([find(validData(:,1),1,'first'),find(validData(:,2),1,'first'),find(validData(:,3),1,'first'),find(validData(:,4),1,'first'),find(validData(:,5),1,'first')]);
endIndex = min( [find(validData(:,1),1,'last'), find(validData(:,2),1,'last'), find(validData(:,3),1,'last'), find(validData(:,4),1,'last'), find(validData(:,5),1,'last')] );
% import the time data
DTDD.m_timeDisplacement = data.data(startIndex:endIndex,1)./1000;
% import the impact hammer data and convert to m
DTDD.m_displacementHammer = [data.data(startIndex:endIndex,2), data.data(startIndex:endIndex,3) ]./1000;
DTDD.m_displacementTroch = [data.data(startIndex:endIndex,4), data.data(startIndex:endIndex,5) ]./1000;
end
function o = GetDisplacementTrochUnfiltered(DTDD)
% A function to get the unfiltered displacement of the
% trochanter in m.
%
% Displacement = DTDD.GetDisplacementTrochUnfiltered()
%
o = DTDD.m_displacementTroch;
end
function o = GetDisplacementHammerUnfiltered(DTDD)
% A function to get the unfiltered displacement of the impact
% hammer in m.
%
% Displacement = DTDD.GetDisplacementHammerUnfiltered()
%
o = DTDD.m_displacementHammer;
end
function SetFilterCutoff(DTDD,rate)
% A function to set the filter cutoff frequency in Hz. The
% default value is 500 Hz.
%
% DTDD.SetFilterCutoff(cutoff)
%
if DTDD.m_filterCutoff ~= rate
DTDD.m_filterCutoff = rate;
end
end
function o = GetFilterCutoff(DTDD)
% A function to get the filter cutoff frequency in Hz.
%
% Cutoff = DTDD.GetFilterCutoff()
%
o = DTDD.m_filterCutoff;
end
% functions to set get the filter order
function SetFilterOrder(DTDD,order)
% A funtion to set the order of the butterworth filter. Since
% the algorithm uses the filtfilt function only even filter
% orders will be accepted. If an odd filter order is proveded,
% it will be incremented by one. The filtfilt function is
% passed the order suppled/2. The forward reverse nature of
% filtfilt effectively doubles the filter order.
%
% DTDD.SetFilterOrder(order)
%
if mod(order, 2)
warning('DropTowerDisplacement:DataValues','The filter order for %s was set to an odd number. Only even orders are accepted. The order is being increased by one.\n',DTDD.GetSpecimen().GetSpecimenName());
order = order +1;
end
DTDD.m_filterOrder = order;
end
function o = GetFilterOrder(DTDD)
% A function to get the filter order.
%
% Order = DTDD.GetFilterOrder()
%
o = DTDD.m_filterOrder;
end
function o = GetDisplacementTroch(DTDD)
% A function to get the filtered trochanter displacement data
% in m.
%
% Displacement = DTDD.GetDisplacementTroch()
%
if isempty(DTDD.m_displacementTrochFilt)
if isempty(DTDD.m_displacementTroch)
error('DropTowerDisplacement:DataAvailability','Trochanter displacement was requested for %s before displacement data was available.\n',DTDD.GetSpecimen().GetSpecimenName());
end
DTDD.CalcFilteredData();
end
o = DTDD.m_displacementTrochFilt;
end
function o = GetDisplacementHammer(DTDD)
% A function to get the filtered impact hammer displecent data
% in m.
%
% Displacement = DTDD.GetDisplacementHammer()
%
if isempty(DTDD.m_displacementTrochFilt)
if isempty(DTDD.m_displacementTroch)
error('DropTowerDisplacement:DataAvailability','Hammer displacement was requested for %s before displacement data was available.\n',DTDD.GetSpecimen().GetSpecimenName());
end
DTDD.CalcFilteredData();
end
o = DTDD.m_displacementHammerFilt;
end
function o = GetTimeDisplacement(DTDD)
% A funtion to get the time in seconds in the displacement data
% time frame. If there is an offest between the first data
% point in the displacement this data will not line up with the
% experimental data. Use DTDD.GetTime() to get time in the
% experimental time frame.
%
% Time = DTDD.GetTimeDisplacement()
%
o = DTDD.m_timeDisplacement;
end
function o = GetTime(DTDD)
% A function to get the time in seconds in the experimental
% time frame. If no start time or sample rate has been set, a
% warning will be issued.
% The original data given by TEMA was rounded to the nearest
% 0.1 ms. This function returns a time vector of the correct
% length that has a spacing of 1/GetSampleRate(), resulting
% in a smooth time vector.
%
% Time = DTDD.GetTime()
%
if isempty(DTDD.GetSampleRate() )
error('DropTowerDisplacement:DataAvailability','Time was requested for %s before sample rate was supplied. The time will not be referenced to the experiment.\n',DTDD.GetSpecimen().GetSpecimenName());
end
if isempty(DTDD.GetTimeStart() )
warning('DropTowerDisplacement:DataAvailability','Time was requested for %s before start time was supplied. The time will not be referenced to the experiment.\n',DTDD.GetSpecimen().GetSpecimenName());
DTDD.SetTimeStart(0);
end
o = (0:1/DTDD.GetSampleRate():(length(DTDD.GetTimeDisplacement)-1)/DTDD.GetSampleRate()) + DTDD.GetTimeStart();
end
function Update(DTDD)
% A function to update the state of the drop tower
% displacement data object. This method does not call
% ReadFile(), which must be done by the user.
%
% DTDD.Update()
%
% check if sample rate and start time have been set
if isempty(DTDD.GetSampleRate())
error('DropTowerDisplacement:DataAvailable','Update was called for %s when no sample rate has been set.\n',DTDD.GetSpecimen().GetSpecimenName());
end
if isempty(DTDD.GetTimeStart())
error('DropTowerDisplacement:DataAvailable','Update was called for %s when no start time has been set.\n',DTDD.GetSpecimen().GetSpecimenName());
end
% check for raw data
if ( isempty(DTDD.GetDisplacementHammerUnfiltered) || isempty(DTDD.GetDisplacementTrochUnfiltered) )
error('DropTowerDisplacement:DataAvailable','Update was called for %s when no raw data is available.\nPerhapse call DTDD.ReadFile().\n',DTDD.GetSpecimen().GetSpecimenName());
end
% filter the data
DTDD.CalcFilteredData();
end
function PrintSelf(DTDD)
% A function to print the current state of the displacement
% data object
%
% DTDD.PrintSelf()
%
fprintf(1,'\n%%%%%%%%%% DTDisplacementData Class Parameters %%%%%%%%%%\n');
DTDD.GetSpecimen().PrintSelf();
fprintf(1,'\n %%%% Scalar Inputs %%%%\n');
fprintf(1,'File name: %s\n',DTDD.GetFileName());
fprintf(1,'Time of first data point in experiment time: %f seconds\n',DTDD.GetTimeStart());
fprintf(1,'Sample rate: %f Hz\n',DTDD.GetSampleRate());
fprintf(1,'Filterind cutoff: %f Hz\n',DTDD.GetFilterCutoff());
fprintf(1,'Filter order: %d\n',DTDD.GetFilterOrder());
fprintf(1,'\n %%%% Vector Outputs %%%%\n');
fprintf(1,'Time in displacement time frame: [%d,%d] seconds\n',size(DTDD.GetTimeDisplacement()));
fprintf(1,'Time in experimental time frame: [%d,%d] seconds\n',size(DTDD.GetTime()));
fprintf(1,'Filtered displacement of the trochanter: [%d,%d] m\n',size(DTDD.GetDisplacementTroch()));
fprintf(1,'Raw displacement of the trochanter: [%d,%d] m\n',size(DTDD.GetDisplacementTrochUnfiltered()));
fprintf(1,'Filtered displacement of the hammer: [%d,%d] m\n',size(DTDD.GetDisplacementHammer()));
fprintf(1,'Raw displacement of the hammer: [%d,%d] m\n',size(DTDD.GetDisplacementHammerUnfiltered()));
end
end % public methods
methods (Access = private, Hidden = true)
function CalcFilteredData(DTDD)
% A function to calculate the filtered data.
%
% DTDD.CalcFilteredData()
%
if (isempty(DTDD.m_sampleRate) || isempty(DTDD.m_filterCutoff) || isempty(DTDD.m_filterOrder) )
error('DropTowerDisplacement:DataAvailability','Filtering was requested for %s when either sample rate, filter cutoff or filter order had not been set.\n',DTDD.GetSpecimen().GetSpecimenName());
end
cutoffNormal = DTDD.m_filterCutoff / DTDD.m_sampleRate;
[b,a] = butter(DTDD.m_filterOrder/2,cutoffNormal); % divide filter order by two since filtfilt doubles the order
troch = filtfilt(b,a,DTDD.GetDisplacementTrochUnfiltered());
hammer = filtfilt(b,a,DTDD.GetDisplacementHammerUnfiltered());
% zero the data at the start
troch(:,1) = troch(:,1) - troch(1,1);
troch(:,2) = troch(:,2) - troch(1,2);
hammer(:,1) = hammer(:,1) - hammer(1,1);
hammer(:,2) = hammer(:,2) - hammer(1,2);
DTDD.m_displacementTrochFilt = troch;
DTDD.m_displacementHammerFilt = hammer;
end
end % private methods
end % classdef