Skip to content

Commit 30406fb

Browse files
committed
Merge remote-tracking branch 'cpp-lln-lab/master'
2 parents e1958ae + ed7577a commit 30406fb

38 files changed

+1210
-180
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@
1010

1111
check_my_code_report.txt
1212
test_code_report.txt
13+
14+
output/**

.gitmodules

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[submodule "lib/bids-matlab"]
2+
path = lib/bids-matlab
3+
url = https://github.com/bids-standard/bids-matlab.git
4+
branch = master
5+
[submodule "lib/JSONio"]
6+
path = lib/JSONio
7+
url = https://github.com/gllmflndn/JSONio.git
8+
branch = master

.travis.yml

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,32 @@ before_install:
1313
- travis_retry sudo apt-get -y -qq update
1414
- travis_retry sudo apt-get -y install octave
1515
- travis_retry sudo apt-get -y install liboctave-dev
16-
# - travis_retry sudo apt-get -y install nodejs
17-
# - travis_retry sudo apt-get -y install npm
16+
- travis_retry sudo apt-get -y install nodejs
17+
- travis_retry sudo apt-get -y install npm
1818
- cd .. && git clone https://github.com/florianschanda/miss_hit.git && export PATH=$PATH:`pwd`/miss_hit && cd CPP_BIDS
1919

2020

2121
install:
22-
# Install JSONio
23-
#- travis_retry git clone git://github.com/gllmflndn/JSONio.git --depth 1
24-
#- cd JSONio; mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS; cd ..
25-
#- octave $OCTFLAGS --eval "addpath (fullfile (pwd, 'JSONio')); savepath ();"
26-
# Install BIDS-MATLAB
22+
# make octave file for JSONio
23+
- cd lib/JSONio; mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS; cd ../..
2724
- octave $OCTFLAGS --eval "addpath (pwd); savepath ();"
2825
# Install BIDS-Validator
29-
#- sudo npm install -g bids-validator
26+
- sudo npm install -g bids-validator
3027

3128
before_script:
3229
# Change current directory
3330
- cd tests
3431

3532
jobs:
3633
include:
37-
- stage: "Tests and linter"
38-
name: "Unit Tests" # names the first job
34+
- stage: "Tests"
35+
name: "Unit and integration Tests"
3936
script: octave $OCTFLAGS --eval "results = runTests; assert(all(~[results.Failed]))"
40-
- script: cd .. && mh_style.py `pwd`
41-
name: "miss_hit linter" # names the second job
37+
- stage: "BIDS validator"
38+
name: "Create and check dataset"
39+
script: octave $OCTFLAGS --eval "testmanual_makeRawDataset" && bids-validator `pwd`/../output/rawdata/ --ignoreNiftiHeaders
40+
- stage: "Linter"
41+
name: "miss_hit"
42+
script: cd .. && mh_style `pwd`
43+
44+

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Crossmodal Perception and Plasticity laboratory
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,17 @@ logFile.extraColumns = {'Speed', 'is_Fixation'};
127127
128128
[cfg, expParameters] = createFilename(cfg, expParameters);
129129
130-
% dummy call to initialize the logFile variable
131-
logFile = saveEventsFile('open', expParameters, logFile);
130+
% initialize the logFile variable
131+
[logFile] = saveEventsFile('init', expParameters, logFile);
132132
133133
% set the real length we really want
134134
logFile.extraColumns.Speed.length = 12;
135135
136-
% actual inititalization
136+
% open the file
137137
logFile = saveEventsFile('open', expParameters, logFile);
138138
```
139139

140+
140141
## Functions descriptions
141142

142143
### userInputs

checkCFG.m

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,110 @@
11
function [cfg, expParameters] = checkCFG(cfg, expParameters)
22
% check that we have all the fields that we need in the experiment parameters
33

4+
checkCppBidsDependencies();
5+
6+
if nargin < 1 || isempty(cfg)
7+
cfg = struct();
8+
end
9+
if nargin < 2 || isempty(expParameters)
10+
expParameters = struct();
11+
end
12+
413
%% set the expParameters defaults
514

6-
fieldsToSet.verbose = 0;
15+
fieldsToSet.verbose = false;
716
fieldsToSet.outputDir = fullfile( ...
817
fileparts(mfilename('fullpath')), ...
918
'..', ...
1019
'output');
1120

12-
fieldsToSet.subjectGrp = []; % in case no group was provided
21+
fieldsToSet = mriDefaults(fieldsToSet);
22+
23+
fieldsToSet.subjectGrp = ''; % in case no group was provided
1324
fieldsToSet.sessionNb = 1; % in case no session was provided
1425
fieldsToSet.askGrpSess = [true true];
1526

16-
% BIDS
27+
expParameters = setDefaultFields(expParameters, fieldsToSet);
1728

18-
% dataset description json
19-
% required
20-
fieldsToSet.bids.datasetDescription.json.Name = '';
21-
fieldsToSet.bids.datasetDescription.json.BIDSVersion = '';
22-
% recommended
23-
fieldsToSet.bids.datasetDescription.json.License = '';
24-
fieldsToSet.bids.datasetDescription.json.Authors = {''};
25-
fieldsToSet.bids.datasetDescription.json.Acknowledgements = '';
26-
fieldsToSet.bids.datasetDescription.json.HowToAcknowledge = '';
27-
fieldsToSet.bids.datasetDescription.json.Funding = {''};
28-
fieldsToSet.bids.datasetDescription.json.ReferencesAndLinks = {''};
29-
fieldsToSet.bids.datasetDescription.json.DatasetDOI = '';
30-
31-
% mri
32-
% for json
33-
fieldsToSet.MRI.repetitionTime = [];
34-
% for file naming
35-
fieldsToSet.MRI.ce = [];
36-
fieldsToSet.MRI.dir = []; % phase encoding direction of acquisition for fMRI
37-
fieldsToSet.MRI.rec = []; % reconstruction of fMRI images
38-
fieldsToSet.MRI.echo = []; % echo fMRI images
39-
fieldsToSet.MRI.acq = []; % acquisition of fMRI images
29+
%% BIDS
30+
clear fieldsToSet;
31+
fieldsToSet.bids = struct();
32+
expParameters = setDefaultFields(expParameters, fieldsToSet);
33+
34+
clear fieldsToSet;
35+
fieldsToSet.MRI = struct();
36+
fieldsToSet.datasetDescription = struct();
37+
expParameters.bids = setDefaultFields(expParameters.bids, fieldsToSet);
38+
39+
clear fieldsToSet;
40+
fieldsToSet = datasetDescriptionDefaults();
41+
42+
expParameters.bids.datasetDescription = ...
43+
setDefaultFields(expParameters.bids.datasetDescription, fieldsToSet);
44+
45+
clear fieldsToSet;
46+
fieldsToSet = mriJsonDefaults();
47+
if isfield(expParameters, 'task')
48+
fieldsToSet.TaskName = expParameters.task;
49+
end
50+
51+
expParameters.bids.MRI = ...
52+
setDefaultFields(expParameters.bids.MRI, fieldsToSet);
4053

41-
expParameters = setDefaults(expParameters, fieldsToSet);
54+
% sort fields alphabetically
55+
expParameters = orderfields(expParameters);
4256

4357
%% set the cfg defaults
4458

4559
clear fieldsToSet;
60+
fieldsToSet.verbose = false;
4661
fieldsToSet.testingDevice = 'pc';
4762
fieldsToSet.eyeTracker = false;
4863

49-
cfg = setDefaults(cfg, fieldsToSet);
64+
cfg = setDefaultFields(cfg, fieldsToSet);
5065

51-
end
66+
% sort fields alphabetically
67+
cfg = orderfields(cfg);
5268

53-
function structure = setDefaults(structure, fieldsToSet)
54-
% loop through the defaults fiels to set and update if they don't exist
69+
end
5570

56-
names = fieldnames(fieldsToSet);
71+
function fieldsToSet = mriDefaults(fieldsToSet)
5772

58-
for i = 1:numel(names)
73+
% for file naming
74+
fieldsToSet.MRI.ce = [];
75+
fieldsToSet.MRI.dir = []; % phase encoding direction of acquisition for fMRI
76+
fieldsToSet.MRI.rec = []; % reconstruction of fMRI images
77+
fieldsToSet.MRI.echo = []; % echo fMRI images
78+
fieldsToSet.MRI.acq = []; % acquisition of fMRI images
5979

60-
thisField = fieldsToSet.(names{i});
80+
end
6181

62-
structure = setFieldToIfNotPresent( ...
63-
structure, ...
64-
names{i}, ...
65-
thisField);
82+
function fieldsToSet = datasetDescriptionDefaults()
83+
% required
84+
fieldsToSet.Name = '';
85+
fieldsToSet.BIDSVersion = '';
86+
% recommended
87+
fieldsToSet.License = '';
88+
fieldsToSet.Authors = {''};
89+
fieldsToSet.Acknowledgements = '';
90+
fieldsToSet.HowToAcknowledge = '';
91+
fieldsToSet.Funding = {''};
92+
fieldsToSet.ReferencesAndLinks = {''};
93+
fieldsToSet.DatasetDOI = '';
94+
end
6695

67-
end
96+
function fieldsToSet = mriJsonDefaults()
6897

69-
end
98+
% for json for funcfional data
99+
% required
100+
fieldsToSet.RepetitionTime = [];
101+
fieldsToSet.SliceTiming = [];
102+
fieldsToSet.TaskName = [];
103+
% fieldsToSet.PhaseEncodingDirection = [];
104+
% fieldsToSet.EffectiveEchoSpacing = [];
105+
% fieldsToSet.EchoTime = [];
106+
% recommended
107+
fieldsToSet.Instructions = [];
108+
fieldsToSet.TaskDescription = [];
70109

71-
function structure = setFieldToIfNotPresent(structure, fieldName, value)
72-
if ~isfield(structure, fieldName)
73-
structure.(fieldName) = value;
74-
end
75110
end

checkCppBidsDependencies.m

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function checkCppBidsDependencies
2+
3+
pth = fileparts(mfilename('fullpath'));
4+
5+
checkSubmodule(fullfile(pth, 'lib', 'JSONio'))
6+
checkSubmodule(fullfile(pth, 'lib', 'bids-matlab'))
7+
8+
addpath(fullfile(pth, 'lib', 'utils'));
9+
addpath(fullfile(pth, 'subfun'));
10+
11+
printCreditsCppBids();
12+
13+
end
14+
15+
function checkSubmodule(pth)
16+
% If external dir is empty throw an exception
17+
% and ask user to update submodules.
18+
if numel(dir(pth)) <= 2 % Means that the external is empty
19+
error(['Git submodules are not cloned!', ...
20+
'Try this in your terminal:', ...
21+
' git submodule update --recursive ']);
22+
else
23+
addpath(pth);
24+
end
25+
end

convertSourceToRaw.m

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
function convertSourceToRaw(expParameters)
2+
3+
sourceDir = fullfile(expParameters.outputDir, 'source');
4+
rawDir = fullfile(expParameters.outputDir, 'rawdata');
5+
6+
% add dummy readme and change file
7+
copyfile(fullfile('..', 'dummyData', 'README'), sourceDir);
8+
copyfile(fullfile('..', 'dummyData', 'CHANGES'), sourceDir);
9+
10+
copyfile(sourceDir, rawDir);
11+
12+
% list subjects
13+
subjects = cellstr(file_utils('List', rawDir, 'dir', '^sub-.*$'));
14+
15+
if isequal(subjects, {''})
16+
error('No subjects found in BIDS directory.');
17+
end
18+
19+
for su = 1:numel(subjects)
20+
21+
sess = cellstr(file_utils('List', fullfile(rawDir, subjects{su}), 'dir', '^ses-.*$'));
22+
23+
for se = 1:numel(sess)
24+
parseFunc(rawDir, subjects{su}, sess{se});
25+
end
26+
27+
end
28+
29+
end
30+
31+
function parseFunc(rawDir, subjName, sesName)
32+
33+
subjectPath = fullfile(rawDir, subjName, sesName, 'func');
34+
35+
if exist(subjectPath, 'dir')
36+
37+
% do events
38+
filenames = file_utils('List', subjectPath, ...
39+
sprintf('^%s.*_task-.*_events_date-.*$', subjName));
40+
41+
removeDateSuffix(filenames, subjectPath);
42+
43+
% do bold
44+
filenames = file_utils('List', subjectPath, ...
45+
sprintf('^%s.*_task-.*_bold_date-.*$', subjName));
46+
47+
removeDateSuffix(filenames, subjectPath);
48+
49+
end
50+
end
51+
52+
function removeDateSuffix(filenames, subjectPath)
53+
if isempty(filenames)
54+
filenames = {};
55+
else
56+
filenames = cellstr(filenames);
57+
end
58+
59+
for i = 1:numel(filenames)
60+
61+
[~, name, ext] = fileparts(filenames{i});
62+
63+
[parts, ~] = regexp(name, '(?:_date-)+', 'split', 'match');
64+
65+
movefile(fullfile(subjectPath, filenames{i}), ...
66+
fullfile(subjectPath, [parts{1} ext]));
67+
68+
end
69+
end

createBoldJson.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function createBoldJson(expParameters)
2+
3+
opts.Indent = ' ';
4+
5+
fileName = strrep(expParameters.fileName.events, '_events', '_bold');
6+
fileName = strrep(fileName, '.tsv', '.json');
7+
8+
fileName = fullfile( ...
9+
expParameters.subjectOutputDir, ...
10+
expParameters.modality, ...
11+
fileName);
12+
13+
jsonContent = expParameters.bids.MRI;
14+
15+
bids.util.jsonencode(fileName, jsonContent, opts);
16+
17+
end

0 commit comments

Comments
 (0)