Skip to content

Commit 414447a

Browse files
committed
improve creation of stim file and their conversion to raw
- creates test for remove date suffix - improves removing date suffix for zipped files like the stim ones
1 parent f4ec30a commit 414447a

File tree

8 files changed

+228
-44
lines changed

8 files changed

+228
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ output/*
1616
tests/coverage*
1717
tests/test_code_report.txt
1818
test_code_report.txt
19+
*/coverage_html/*
1920

2021
# exclude report from check_my_code
2122
check_my_code_report.txt

manualTests/test_makeRawDataset.m

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ function test_makeRawDataset()
6868
% close the file
6969
saveEventsFile('close', cfg, logFile);
7070

71+
% add dummy stim data
72+
stimLogFile = saveEventsFile('open_stim', cfg, logFile);
73+
for i = 1:100
74+
stimLogFile(i, 1).onset = cfg.mri.repetitionTime * i;
75+
stimLogFile(i, 1).trial_type = 'test';
76+
stimLogFile(i, 1).duration = 1;
77+
stimLogFile(i, 1).Speed = rand(1);
78+
stimLogFile(i, 1).is_Fixation = rand > 0.5;
79+
stimLogFile(i, 1).LHL24 = randn(1, 3);
80+
end
81+
saveEventsFile('save', cfg, stimLogFile);
82+
saveEventsFile('close', cfg, stimLogFile);
83+
7184
% add dummy functional data
7285
funcDir = fullfile(cfg.dir.output, 'source', 'sub-001', 'ses-001', 'func');
7386
boldFilename = 'sub-001_ses-001_task-testtask_run-001_bold.nii.gz';
@@ -87,6 +100,7 @@ function test_makeRawDataset()
87100
cfg.subject.sessionNb = 3;
88101
cfg.subject.runNb = 4;
89102

103+
% deal with MRI suffixes
90104
cfg.mri.reconstruction = 'fast recon';
91105
cfg.mri.contrastEnhancement = 'test';
92106
cfg.mri.phaseEncodingDirection = 'y pos';
@@ -100,7 +114,7 @@ function test_makeRawDataset()
100114

101115
createBoldJson(cfg);
102116

103-
% add dummy functional data
117+
%% add dummy functional data
104118
funcDir = fullfile(cfg.dir.output, 'source', 'sub-002', 'ses-003', 'func');
105119
boldFilename = ['sub-002_ses-003_task-rest', ...
106120
'_acq-newTYpe_ce-test_dir-yPos_rec-fastRecon', ...
@@ -110,9 +124,11 @@ function test_makeRawDataset()
110124
fullfile('..', 'dummyData', 'dummyData.nii.gz'), ...
111125
fullfile(funcDir, boldFilename));
112126

113-
%%
127+
%% actually do the conversion of the source data thus created
114128
clear;
129+
115130
outputDir = fullfile(fileparts(mfilename('fullpath')), 'output');
116131
cfg.dir.output = outputDir;
117132
convertSourceToRaw(cfg);
133+
118134
end

src/convertSourceToRaw.m

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ function convertSourceToRaw(cfg)
77
% - copy source dir to raw dir
88
% - remove the date suffix (_date-YYYYMMDDHHMM) from the files where it is present
99
%
10+
% Only covers func folder at the moment
1011

1112
sourceDir = fullfile(cfg.dir.output, 'source');
1213
rawDir = fullfile(cfg.dir.output, 'rawdata');
@@ -41,42 +42,6 @@ function convertSourceToRaw(cfg)
4142

4243
end
4344

44-
function parseFunc(rawDir, subjName, sesName)
4545

46-
subjectPath = fullfile(rawDir, subjName, sesName, 'func');
4746

48-
if exist(subjectPath, 'dir')
4947

50-
% do events
51-
filenames = file_utils('List', subjectPath, ...
52-
sprintf('^%s.*_task-.*_events_date-.*$', subjName));
53-
54-
removeDateSuffix(filenames, subjectPath);
55-
56-
% do bold
57-
filenames = file_utils('List', subjectPath, ...
58-
sprintf('^%s.*_task-.*_bold_date-.*$', subjName));
59-
60-
removeDateSuffix(filenames, subjectPath);
61-
62-
end
63-
end
64-
65-
function removeDateSuffix(filenames, subjectPath)
66-
if isempty(filenames)
67-
filenames = {};
68-
else
69-
filenames = cellstr(filenames);
70-
end
71-
72-
for i = 1:numel(filenames)
73-
74-
[~, name, ext] = fileparts(filenames{i});
75-
76-
[parts, ~] = regexp(name, '(?:_date-)+', 'split', 'match');
77-
78-
movefile(fullfile(subjectPath, filenames{i}), ...
79-
fullfile(subjectPath, [parts{1} ext]));
80-
81-
end
82-
end

src/saveEventsFile.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@
6464

6565
case 'open'
6666

67-
logFile.filename = cfg.fileName.events;
67+
logFile(1).filename = cfg.fileName.events;
6868

6969
logFile = initializeFile(cfg, logFile);
7070

7171
case 'open_stim'
7272

73-
logFile.filename = cfg.fileName.stim;
73+
logFile(1).filename = cfg.fileName.stim;
7474

7575
logFile = initializeFile(cfg, logFile);
7676

@@ -143,21 +143,22 @@
143143

144144
% Initialize txt logfiles and empty fields for the standard BIDS
145145
% event file
146-
logFile.fileID = fopen( ...
146+
logFile(1).fileID = fopen( ...
147147
fullfile( ...
148148
cfg.dir.outputSubject, ...
149149
cfg.fileName.modality, ...
150150
logFile.filename), ...
151151
'w');
152152

153153
% print the basic BIDS columns
154-
fprintf(logFile.fileID, '%s\t%s\t%s', 'onset', 'duration', 'trial_type');
154+
fprintf(logFile(1).fileID, '%s\t%s\t%s', 'onset', 'duration', 'trial_type');
155155
fprintf(1, '%s\t%s\t%s', 'onset', 'duration', 'trial_type');
156156

157157
printHeaderExtraColumns(logFile);
158158

159159
% next line so we start printing at the right place
160-
fprintf(logFile.fileID, '\n');
160+
fprintf(logFile(1).fileID, '\n');
161+
fprintf(1, '\n');
161162

162163
end
163164

@@ -174,7 +175,7 @@ function printHeaderExtraColumns(logFile)
174175

175176
headerName = returnHeaderName(namesExtraColumns{iExtraColumn}, nbCol, iCol);
176177

177-
fprintf(logFile.fileID, '\t%s', headerName);
178+
fprintf(logFile(1).fileID, '\t%s', headerName);
178179
fprintf(1, '\t%s', headerName);
179180

180181
end

src/subfun/parseFunc.m

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
function parseFunc(rawDir, subjName, sesName)
2+
% parseFunc(rawDir, subjName, sesName)
3+
%
4+
5+
subjectPath = fullfile(rawDir, subjName, sesName, 'func');
6+
7+
if exist(subjectPath, 'dir')
8+
9+
% do events
10+
filenames = file_utils('List', subjectPath, ...
11+
sprintf('^%s.*_task-.*_events_date-.*$', subjName));
12+
13+
removeDateSuffix(filenames, subjectPath);
14+
15+
% do bold
16+
filenames = file_utils('List', subjectPath, ...
17+
sprintf('^%s.*_task-.*_bold_date-.*$', subjName));
18+
19+
removeDateSuffix(filenames, subjectPath);
20+
21+
% do stim
22+
filenames = file_utils('List', subjectPath, ...
23+
sprintf('^%s.*_task-.*_stim_date-.*tsv$', subjName));
24+
compressFiles(filenames, subjectPath);
25+
filenames = file_utils('List', subjectPath, ...
26+
sprintf('^%s.*_task-.*_stim_date-.*tsv.gz$', subjName));
27+
removeDateSuffix(filenames, subjectPath);
28+
29+
end
30+
end
31+
32+
function compressFiles(filenames, subjectPath)
33+
if isempty(filenames)
34+
filenames = {};
35+
else
36+
filenames = cellstr(filenames);
37+
end
38+
39+
for i = 1:numel(filenames)
40+
41+
gzip(fullfile(subjectPath, filenames{i}))
42+
delete(fullfile(subjectPath, filenames{i}))
43+
44+
end
45+
end

src/subfun/removeDateSuffix.m

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function removeDateSuffix(filenames, subjectPath)
2+
% removeDateSuffix(filenames, subjectPath)
3+
%
4+
%
5+
6+
if isempty(filenames)
7+
filenames = {};
8+
else
9+
filenames = cellstr(filenames);
10+
end
11+
12+
for i = 1:numel(filenames)
13+
14+
[~, name, ext] = fileparts(filenames{i});
15+
16+
if strcmp(ext, '.gz')
17+
[~, name, ext2] = fileparts(name);
18+
ext = [ext2, ext]; %#ok<AGROW>
19+
end
20+
21+
[parts, ~] = regexp(name, '(?:_date-)+', 'split', 'match');
22+
23+
% remove suffix file if there was one
24+
if ~strcmp(filenames{i}, [parts{1} ext])
25+
movefile(fullfile(subjectPath, filenames{i}), ...
26+
fullfile(subjectPath, [parts{1} ext]));
27+
end
28+
29+
end
30+
31+
32+
33+
end

tests/test_removeDateSuffix.m

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
function test_suite = test_removeDateSuffix %#ok<*STOUT>
2+
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
3+
test_functions = localfunctions(); %#ok<*NASGU>
4+
catch % no problem; early Matlab versions can use initTestSuite fine
5+
end
6+
initTestSuite;
7+
end
8+
9+
10+
function test_removeDateSuffixBasic()
11+
12+
%% set up
13+
cfg.dir.output = fullfile(fileparts(mfilename('fullpath')), '..', 'output');
14+
15+
% clean up
16+
if isdir(cfg.dir.output)
17+
rmdir(cfg.dir.output, 's');
18+
end
19+
[~, ~, ~] = mkdir(cfg.dir.output);
20+
21+
% TODO
22+
% make sure we use the default date parameter (to implement?)
23+
% cfg = checkCFG(cfg);
24+
25+
%% set up
26+
boldName = 'test_bold_date-202008050730.nii.gz';
27+
boldName2 = 'test2_bold.nii.gz';
28+
boldName3 = 'test3_bold_date-202008050730.nii';
29+
jsonName = 'test_bold_date-202008050730.json';
30+
eventsName = 'test_events_date-202008050730.tsv';
31+
stimName = 'test_stim_date-202008050730.tsv';
32+
stimNameZipped = 'test2_stim_date-202008050730.tsv.gz';
33+
34+
filesToProcess = { ...
35+
boldName ;
36+
boldName2 ;
37+
boldName3 ;
38+
jsonName ;
39+
eventsName ;
40+
stimName ;
41+
stimNameZipped ;
42+
};
43+
44+
for iFile = 1:numel(filesToProcess)
45+
copyfile( ...
46+
fullfile('..', 'dummyData', 'dummyData.nii.gz'), ...
47+
fullfile(cfg.dir.output, filesToProcess{iFile}));
48+
end
49+
50+
%% do stuff
51+
filenames = file_utils('List', cfg.dir.output, '^test.*$');
52+
53+
removeDateSuffix(filenames, cfg.dir.output);
54+
55+
%% expected data
56+
expectedBoldName = 'test_bold.nii.gz';
57+
expectedBoldName2 = 'test2_bold.nii.gz';
58+
expectedBoldName3 = 'test3_bold.nii';
59+
expectedJsonName = 'test_bold.json';
60+
expectedEventsName = 'test_events.tsv';
61+
expectedStimName = 'test_stim.tsv';
62+
expectedStimNameZipped = 'test2_stim.tsv.gz';
63+
64+
%% test
65+
assertEqual(exist(fullfile(cfg.dir.output, expectedBoldName3), 'file'), 2);
66+
assertEqual(exist(fullfile(cfg.dir.output, expectedJsonName), 'file'), 2);
67+
assertEqual(exist(fullfile(cfg.dir.output, expectedEventsName), 'file'), 2);
68+
assertEqual(exist(fullfile(cfg.dir.output, expectedStimName), 'file'), 2);
69+
assertEqual(exist(fullfile(cfg.dir.output, expectedStimNameZipped), 'file'), 2);
70+
assertEqual(exist(fullfile(cfg.dir.output, expectedBoldName2), 'file'), 2);
71+
assertEqual(exist(fullfile(cfg.dir.output, expectedBoldName), 'file'), 2);
72+
73+
end
74+
75+
76+
77+
78+
79+

tests/test_saveEventsFileOpen.m

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,50 @@ function test_saveEventsFileOpenBasic()
5050

5151
end
5252

53+
function test_saveEventsFileOpenStimfile()
54+
55+
outputDir = fullfile(fileparts(mfilename('fullpath')), '..', 'output');
56+
57+
%% set up
58+
59+
cfg.verbose = false;
60+
61+
cfg.subject.subjectNb = 1;
62+
cfg.subject.runNb = 1;
63+
64+
cfg.task.name = 'testtask';
65+
66+
cfg.dir.output = outputDir;
67+
68+
cfg.testingDevice = 'mri';
69+
70+
cfg = createFilename(cfg);
71+
72+
% create the events file and header
73+
logFile = saveEventsFile('open_stim', cfg);
74+
75+
% close the file
76+
saveEventsFile('close', cfg, logFile);
77+
78+
%% data to test against
79+
funcDir = fullfile(outputDir, 'source', 'sub-001', 'ses-001', 'func');
80+
eventFilename = ['sub-001_ses-001_task-testtask_run-001_stim_date-' ...
81+
cfg.fileName.date '.tsv'];
82+
83+
% check that the file has the right path and name
84+
assert(exist(fullfile(funcDir, eventFilename), 'file') == 2);
85+
86+
FID = fopen(fullfile(funcDir, eventFilename), 'r');
87+
C = textscan(FID, repmat('%s', 1, 3), 'Delimiter', '\t', 'EndOfLine', '\n');
88+
89+
%% test
90+
% check the extra columns of the header
91+
assertEqual(C{1}{1}, 'onset');
92+
assertEqual(C{2}{1}, 'duration');
93+
assertEqual(C{3}{1}, 'trial_type');
94+
95+
end
96+
5397
function test_saveEventsFileOpenExtraColumns()
5498

5599
outputDir = fullfile(fileparts(mfilename('fullpath')), '..', 'output');

0 commit comments

Comments
 (0)