Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@

check_my_code_report.txt
test_code_report.txt

output/**
8 changes: 8 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[submodule "lib/bids-matlab"]
path = lib/bids-matlab
url = https://github.com/bids-standard/bids-matlab.git
branch = master
[submodule "lib/JSONio"]
path = lib/JSONio
url = https://github.com/gllmflndn/JSONio.git
branch = master
27 changes: 15 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,32 @@ before_install:
- travis_retry sudo apt-get -y -qq update
- travis_retry sudo apt-get -y install octave
- travis_retry sudo apt-get -y install liboctave-dev
# - travis_retry sudo apt-get -y install nodejs
# - travis_retry sudo apt-get -y install npm
- travis_retry sudo apt-get -y install nodejs
- travis_retry sudo apt-get -y install npm
- cd .. && git clone https://github.com/florianschanda/miss_hit.git && export PATH=$PATH:`pwd`/miss_hit && cd CPP_BIDS


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

before_script:
# Change current directory
- cd tests

jobs:
include:
- stage: "Tests and linter"
name: "Unit Tests" # names the first job
- stage: "Tests"
name: "Unit and integration Tests"
script: octave $OCTFLAGS --eval "results = runTests; assert(all(~[results.Failed]))"
- script: cd .. && mh_style.py `pwd`
name: "miss_hit linter" # names the second job
- stage: "BIDS validator"
name: "Create and check dataset"
script: octave $OCTFLAGS --eval "testmanual_makeRawDataset" && bids-validator `pwd`/../output/rawdata/ --ignoreNiftiHeaders
- stage: "Linter"
name: "miss_hit"
script: cd .. && mh_style `pwd`


7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,17 @@ logFile.extraColumns = {'Speed', 'is_Fixation'};

[cfg, expParameters] = createFilename(cfg, expParameters);

% dummy call to initialize the logFile variable
logFile = saveEventsFile('open', expParameters, logFile);
% initialize the logFile variable
[logFile] = saveEventsFile('init', expParameters, logFile);

% set the real length we really want
logFile.extraColumns.Speed.length = 12;

% actual inititalization
% open the file
logFile = saveEventsFile('open', expParameters, logFile);
```


## Functions descriptions

### userInputs
Expand Down
118 changes: 76 additions & 42 deletions checkCFG.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
function [cfg, expParameters] = checkCFG(cfg, expParameters)
% check that we have all the fields that we need in the experiment parameters

checkCppBidsDependencies();

if nargin < 1 || isempty(cfg)
cfg = struct();
end
if nargin < 2 || isempty(expParameters)
expParameters = struct();
end

%% set the expParameters defaults

fieldsToSet.verbose = 0;
Expand All @@ -9,67 +18,92 @@
'..', ...
'output');

fieldsToSet.subjectGrp = []; % in case no group was provided
fieldsToSet = mriDefaults(fieldsToSet);

fieldsToSet.subjectGrp = ''; % in case no group was provided
fieldsToSet.sessionNb = 1; % in case no session was provided
fieldsToSet.askGrpSess = [true true];

% BIDS
expParameters = setDefaultFields(expParameters, fieldsToSet);

% dataset description json
% required
fieldsToSet.bids.datasetDescription.json.Name = '';
fieldsToSet.bids.datasetDescription.json.BIDSVersion = '';
% recommended
fieldsToSet.bids.datasetDescription.json.License = '';
fieldsToSet.bids.datasetDescription.json.Authors = {''};
fieldsToSet.bids.datasetDescription.json.Acknowledgements = '';
fieldsToSet.bids.datasetDescription.json.HowToAcknowledge = '';
fieldsToSet.bids.datasetDescription.json.Funding = {''};
fieldsToSet.bids.datasetDescription.json.ReferencesAndLinks = {''};
fieldsToSet.bids.datasetDescription.json.DatasetDOI = '';

% mri
% for json
fieldsToSet.MRI.repetitionTime = [];
% for file naming
fieldsToSet.MRI.ce = [];
fieldsToSet.MRI.dir = []; % phase encoding direction of acquisition for fMRI
fieldsToSet.MRI.rec = []; % reconstruction of fMRI images
fieldsToSet.MRI.echo = []; % echo fMRI images
fieldsToSet.MRI.acq = []; % acquisition of fMRI images
%% BIDS
clear fieldsToSet;
fieldsToSet.bids = struct();
expParameters = setDefaultFields(expParameters, fieldsToSet);

clear fieldsToSet;
fieldsToSet.MRI = struct();
fieldsToSet.datasetDescription = struct();
expParameters.bids = setDefaultFields(expParameters.bids, fieldsToSet);

clear fieldsToSet;
fieldsToSet = datasetDescriptionDefaults();

expParameters.bids.datasetDescription = ...
setDefaultFields(expParameters.bids.datasetDescription, fieldsToSet);

clear fieldsToSet;
fieldsToSet = mriJsonDefaults();
if isfield(expParameters, 'task')
fieldsToSet.TaskName = expParameters.task;
end

expParameters.bids.MRI = ...
setDefaultFields(expParameters.bids.MRI, fieldsToSet);

expParameters = setDefaults(expParameters, fieldsToSet);
% sort fields alphabetically
expParameters = orderfields(expParameters);

%% set the cfg defaults

clear fieldsToSet;
fieldsToSet.testingDevice = 'pc';
fieldsToSet.eyeTracker = false;

cfg = setDefaults(cfg, fieldsToSet);
cfg = setDefaultFields(cfg, fieldsToSet);

end
% sort fields alphabetically
cfg = orderfields(cfg);

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

names = fieldnames(fieldsToSet);
function fieldsToSet = mriDefaults(fieldsToSet)

for i = 1:numel(names)
% for file naming
fieldsToSet.MRI.ce = [];
fieldsToSet.MRI.dir = []; % phase encoding direction of acquisition for fMRI
fieldsToSet.MRI.rec = []; % reconstruction of fMRI images
fieldsToSet.MRI.echo = []; % echo fMRI images
fieldsToSet.MRI.acq = []; % acquisition of fMRI images

thisField = fieldsToSet.(names{i});
end

structure = setFieldToIfNotPresent( ...
structure, ...
names{i}, ...
thisField);
function fieldsToSet = datasetDescriptionDefaults()
% required
fieldsToSet.Name = '';
fieldsToSet.BIDSVersion = '';
% recommended
fieldsToSet.License = '';
fieldsToSet.Authors = {''};
fieldsToSet.Acknowledgements = '';
fieldsToSet.HowToAcknowledge = '';
fieldsToSet.Funding = {''};
fieldsToSet.ReferencesAndLinks = {''};
fieldsToSet.DatasetDOI = '';
end

end
function fieldsToSet = mriJsonDefaults()

end
% for json for funcfional data
% required
fieldsToSet.RepetitionTime = [];
fieldsToSet.SliceTiming = [];
fieldsToSet.TaskName = [];
% fieldsToSet.PhaseEncodingDirection = [];
% fieldsToSet.EffectiveEchoSpacing = [];
% fieldsToSet.EchoTime = [];
% recommended
fieldsToSet.Instructions = [];
fieldsToSet.TaskDescription = [];

function structure = setFieldToIfNotPresent(structure, fieldName, value)
if ~isfield(structure, fieldName)
structure.(fieldName) = value;
end
end
9 changes: 9 additions & 0 deletions checkCppBidsDependencies.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function checkCppBidsDependencies

pth = fileparts(mfilename('fullpath'));
addpath(fullfile(pth, 'lib', 'JSONio'));
addpath(fullfile(pth, 'lib', 'bids-matlab'));
addpath(fullfile(pth, 'lib', 'utils'));
addpath(fullfile(pth, 'subfun'));

end
69 changes: 69 additions & 0 deletions convertSourceToRaw.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
function convertSourceToRaw(expParameters)

sourceDir = fullfile(expParameters.outputDir, 'source');
rawDir = fullfile(expParameters.outputDir, 'rawdata');

% add dummy readme and change file
copyfile(fullfile('..', 'dummyData', 'README'), sourceDir);
copyfile(fullfile('..', 'dummyData', 'CHANGES'), sourceDir);

copyfile(sourceDir, rawDir);

% list subjects
subjects = cellstr(file_utils('List', rawDir, 'dir', '^sub-.*$'));

if isequal(subjects, {''})
error('No subjects found in BIDS directory.');
end

for su = 1:numel(subjects)

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

for se = 1:numel(sess)
parseFunc(rawDir, subjects{su}, sess{se});
end

end

end

function parseFunc(rawDir, subjName, sesName)

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

if exist(subjectPath, 'dir')

% do events
filenames = file_utils('List', subjectPath, ...
sprintf('^%s.*_task-.*_events_date-.*$', subjName));

removeDateSuffix(filenames, subjectPath);

% do bold
filenames = file_utils('List', subjectPath, ...
sprintf('^%s.*_task-.*_bold_date-.*$', subjName));

removeDateSuffix(filenames, subjectPath);

end
end

function removeDateSuffix(filenames, subjectPath)
if isempty(filenames)
filenames = {};
else
filenames = cellstr(filenames);
end

for i = 1:numel(filenames)

[~, name, ext] = fileparts(filenames{i});

[parts, ~] = regexp(name, '(?:_date-)+', 'split', 'match');

movefile(fullfile(subjectPath, filenames{i}), ...
fullfile(subjectPath, [parts{1} ext]));

end
end
17 changes: 17 additions & 0 deletions createBoldJson.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function createBoldJson(expParameters)

opts.Indent = ' ';

fileName = strrep(expParameters.fileName.events, '_events', '_bold');
fileName = strrep(fileName, '.tsv', '.json');

fileName = fullfile( ...
expParameters.subjectOutputDir, ...
expParameters.modality, ...
fileName);

jsonContent = expParameters.bids.MRI;

bids.util.jsonencode(fileName, jsonContent, opts);

end
44 changes: 44 additions & 0 deletions createDataDictionary.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function createDataDictionary(expParameters, logFile)

opts.Indent = ' ';

fileName = strrep(expParameters.fileName.events, '.tsv', '.json');

fileName = fullfile( ...
expParameters.subjectOutputDir, ...
expParameters.modality, ...
fileName);

jsonContent = struct( ...
'onset', struct( ...
'Description', 'time elapsed since experiment start', ...
'Unit', 's'), ...
'trial_type', struct( ...
'Description', 'types of trial', ...
'Levels', ''), ...
'duration', struct( ...
'Description', 'duration of the event or the block', ...
'Unit', 's') ...
);

% transfer content of extra fields to json content
namesExtraColumns = returnNamesExtraColumns(logFile);

for iExtraColumn = 1:numel(namesExtraColumns)

nbCol = returnNbColumns(logFile, namesExtraColumns{iExtraColumn});

for iCol = 1:nbCol

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

jsonContent.(headerName) = ...
logFile(1).extraColumns.(namesExtraColumns{iExtraColumn}).bids;

end

end

bids.util.jsonencode(fileName, jsonContent, opts);

end
13 changes: 13 additions & 0 deletions createDatasetDescription.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function createDatasetDescription(expParameters)

opts.Indent = ' ';

fileName = fullfile( ...
expParameters.outputDir, 'source', ...
'dataset_description.json');

jsonContent = expParameters.bids.datasetDescription;

bids.util.jsonencode(fileName, jsonContent, opts);

end
Loading