1clc
2clear
3close all
4fprintf('Matlab tests started..\n\n')
5
6% Load an empty c3d structure
7fprintf('Loading an empty C3D.. ');
8c3d = ezc3dRead();
9
10% Test the header of the new C3D
11assert(c3d.header.points.size == 0)
12assert(c3d.header.points.frameRate == 0)
13assert(c3d.header.points.firstFrame == 1)
14assert(c3d.header.points.lastFrame == 1)
15
16assert(c3d.header.analogs.size == 0)
17assert(c3d.header.analogs.frameRate == 0)
18assert(c3d.header.analogs.firstFrame == 1)
19assert(c3d.header.analogs.lastFrame == 0)
20
21assert(c3d.header.events.size == 18)
22for i = 1:18
23    assert(c3d.header.events.eventsTime(i) == 0)
24    assert(isempty(c3d.header.events.eventsLabel{i}))
25    assert(ischar(c3d.header.events.eventsLabel{i}))
26end
27
28% Test the parameters
29assert(c3d.parameters.POINT.USED.DATA == 0)
30assert(c3d.parameters.POINT.SCALE.DATA == -1)
31assert(c3d.parameters.POINT.RATE.DATA == 0)
32assert(c3d.parameters.POINT.FRAMES.DATA == 0)
33assert(isempty(c3d.parameters.POINT.LABELS.DATA))
34assert(isempty(c3d.parameters.POINT.DESCRIPTIONS.DATA))
35assert(isempty(c3d.parameters.POINT.UNITS.DATA))
36
37assert(c3d.parameters.ANALOG.USED.DATA == 0)
38assert(isempty(c3d.parameters.ANALOG.LABELS.DATA))
39assert(isempty(c3d.parameters.ANALOG.DESCRIPTIONS.DATA))
40assert(c3d.parameters.ANALOG.GEN_SCALE.DATA == 1)
41assert(isempty(c3d.parameters.ANALOG.SCALE.DATA))
42assert(isempty(c3d.parameters.ANALOG.OFFSET.DATA))
43assert(isempty(c3d.parameters.ANALOG.UNITS.DATA))
44assert(c3d.parameters.ANALOG.RATE.DATA == 0)
45assert(isempty(c3d.parameters.ANALOG.FORMAT.DATA))
46assert(isempty(c3d.parameters.ANALOG.BITS.DATA))
47
48assert(c3d.parameters.FORCE_PLATFORM.USED.DATA == 0)
49assert(isempty(c3d.parameters.FORCE_PLATFORM.TYPE.DATA))
50assert(size(c3d.parameters.FORCE_PLATFORM.ZERO.DATA, 1) == 2)
51FORCE_PLATFORM.ZERO = [1, 0];
52for i=1:length(c3d.parameters.FORCE_PLATFORM.ZERO)
53    assert(c3d.parameters.FORCE_PLATFORM.ZERO.DATA(i) == FORCE_PLATFORM.ZERO(i))
54end
55assert(isempty(c3d.parameters.FORCE_PLATFORM.CORNERS.DATA))
56assert(isempty(c3d.parameters.FORCE_PLATFORM.ORIGIN.DATA))
57assert(isempty(c3d.parameters.FORCE_PLATFORM.CHANNEL.DATA))
58assert(isempty(c3d.parameters.FORCE_PLATFORM.CAL_MATRIX.DATA))
59
60% Test the data
61assert(isempty(c3d.data.points))
62assert(sum(size(c3d.data.points) == [3, 0, 0]) == 3)
63assert(isempty(c3d.data.analogs))
64assert(sum(size(c3d.data.analogs) == [0, 0]) == 2)
65fprintf('Done\n');
66
67% Now add some data.
68fprintf('Writing and reading back a C3D.. ');
69
70% Adjust some mandatory values of the parameters and fill
71% the data with random values
72nbSeconds = 2;
73pointFrameRate = 100;
74pointNames = {'point1', 'point2', 'point3', 'point4', 'point5'};
75pointData = rand(3, length(pointNames), pointFrameRate * nbSeconds);
76analogFrameRate = 1000;
77analogNames = {'analog1', 'analog2', 'analog3', ...
78               'analog4', 'analog5', 'analog6'};
79analogData = rand(analogFrameRate * nbSeconds, length(analogNames));
80
81
82
83c3d.parameters.POINT.RATE.DATA = pointFrameRate;
84c3d.parameters.POINT.LABELS.DATA = pointNames;
85c3d.data.points = pointData;
86
87c3d.parameters.ANALOG.RATE.DATA = analogFrameRate;
88c3d.parameters.ANALOG.LABELS.DATA = analogNames;
89c3d.data.analogs = analogData;
90
91% Create a custom parameter to the POINT group
92newPointParam = {'POINT', 'newParam', [1, 2, 3]};
93c3d.parameters.(newPointParam{1}).(newPointParam{2}) = ezc3dNewParam(newPointParam{3});
94
95% Create a custom parameter a new group
96newGroupParam = {'newGroup', 'newParam', {'MyParam1', 'MyParam2'}};
97c3d.parameters.(newGroupParam{1}).(newGroupParam{2}) = ezc3dNewParam(newGroupParam{3});
98
99% Write a new modified C3D and read back the data
100ezc3dWrite('temporary.c3d', c3d);
101c3d_to_compare = ezc3dRead('temporary.c3d');
102
103% Test the opened file
104% Test the header
105assert(c3d_to_compare.header.points.size == length(pointNames))
106assert(c3d_to_compare.header.points.frameRate == pointFrameRate)
107assert(c3d_to_compare.header.points.firstFrame == 1)
108assert(c3d_to_compare.header.points.lastFrame == pointFrameRate * nbSeconds)
109
110assert(c3d_to_compare.header.analogs.size == length(analogNames))
111assert(c3d_to_compare.header.analogs.frameRate == analogFrameRate)
112assert(c3d_to_compare.header.analogs.firstFrame == 1)
113assert(c3d_to_compare.header.analogs.lastFrame == analogFrameRate * nbSeconds)
114
115assert(c3d_to_compare.header.events.size == 18)
116for i = 1:18
117    assert(c3d_to_compare.header.events.eventsTime(i) == 0)
118    assert(isempty(c3d_to_compare.header.events.eventsLabel{i}))
119    assert(ischar(c3d_to_compare.header.events.eventsLabel{i}))
120end
121
122% Test the parameters
123assert(c3d_to_compare.parameters.POINT.USED.DATA == length(pointNames))
124assert(c3d_to_compare.parameters.POINT.SCALE.DATA == -1)
125assert(c3d_to_compare.parameters.POINT.RATE.DATA == pointFrameRate)
126assert(c3d_to_compare.parameters.POINT.FRAMES.DATA == pointFrameRate * nbSeconds)
127assert(length(c3d_to_compare.parameters.POINT.LABELS.DATA) == length(pointNames))
128assert(length(c3d_to_compare.parameters.POINT.DESCRIPTIONS.DATA) == length(pointNames))
129for i = 1:length(pointNames)
130    assert(strcmp(c3d_to_compare.parameters.POINT.LABELS.DATA{i}, pointNames{i}))
131    assert(isempty(c3d_to_compare.parameters.POINT.DESCRIPTIONS.DATA{i}))
132end
133assert(isempty(c3d_to_compare.parameters.POINT.UNITS.DATA))
134assert(length(c3d_to_compare.parameters.(newPointParam{1}).(newPointParam{2}).DATA) == length(newPointParam{3}))
135for i = 1:length(newPointParam{3})
136    assert(c3d_to_compare.parameters.(newPointParam{1}).(newPointParam{2}).DATA(i) == newPointParam{3}(i))
137end
138
139assert(c3d_to_compare.parameters.ANALOG.USED.DATA == length(analogNames))
140assert(c3d_to_compare.parameters.ANALOG.RATE.DATA == analogFrameRate)
141assert(length(c3d_to_compare.parameters.ANALOG.LABELS.DATA) == length(analogNames))
142assert(length(c3d_to_compare.parameters.ANALOG.DESCRIPTIONS.DATA) == length(analogNames))
143assert(length(c3d_to_compare.parameters.ANALOG.SCALE.DATA) == length(analogNames))
144assert(length(c3d_to_compare.parameters.ANALOG.OFFSET.DATA) == length(analogNames))
145assert(length(c3d_to_compare.parameters.ANALOG.UNITS.DATA) == length(analogNames))
146for i = 1:length(analogNames)
147    assert(strcmp(c3d_to_compare.parameters.ANALOG.LABELS.DATA{i}, analogNames{i}))
148    assert(isempty(c3d_to_compare.parameters.ANALOG.DESCRIPTIONS.DATA{i}))
149    assert(c3d_to_compare.parameters.ANALOG.SCALE.DATA(i) == 1)
150    assert(c3d_to_compare.parameters.ANALOG.OFFSET.DATA(i) == 0)
151    assert(strcmp(c3d_to_compare.parameters.ANALOG.UNITS.DATA{i}, ''))
152end
153assert(c3d_to_compare.parameters.ANALOG.GEN_SCALE.DATA == 1)
154assert(isempty(c3d_to_compare.parameters.ANALOG.FORMAT.DATA))
155assert(isempty(c3d_to_compare.parameters.ANALOG.BITS.DATA))
156
157assert(c3d_to_compare.parameters.FORCE_PLATFORM.USED.DATA == 0)
158assert(isempty(c3d_to_compare.parameters.FORCE_PLATFORM.TYPE.DATA))
159assert(size(c3d_to_compare.parameters.FORCE_PLATFORM.ZERO.DATA, 1) == 2)
160FORCE_PLATFORM.ZERO = [1, 0];
161for i=1:length(c3d_to_compare.parameters.FORCE_PLATFORM.ZERO)
162    assert(c3d_to_compare.parameters.FORCE_PLATFORM.ZERO.DATA(i) == FORCE_PLATFORM.ZERO(i))
163end
164assert(isempty(c3d_to_compare.parameters.FORCE_PLATFORM.CORNERS.DATA))
165assert(isempty(c3d_to_compare.parameters.FORCE_PLATFORM.ORIGIN.DATA))
166assert(isempty(c3d_to_compare.parameters.FORCE_PLATFORM.CHANNEL.DATA))
167assert(isempty(c3d_to_compare.parameters.FORCE_PLATFORM.CAL_MATRIX.DATA))
168
169assert(length(c3d_to_compare.parameters.(newGroupParam{1}).(newGroupParam{2}).DATA) == length(newGroupParam{3}))
170for i = 1:length(newGroupParam{3})
171    assert(strcmp(c3d_to_compare.parameters.(newGroupParam{1}).(newGroupParam{2}).DATA{i}, newGroupParam{3}{i}))
172end
173
174% Test the data
175assert(sum(size(c3d_to_compare.data.points) == [3, length(pointNames),  pointFrameRate * nbSeconds]) == 3)
176assert(sum(sum(sum(abs(c3d_to_compare.data.points - pointData) < 1e-6))) == 3 * length(pointNames) *  pointFrameRate * nbSeconds)
177assert(sum(size(c3d_to_compare.data.analogs) == [analogFrameRate * nbSeconds, length(analogNames)]) == 2)
178assert(sum(sum(abs(c3d_to_compare.data.analogs - analogData) < 1e-6)) == analogFrameRate * nbSeconds * length(analogNames))
179fprintf('Done\n');
180
181% Test the event adder from a file which does not have event yet
182c3d = ezc3dRead('../c3dFiles/ezc3d-testFiles-master/ezc3d-testFiles-master/Optotrak.c3d');
183c3d = ezc3dAddEvent(c3d, [0, 0.1], 'Left', 'MyNewEvent', 'Hey! This is new!', 'Me', 2, 1);
184% Only one event
185ezc3dWrite('temporary.c3d', c3d);
186c3dToCompare = ezc3dRead('temporary.c3d');
187assert(c3dToCompare.parameters.EVENT.USED.DATA == 1)
188assert(sum(sum(abs(c3dToCompare.parameters.EVENT.TIMES.DATA - [0; 0.1]))) < 1e-5);
189assert(strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{1}, 'Left'));
190assert(strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{1}, 'MyNewEvent'));
191assert(strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{1}, 'Hey! This is new!'));
192assert(strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{1}, 'Me'));
193assert(sum(c3dToCompare.parameters.EVENT.ICON_IDS.DATA - 2) == 0);
194assert(sum(c3dToCompare.parameters.EVENT.GENERIC_FLAGS.DATA - 1) == 0);
195
196% More than one
197c3d = ezc3dAddEvent(c3d, [0, 0.2]);
198ezc3dWrite('temporary.c3d', c3d);
199c3dToCompare = ezc3dRead('temporary.c3d');
200assert(c3dToCompare.parameters.EVENT.USED.DATA == 2)
201assert(sum(sum(abs(c3dToCompare.parameters.EVENT.TIMES.DATA - [0 0; 0.1 0.2]))) < 1e-5);
202assert(strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{1}, 'Left'));
203assert(strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{2}, ''));
204assert(strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{1}, 'MyNewEvent'));
205assert(strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{2}, ''));
206assert(strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{1}, 'Hey! This is new!'));
207assert(strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{2}, ''));
208assert(strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{1}, 'Me'));
209assert(strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{2}, ''));
210assert(sum(c3dToCompare.parameters.EVENT.ICON_IDS.DATA - [2, 0]) == 0);
211assert(sum(c3dToCompare.parameters.EVENT.GENERIC_FLAGS.DATA - [1, 0]) == 0);
212
213% Add from a previously loaded file
214c3d = c3dToCompare;
215c3d = ezc3dAddEvent(c3d, [0, 0.3], 'Right', 'MySecondNewEvent', 'Hey! This is new again!', 'You', 3, 2);
216c3d = ezc3dAddEvent(c3d, [0, 0.4]);
217ezc3dWrite('temporary.c3d', c3d);
218c3dToCompare = ezc3dRead('temporary.c3d');
219assert(c3dToCompare.parameters.EVENT.USED.DATA == 4)
220assert(sum(sum(abs(c3dToCompare.parameters.EVENT.TIMES.DATA - [0 0 0 0; 0.1 0.2 0.3 0.4]))) < 1e-5);
221strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{1}, 'Left');
222strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{2}, '');
223strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{3}, 'Right');
224strcmp(c3dToCompare.parameters.EVENT.CONTEXTS.DATA{4}, '');
225strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{1}, 'MyNewEvent');
226strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{2}, '');
227strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{3}, 'MySecondNewEvent');
228strcmp(c3dToCompare.parameters.EVENT.LABELS.DATA{4}, '');
229strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{1}, 'Hey! This is new!');
230strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{2}, '');
231strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{3}, 'Hey! This is new again!');
232strcmp(c3dToCompare.parameters.EVENT.DESCRIPTIONS.DATA{4}, '');
233strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{1}, 'Me');
234strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{2}, '');
235strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{3}, 'Me');
236strcmp(c3dToCompare.parameters.EVENT.SUBJECTS.DATA{4}, '');
237assert(sum(c3dToCompare.parameters.EVENT.ICON_IDS.DATA - [2, 0, 3, 0]) == 0);
238assert(sum(c3dToCompare.parameters.EVENT.GENERIC_FLAGS.DATA - [1, 0, 2, 0]) == 0);
239
240fprintf('\nMatlab tests successfully completed!\n')
241
242