Skip to content

Commit

Permalink
[FIX] handle nan and and datetimes when printing tables (#605)
Browse files Browse the repository at this point in the history
* fix bugs in tables and datetimes

* skip on windows
  • Loading branch information
Remi-Gau authored Jul 31, 2023
1 parent 4240542 commit 7d76945
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
27 changes: 20 additions & 7 deletions +bids/+util/tsvwrite.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ function tsvwrite(filename, var)
% tsvwrite(f, var)
%
% :param filename:
% :type filename: string
% :type filename: string
%
% :param var:
% :type var: data array or structure
% :type var: data array or structure
%
%
% Based on spm_save.m from SPM12.
%
%

% (C) Copyright 2018 Guillaume Flandin, Wellcome Centre for Human Neuroimaging
%
% (C) Copyright 2018 BIDS-MATLAB developers

delim = sprintf('\t');
Expand Down Expand Up @@ -55,6 +55,7 @@ function tsvwrite(filename, var)
var = num2cell(var);
end

var = convert_datetimes(var);
var = cellfun(@(x) num2str(x, 16), var, 'UniformOutput', false);
var = strtrim(var);
var(cellfun(@(x) strcmp(x, 'NaN'), var)) = {'n/a'};
Expand All @@ -64,9 +65,10 @@ function tsvwrite(filename, var)
write_to_file(filename, var, delim);

elseif isa(var, 'table')
writetable(var, filename, ...
'FileType', 'text', ...
'Delimiter', delim);
header = var.Properties.VariableNames;
var = table2cell(var);
var = cat(1, header, var);
bids.util.tsvwrite(filename, var);

else
error('Unknown data type.');
Expand All @@ -75,6 +77,17 @@ function tsvwrite(filename, var)

end

function var = convert_datetimes(var)
if bids.internal.is_octave
return
end
is_datetime = find(cellfun(@(x) isdatetime(x), var(:)));
for i = 1:numel(is_datetime)
idx = is_datetime(i);
var{idx} = char(var{idx}, 'yyyy-MM-dd''T''HH:mm:ss.SSS'); % bids-compliant datetime
end
end

function write_to_file(filename, var, delim)

fid = fopen(filename, 'Wt');
Expand Down
37 changes: 36 additions & 1 deletion tests/tests_utils/test_tsvwrite.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,41 @@
initTestSuite;
end

function test_datetime_in_table()
% TODO fix line issue on windows
if bids.internal.is_octave() || ispc()
moxunit_throw_test_skipped_exception('no datetime in Octave and line issue in windows');
end
x = '201401010000';
acq_time = datetime(x, 'InputFormat', 'yyyyMMddHHmm');
sub_id = {'foo'};
patients = table(sub_id, acq_time);
file = fullfile(tempname(), 'foo.tsv');
bids.util.mkdir(fileparts(file));
bids.util.tsvwrite(file, patients);

FID = fopen(file, 'r');
C = textscan(FID, '%s%s', 'Delimiter', '\t', 'EndOfLine', '\n');
assertEqual(C{2}{2}, '2014-01-01T00:00:00.000');
end

function test_nan_in_table()
% TODO fix line issue on windows
if bids.internal.is_octave() || ispc()
moxunit_throw_test_skipped_exception('no table in Octave and line issue in windows');
end
sub_id = {'foo'; 'bar'};
age = [25; nan];
patients = table(sub_id, age);
file = fullfile(tempname(), 'foo.tsv');
bids.util.mkdir(fileparts(file));
bids.util.tsvwrite(file, patients);

FID = fopen(file, 'r');
C = textscan(FID, '%s%s', 'Delimiter', '\t', 'EndOfLine', '\n');
assertEqual(C{2}{3}, 'n/a');
end

function test_tsvwrite_basic()

pth = fileparts(mfilename('fullpath'));
Expand Down Expand Up @@ -67,7 +102,7 @@ function test_tsvwrite_basic()

FID = fopen(tsv_file, 'r');
C = textscan(FID, '%s%s', 'Delimiter', '\t', 'EndOfLine', '\n');
assertEqual(C{1}{2}, 'n/a'); %
assertEqual(C{1}{2}, 'n/a');

delete(tsv_file);

Expand Down

0 comments on commit 7d76945

Please sign in to comment.