Skip to content

Commit 53dab15

Browse files
authored
Merge pull request #69 from Remi-Gau/remi-print_output_to_screen
saveEvents prints to screen / Badges / MRI suffixes
2 parents cae3276 + f4ec30a commit 53dab15

File tree

10 files changed

+154
-33
lines changed

10 files changed

+154
-33
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) [![Build Status](https://travis-ci.com/cpp-lln-lab/CPP_BIDS.svg?branch=master)](https://travis-ci.com/cpp-lln-lab/CPP_BIDS)
1+
**BIDS validator and linter**
22

3+
[![Build Status](https://travis-ci.com/cpp-lln-lab/CPP_BIDS.svg?branch=master)](https://travis-ci.com/cpp-lln-lab/CPP_BIDS)
4+
5+
**Unit tests**
6+
7+
[![](https://img.shields.io/badge/Octave-CI-blue?logo=Octave&logoColor=white)](https://github.com/cpp-lln-lab/CPP_BIDS/actions)
8+
![](https://github.com/cpp-lln-lab/CPP_BIDS/workflows/CI/badge.svg)
9+
10+
**Contributors**
11+
12+
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
13+
14+
---
15+
316
# CPP_BIDS
417

518
<!-- TOC -->
@@ -18,6 +31,7 @@
1831
- [How to install](#how-to-install)
1932
- [Download with git](#download-with-git)
2033
- [Add as a submodule](#add-as-a-submodule)
34+
- [Example for submodule usage](#example-for-submodule-usage)
2135
- [Direct download](#direct-download)
2236
- [Contributing](#contributing)
2337
- [Guidestyle](#guidestyle)

manualTests/test_makeRawDataset.m

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,35 @@ function test_makeRawDataset()
77
end
88

99
%% set up
10-
11-
%%% set up
12-
13-
cfg.subject.subjectNb = 1;
14-
cfg.subject.runNb = 1;
15-
16-
cfg.task.name = 'testtask';
17-
1810
cfg.dir.output = outputDir;
1911

2012
cfg.bids.datasetDescription.Name = 'dummy';
2113
cfg.bids.datasetDescription.BIDSVersion = '1.0.0';
2214
cfg.bids.datasetDescription.Authors = {'Jane Doe', 'John Doe'};
2315

24-
cfg.bids.mri.RepetitionTime = 1.56;
25-
2616
cfg.testingDevice = 'mri';
2717

18+
%% MRI task data
19+
cfg.mri.repetitionTime = 1.56;
20+
21+
cfg.subject.subjectNb = 1;
22+
cfg.subject.runNb = 1;
23+
24+
cfg.task.name = 'testtask';
25+
2826
logFile.extraColumns.Speed.length = 1;
2927
logFile.extraColumns.LHL24.length = 3;
3028
logFile.extraColumns.is_Fixation.length = 1;
3129

32-
%%% do stuff
33-
3430
cfg = createFilename(cfg);
3531

36-
% create the events file and header
37-
logFile = saveEventsFile('open', cfg, logFile);
38-
3932
createBoldJson(cfg);
33+
4034
createDatasetDescription(cfg);
4135

36+
% create the events file and header
37+
logFile = saveEventsFile('open', cfg, logFile);
38+
4239
% ROW 2: normal events : all info is there
4340
logFile(1, 1).onset = 2;
4441
logFile(end, 1).trial_type = 'MotionUp';
@@ -74,11 +71,48 @@ function test_makeRawDataset()
7471
% add dummy functional data
7572
funcDir = fullfile(cfg.dir.output, 'source', 'sub-001', 'ses-001', 'func');
7673
boldFilename = 'sub-001_ses-001_task-testtask_run-001_bold.nii.gz';
74+
7775
copyfile( ...
7876
fullfile('..', 'dummyData', 'dummyData.nii.gz'), ...
7977
fullfile(funcDir, boldFilename));
8078

81-
%%
79+
%% MRI bold rest data and fancy suffixes
80+
clear cfg;
81+
82+
cfg.dir.output = outputDir;
83+
84+
cfg.testingDevice = 'mri';
85+
86+
cfg.subject.subjectNb = 2;
87+
cfg.subject.sessionNb = 3;
88+
cfg.subject.runNb = 4;
89+
90+
cfg.mri.reconstruction = 'fast recon';
91+
cfg.mri.contrastEnhancement = 'test';
92+
cfg.mri.phaseEncodingDirection = 'y pos';
93+
cfg.mri.echo = '1';
94+
cfg.mri.acquisition = ' new tYpe';
95+
cfg.mri.repetitionTime = 1.56;
96+
97+
cfg.task.name = 'rest';
98+
99+
cfg = createFilename(cfg);
82100

101+
createBoldJson(cfg);
102+
103+
% add dummy functional data
104+
funcDir = fullfile(cfg.dir.output, 'source', 'sub-002', 'ses-003', 'func');
105+
boldFilename = ['sub-002_ses-003_task-rest', ...
106+
'_acq-newTYpe_ce-test_dir-yPos_rec-fastRecon', ...
107+
'_run-004_echo-1_bold.nii.gz'];
108+
109+
copyfile( ...
110+
fullfile('..', 'dummyData', 'dummyData.nii.gz'), ...
111+
fullfile(funcDir, boldFilename));
112+
113+
%%
114+
clear;
115+
outputDir = fullfile(fileparts(mfilename('fullpath')), 'output');
116+
cfg.dir.output = outputDir;
83117
convertSourceToRaw(cfg);
84118
end

src/convertSourceToRaw.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function convertSourceToRaw(cfg)
1111
sourceDir = fullfile(cfg.dir.output, 'source');
1212
rawDir = fullfile(cfg.dir.output, 'rawdata');
1313

14-
% add dummy readme and change file
14+
% add dummy README and CHANGE file
1515
copyfile(fullfile( ...
1616
fileparts(mfilename('fullpath')), '..', 'dummyData', 'README'), ...
1717
sourceDir);
@@ -28,6 +28,7 @@ function convertSourceToRaw(cfg)
2828
error('No subjects found in BIDS directory.');
2929
end
3030

31+
% go through the subject files and parses them to remove the date suffix
3132
for su = 1:numel(subjects)
3233

3334
sess = cellstr(file_utils('List', fullfile(rawDir, subjects{su}), 'dir', '^ses-.*$'));

src/createFilename.m

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
function cfg = createFilename(cfg)
2+
% cfg = createFilename(cfg)
3+
%
24
% create the BIDS compliant directories and fileNames for the behavioral output
35
% for this subject / session / run using the information from cfg and expParameters.
46
% Will also create the right fileName for the eyetracking data file.
@@ -99,21 +101,39 @@
99101

100102
cfg.fileName.suffix.run = ['_run-' sprintf(cfg.fileName.pattern, cfg.subject.runNb)];
101103

104+
%% MRI
102105
% set values for the suffixes for the different fields in the BIDS name
103106
fields2Check = { ...
107+
'acquisition', ...
104108
'contrastEnhancement', ...
109+
'echo', ...
105110
'phaseEncodingDirection', ...
106111
'reconstruction', ...
112+
};
113+
114+
targetFields = { ...
115+
'acq', ...
116+
'ce', ...
107117
'echo', ...
108-
'acquisition'
118+
'dir', ...
119+
'rec', ...
109120
};
110121

111122
for iField = 1:numel(fields2Check)
123+
112124
if isempty (cfg.mri.(fields2Check{iField})) %#ok<*GFLD>
125+
113126
cfg.fileName.suffix.mri.(fields2Check{iField}) = ''; %#ok<*SFLD>
127+
114128
else
129+
130+
% upper camelCase and remove invalid characters
131+
thisField = getfield(cfg.mri, fields2Check{iField});
132+
[~, validFieldName] = createValidName(thisField);
133+
115134
cfg.fileName.suffix.mri.(fields2Check{iField}) = ...
116-
['_' fields2Check{iField} '-' getfield(cfg.mri, fields2Check{iField})];
135+
['_' targetFields{iField} '-' validFieldName];
136+
117137
end
118138
end
119139

src/saveEventsFile.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152

153153
% print the basic BIDS columns
154154
fprintf(logFile.fileID, '%s\t%s\t%s', 'onset', 'duration', 'trial_type');
155+
fprintf(1, '%s\t%s\t%s', 'onset', 'duration', 'trial_type');
155156

156157
printHeaderExtraColumns(logFile);
157158

@@ -174,6 +175,7 @@ function printHeaderExtraColumns(logFile)
174175
headerName = returnHeaderName(namesExtraColumns{iExtraColumn}, nbCol, iCol);
175176

176177
fprintf(logFile.fileID, '\t%s', headerName);
178+
fprintf(1, '\t%s', headerName);
177179

178180
end
179181

@@ -281,6 +283,7 @@ function printHeaderExtraColumns(logFile)
281283
printExtraColumns(logFile, iEvent);
282284

283285
fprintf(logFile(1).fileID, '\n');
286+
fprintf(1, '\n');
284287

285288
end
286289
end
@@ -307,12 +310,15 @@ function printData(output, data)
307310
% for numeric data we replace any nan by n/a
308311
if ischar(data)
309312
fprintf(output, '%s\t', data);
313+
fprintf(1, '%s\t', data);
310314
else
311315
for i = 1:numel(data)
312316
if isnan(data(i))
313317
fprintf(output, '%s\t', 'n/a');
318+
fprintf(1, '%s\t', 'n/a');
314319
else
315320
fprintf(output, '%f\t', data(i));
321+
fprintf(1, '%f\t', data(i));
316322
end
317323
end
318324
end
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
function [taskName, taskNameValid] = createTaskName(taskName)
1+
function [name, nameValid] = createValidName(name)
22
% [taskName, taskNameValid] = createTaskName(taskName)
33
%
44
% Name of the task (for resting state use the "rest" prefix). No two tasks
55
% should have the same name. Task label is derived from this field by
66
% removing all non alphanumeric ([a-zA-Z0-9]) characters.
77

88
% camel case: upper case for first letter for all words but the first one
9-
spaceIdx = regexp(taskName, '[a-zA-Z0-9]*', 'start');
10-
taskName(spaceIdx(2:end)) = upper(taskName(spaceIdx(2:end)));
9+
spaceIdx = regexp(name, '[a-zA-Z0-9]*', 'start');
10+
name(spaceIdx(2:end)) = upper(name(spaceIdx(2:end)));
1111

1212
% remove invalid characters
13-
[unvalidCharacters] = regexp(taskName, '[^a-zA-Z0-9]');
14-
taskNameValid = taskName;
15-
taskNameValid(unvalidCharacters) = [];
13+
[unvalidCharacters] = regexp(name, '[^a-zA-Z0-9]');
14+
nameValid = name;
15+
nameValid(unvalidCharacters) = [];
1616

1717
end

src/subfun/transferInfoToBids.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
% relevant field for its reuse for BIDS filenames or JSON later
66

77
if isfield(cfg, 'task') && isfield(cfg.task, 'name')
8-
[taskName, taskNameValid] = createTaskName(cfg.task.name);
8+
[taskName, taskNameValid] = createValidName(cfg.task.name);
99
fieldsToSet.fileName.task = taskNameValid;
1010
fieldsToSet.bids.meg.TaskName = taskName;
1111
fieldsToSet.bids.mri.TaskName = taskName;

tests/test_checkCFG.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,4 @@ function test_checkCfgBasic()
124124

125125
expectedCfgStructure = orderfields(expectedCfgStructure);
126126

127-
end
127+
end

tests/test_createFilename.m

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,52 @@ function test_createFilenameMriEyetracker()
9494

9595
end
9696

97+
function test_createFilenameMriSuffix()
98+
99+
outputDir = fullfile(fileparts(mfilename('fullpath')), '..', 'output');
100+
101+
%% set up
102+
103+
cfg.verbose = false;
104+
cfg.subject.subjectGrp = 'ssri';
105+
cfg.subject.subjectNb = 3;
106+
cfg.subject.sessionNb = 4;
107+
cfg.subject.runNb = 5;
108+
cfg.task.name = 'rest';
109+
cfg.dir.output = outputDir;
110+
111+
cfg.eyeTracker.do = false;
112+
cfg.testingDevice = 'mri';
113+
114+
cfg.mri.reconstruction = 'fast recon';
115+
cfg.mri.contrastEnhancement = 'test';
116+
cfg.mri.phaseEncodingDirection = 'y pos';
117+
cfg.mri.echo = '1';
118+
cfg.mri.acquisition = ' new tYpe';
119+
120+
cfg = createFilename(cfg);
121+
122+
%% data to test against
123+
124+
funcDir = fullfile(outputDir, 'source', 'sub-ssri003', 'ses-004', 'func');
125+
126+
baseFilename = 'sub-ssri003_ses-004_task-rest';
127+
128+
eventFilename = ['sub-ssri003_ses-004_task-rest', ...
129+
'_acq-newTYpe_ce-test_dir-yPos_rec-fastRecon', ...
130+
'_run-005_echo-1_events_date-' ...
131+
cfg.fileName.date '.tsv'];
132+
133+
%% tests
134+
% make sure the func dir is created
135+
assertTrue(exist(funcDir, 'dir') == 7);
136+
137+
% make sure the right filenames are created
138+
assertEqual(cfg.fileName.base, baseFilename);
139+
assertEqual(cfg.fileName.events, eventFilename);
140+
141+
end
142+
97143
function test_createFilenameEeg()
98144

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

tests/test_createTaskName.m renamed to tests/test_createValidName.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function test_suite = test_createTaskName %#ok<*STOUT>
1+
function test_suite = test_createValidName %#ok<*STOUT>
22
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
33
test_functions = localfunctions(); %#ok<*NASGU>
44
catch % no problem; early Matlab versions can use initTestSuite fine
@@ -12,7 +12,7 @@ function test_createTaskNameRemoveInvalidCharacters()
1212

1313
taskName = '&|@#-_(§!{})[]ù%£+/=:;.?,\<> visual task';
1414

15-
[taskName, taskNameValid] = createTaskName(taskName);
15+
[~, taskNameValid] = createValidName(taskName);
1616

1717
[unvalidCharacters] = regexp(taskNameValid, '[^a-zA-Z0-9]');
1818

@@ -22,15 +22,15 @@ function test_createTaskNameRemoveInvalidCharacters()
2222
%% set up
2323
taskName = ' 09 visual task';
2424

25-
[taskName, taskNameValid] = createTaskName(taskName);
25+
[~, taskNameValid] = createValidName(taskName);
2626

2727
[unvalidCharacters] = regexp(taskNameValid, '[^a-zA-Z0-9]');
2828

2929
%% test
3030
assertTrue(isempty(unvalidCharacters));
3131

3232
taskName = 'foo bar';
33-
[taskName, taskNameValid] = createTaskName(taskName);
33+
[taskName, taskNameValid] = createValidName(taskName);
3434
assert(isequal(taskName, 'foo Bar'));
3535
assert(isequal(taskNameValid, 'fooBar'));
3636

@@ -40,7 +40,7 @@ function test_createTaskNameCamelCase()
4040

4141
%% set up
4242
taskName = 'foo bar';
43-
[taskName, taskNameValid] = createTaskName(taskName);
43+
[taskName, taskNameValid] = createValidName(taskName);
4444

4545
%% test
4646
assertEqual(taskName, 'foo Bar');

0 commit comments

Comments
 (0)