Skip to content

Commit d0e706c

Browse files
committed
Fix pspm_convert_au2unit to work correctly with files and add a test
1 parent 4bf9dc6 commit d0e706c

File tree

2 files changed

+175
-5
lines changed

2 files changed

+175
-5
lines changed

src/pspm_convert_au2unit.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
[sts, channeldata, infos, pos_of_channel(i)] = pspm_load_channel(alldata, channel{i}, 'pupil');
164164
if sts < 1, return; end
165165
% recursive call to avoid the formula being stated twice in the same function
166-
[sts, convert_data.data{i}] = pspm_convert_au2unit(channeldata.data, unit, distance, record_method, ...
166+
[sts, convert_data{i}.data] = pspm_convert_au2unit(channeldata.data, unit, distance, record_method, ...
167167
multiplicator, reference_distance, reference_unit, options);
168168
if sts < 1, return; end
169169
convert_data{i}.header = channeldata.header;

test/pspm_convert_au2unit_test.m

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,176 @@
11
classdef pspm_convert_au2unit_test < pspm_testcase
2-
% ● Description
3-
% unittest class for the pspm_convert_au2unit function
4-
% ● Authorship
5-
% (C) 2019 Eshref Yozdemir (University of Zurich)
2+
% ● Description
3+
% unittest class for the pspm_convert_au2unit function
4+
% ● Authorship
5+
% (C) 2019 Eshref Yozdemir (University of Zurich)
6+
% Updated in 2026 by Bernhard von Raußendorf
7+
8+
methods (Test)
9+
10+
%% data mode
11+
% [sts, converted_data] = pspm_convert_au2unit(data, unit, distance, record_method,
12+
% multiplicator, reference_distance, reference_unit, options)
13+
function testDiameterSameUnits(testCase)
14+
[sts, out] = pspm_convert_au2unit(20, 'mm', 60, 'diameter', 0.1, 50, 'mm');
15+
testCase.verifyEqual(sts, 1);
16+
testCase.verifyEqual(out, 2.4);
617
end
18+
function testDiameterUnitConversion(testCase)
19+
[sts, out] = pspm_convert_au2unit(30, 'cm', 6, 'diameter', 0.2, 50, 'mm');
20+
testCase.verifyEqual(sts, 1);
21+
testCase.verifyEqual(out, 0.72);
22+
end
23+
function testAreaSameUnits(testCase)
24+
[sts, out] = pspm_convert_au2unit(100, 'mm', 60, 'area', 0.1, 50, 'mm');
25+
testCase.verifyEqual(sts, 1);
26+
testCase.verifyEqual(out, 1.2);
27+
end
28+
function testAreaUnitConversion(testCase)
29+
[sts, out] = pspm_convert_au2unit(400, 'mm', 100, 'area', 0.1, 100, 'm');
30+
testCase.verifyEqual(sts, 1);
31+
testCase.verifyEqual(out, 2, 'AbsTol', 1e-12);
32+
end
33+
function testVectorAreaSameUnits(testCase)
34+
[sts, out] = pspm_convert_au2unit([25 36 49], 'mm', 80, 'area', 0.05, 40, 'mm');
35+
testCase.verifyEqual(sts, 1);
36+
testCase.verifyEqual(out, [0.5 0.6 0.7], 'AbsTol', 1e-12);
37+
end
38+
function testVectorAreaUnitConversion(testCase)
39+
[sts,out]=pspm_convert_au2unit([100 400 900],'mm',100,'area',0.1,50,'m');
40+
testCase.verifyEqual(sts,1);
41+
testCase.verifyEqual(out,[2 4 6],'AbsTol',1e-12);
42+
end
43+
44+
%% Error handeling
45+
function testErrorHandling(testCase)
46+
% invalid inputs
47+
[sts,out] = pspm_convert_au2unit();
48+
testCase.verifyEqual(sts,-1);
49+
testCase.verifyEmpty(out);
50+
51+
[sts,out] = pspm_convert_au2unit(20);
52+
testCase.verifyEqual(sts,-1);
53+
testCase.verifyEmpty(out);
54+
55+
[sts,out] = pspm_convert_au2unit(20,'mm');
56+
testCase.verifyEqual(sts,-1);
57+
testCase.verifyEmpty(out);
58+
59+
[sts,out] = pspm_convert_au2unit(20,'mm',60);
60+
testCase.verifyEqual(sts,-1);
61+
testCase.verifyEmpty(out);
62+
% invalid unit inputs
63+
[sts,out] = pspm_convert_au2unit(20,'mm',60,'wrong',0.1,50,'mm');
64+
testCase.verifyEqual(sts,-1);
65+
testCase.verifyEmpty(out);
66+
67+
[sts,out] = pspm_convert_au2unit(20,'mm','far','diameter',0.1,50,'mm');
68+
testCase.verifyEqual(sts,-1);
69+
testCase.verifyEmpty(out);
70+
71+
[sts,out] = pspm_convert_au2unit(20,'mm',60,'diameter','bad',50,'mm');
72+
testCase.verifyEqual(sts,-1);
73+
testCase.verifyEmpty(out);
74+
75+
[sts,out] = pspm_convert_au2unit(20,'mm',60,'diameter',0.1,'bad','mm');
76+
testCase.verifyEqual(sts,-1);
77+
testCase.verifyEmpty(out);
78+
end
79+
80+
%% Pspm files
81+
82+
83+
function testFileRoundTripConvertAu2Unit(testCase)
84+
85+
fn = '/home/bernd/git/PsPM/ImportTestData/eyelink/pspm_u_sc4b31.mat';
86+
fn_roundtrip = '/home/bernd/git/PsPM/ImportTestData/eyelink/pspm_u_sc4b31_au.mat';
87+
88+
% copy file
89+
S = load(fn);
90+
save(fn_roundtrip, '-struct', 'S');
91+
92+
unit = 'mm';
93+
distance = 600;
94+
record_method = 'diameter';
95+
multiplicator = 0.04;
96+
reference_distance = 500;
97+
reference_unit = 'mm';
98+
99+
options = struct();
100+
options.channel = 'pupil';
101+
options.channel_action = 'replace';
102+
103+
%% 1) Original laden
104+
[sts, infos, data] = pspm_load_data(fn);
105+
testCase.verifyEqual(sts, 1);
106+
107+
108+
%% 3) Originalkanal mit Einheiten laden
109+
[sts, original_channel, ~, pos] = pspm_load_channel(fn, options.channel, 'pupil');
110+
testCase.verifyEqual(sts, 1);
111+
112+
%% 4) Werte künstlich zurück in arbitrary units rechnen
113+
au_data = unit2au(original_channel.data, unit, distance, record_method, ...
114+
multiplicator, reference_distance, reference_unit);
115+
116+
%% 5) AU-Kanal in die neue Datei schreiben
117+
newdata = original_channel;
118+
newdata.data = au_data;
119+
newdata.header.units = 'au';
120+
121+
[sts, info_write] = pspm_write_channel( ...
122+
fn_roundtrip, newdata, 'replace', struct('channel', pos));
123+
testCase.verifyEqual(sts, 1);
124+
125+
%% 6) Neue Datei wieder mit convert_au2unit umrechnen
126+
[sts, outchannel] = pspm_convert_au2unit( ...
127+
fn_roundtrip, unit, distance, record_method, ...
128+
multiplicator, reference_distance, reference_unit, ...
129+
struct('channel', pos, 'channel_action', 'replace'));
130+
testCase.verifyEqual(sts, 1);
131+
132+
%% 7) Rekonvertierten Kanal laden
133+
[sts, reconverted_channel] = pspm_load_channel(fn_roundtrip, outchannel, 'pupil');
134+
testCase.verifyEqual(sts, 1);
135+
136+
%% 8) Vergleich
137+
testCase.verifyEqual(reconverted_channel.data, original_channel.data, 'AbsTol', 1e-12);
138+
testCase.verifyEqual(reconverted_channel.header.units, unit);
139+
140+
%% optional cleanup
141+
if exist(fn_roundtrip, 'file')
142+
delete(fn_roundtrip);
143+
end
144+
end
145+
146+
147+
148+
149+
150+
151+
152+
153+
end
154+
end
155+
156+
function data = unit2au(outchannel, unit, distance, record_method, ...
157+
multiplicator, reference_distance, reference_unit)
158+
159+
[~, outchannel_ref] = pspm_convert_unit(outchannel, unit, reference_unit);
160+
[~, distance_ref] = pspm_convert_unit(distance, unit, reference_unit);
161+
162+
switch lower(record_method)
163+
case 'diameter'
164+
data = outchannel_ref ./ ...
165+
(multiplicator * (distance_ref / reference_distance));
166+
case 'area'
167+
data = (outchannel_ref ./ ...
168+
(multiplicator * (distance_ref / reference_distance))).^2;
169+
otherwise
170+
error('Invalid record_method');
171+
end
172+
end
173+
174+
175+
176+

0 commit comments

Comments
 (0)