Skip to content

Commit 73dd76b

Browse files
committed
update doc, help section and readme
1 parent 4077957 commit 73dd76b

16 files changed

+173
-37
lines changed

.travis.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
# Travis CI (https://travis-ci.org/)
22

33
language: c
4-
dist: bionic
4+
dist: bionic # based on bionic beaver ubuntu distribution
55
cache:
66
apt: true # only works with Pro version
77

88
env:
9-
global:
9+
global: # define environment variables for bash
1010
- OCTFLAGS="--no-gui --no-window-system --silent"
1111

1212
before_install:
1313
- travis_retry sudo apt-get -y -qq update
14+
# install octave
1415
- travis_retry sudo apt-get -y install octave
1516
- travis_retry sudo apt-get -y install liboctave-dev
17+
# install javascript
1618
- travis_retry sudo apt-get -y install nodejs
1719
- travis_retry sudo apt-get -y install npm
20+
# install miss_hit linter
1821
- cd .. && git clone https://github.com/florianschanda/miss_hit.git && export PATH=$PATH:`pwd`/miss_hit && cd CPP_BIDS
1922

2023

2124
install:
22-
# make octave file for JSONio
25+
# make octave file the JSONio submodule
2326
- cd lib/JSONio; mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS; cd ../..
2427
- octave $OCTFLAGS --eval "addpath (pwd); savepath ();"
2528
# Install BIDS-Validator
@@ -31,7 +34,7 @@ before_script:
3134

3235
jobs:
3336
include:
34-
- stage: "Tests"
37+
- stage: "Tests"
3538
name: "Unit and integration Tests"
3639
script: octave $OCTFLAGS --eval "results = runTests; assert(all(~[results.Failed]))"
3740
- stage: "BIDS validator"

README.md

Lines changed: 120 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
<!-- TOC -->
66

77
- [CPP_BIDS](#cpp_bids)
8+
- [Output format](#output-format)
9+
- [Modality agnostic aspect](#modality-agnostic-aspect)
810
- [Usage](#usage)
911
- [To save events.tsv file](#to-save-eventstsv-file)
1012
- [Functions descriptions](#functions-descriptions)
1113
- [userInputs](#userinputs)
1214
- [createFilename](#createfilename)
1315
- [saveEventsFile](#saveeventsfile)
1416
- [checkCFG](#checkcfg)
17+
- [CFG content](#cfg-content)
1518
- [How to install](#how-to-install)
1619
- [Use the matlab package manager](#use-the-matlab-package-manager)
1720
- [Contributing](#contributing)
@@ -23,24 +26,42 @@
2326

2427
A set of function for matlab and octave to create [BIDS-compatible](https://bids-specification.readthedocs.io/en/stable/) folder structure and filenames for the output of behavioral, EEG, fMRI, eyetracking studies.
2528

29+
## Output format
30+
31+
## Modality agnostic aspect
32+
33+
Subjects, session and run number labels will be numbers with zero padding up to 3 values (e.g subject 1 will become `sub-001`).
34+
35+
A session folder will ALWAYS be created even if not requested (default will be `ses-001`).
36+
37+
Task labels will be printed in camelCase in the filenames.
38+
39+
Time stamps are added directly in the filename by adding a suffix `_date-YYYYMMDDHHMM` which makes the file name non-BIDS compliant. This was added to prevent overwriting files in case a certain run needs to be done a second time because of a crash (Some of us are paranoid about keeping even cancelled runs during my experiments). This suffix should be removed to make the data set BIDS compliant. See `convertSourceToRaw.m` for more details.
40+
41+
For example:
42+
43+
```
44+
sub-090/ses-003/sub-090_ses-003_task-auditoryTask_run-023_events_date-202007291536.tsv
45+
```
46+
2647
## Usage
2748

2849
### To save events.tsv file
2950

3051
```matlab
3152
3253
% define the folder where the data will be saved
33-
expParameters.outputDir = fullfile(pwd, '..', 'output');
54+
cfg.outputDir = fullfile(pwd, '..', 'output');
3455
3556
% define the name of the task
36-
expParameters.task = 'testtask';
57+
cfg.task = 'test task';
3758
3859
% can use the userInputs function to collect subject info
39-
% expParameters = userInputs;
60+
% cfg = userInputs;
4061
4162
% or declare it directly
42-
expParameters.subjectNb = 1;
43-
expParameters.runNb = 1;
63+
cfg.subjectNb = 1;
64+
cfg.runNb = 1;
4465
4566
% by default we assume you are running things on a behavioral PC with no eyetracker
4667
% cfg.eyeTracker = false;
@@ -53,14 +74,14 @@ expParameters.runNb = 1;
5374
% cfg.testingDevice = 'eeg';
5475
5576
% create the filenames: this include a step to check that all the information is there (checkCFG)
56-
[cfg, expParameters] = createFilename(cfg, expParameters);
77+
[cfg] = createFilename(cfg);
5778
5879
% initialize the events files with the typical BIDS columns (onsets, duration, trial_type)
59-
% logFile = saveEventsFile('open', expParameters);
80+
% logFile = saveEventsFile('open', cfg);
6081
6182
% You can add some more in this case (Speed and is_Fixation)
6283
logFile.extraColumns = {'Speed', 'is_Fixation'};
63-
logFile = saveEventsFile('open', expParameters, logFile);
84+
logFile = saveEventsFile('open', cfg, logFile);
6485
6586
% The information about 2 events that we want to save
6687
% NOTE : If the user DOES NOT provide `onset`, `trial_type`, this events will be skipped.
@@ -76,24 +97,24 @@ logFile(2,1).duration = 4;
7697
logFile(2,1).is_Fixation = 3;
7798
7899
% add those 2 events to the events.tsv file
79-
saveEventsFile('save', expParameters, logFile);
100+
saveEventsFile('save', cfg, logFile);
80101
81102
% close the file
82-
saveEventsFile('close', expParameters, logFile);
103+
saveEventsFile('close', cfg, logFile);
83104
84105
```
85106

86107
If you want to save more complex events.tsv file you can save several columns at once.
87108

88109
```matlab
89-
expParameters.subjectNb = 1;
90-
expParameters.runNb = 1;
91-
expParameters.task = 'testtask';
92-
expParameters.outputDir = outputDir;
110+
cfg.subjectNb = 1;
111+
cfg.runNb = 1;
112+
cfg.task = 'testtask';
113+
cfg.outputDir = outputDir;
93114
94115
cfg.testingDevice = 'mri';
95116
96-
[cfg, expParameters] = createFilename(cfg, expParameters);
117+
[cfg] = createFilename(cfg);
97118
98119
% You can specify how many columns we want for each variable
99120
% will set 1 columns with name Speed
@@ -104,7 +125,7 @@ logFile.extraColumns.Speed.length = 1;
104125
logFile.extraColumns.LHL24.length = 12;
105126
logFile.extraColumns.is_Fixation.length = 1;
106127
107-
logFile = saveEventsFile('open', expParameters, logFile);
128+
logFile = saveEventsFile('open', cfg, logFile);
108129
109130
logFile(1, 1).onset = 2;
110131
logFile(end, 1).trial_type = 'motion_up';
@@ -113,9 +134,9 @@ logFile(end, 1).Speed = 2;
113134
logFile(end, 1).is_Fixation = true;
114135
logFile(end, 1).LHL24 = 1:12;
115136
116-
saveEventsFile('save', expParameters, logFile);
137+
saveEventsFile('save', cfg, logFile);
117138
118-
saveEventsFile('close', expParameters, logFile);
139+
saveEventsFile('close', cfg, logFile);
119140
120141
```
121142

@@ -125,16 +146,16 @@ If you have many columns to define but only a few with several columns, you can
125146
% define the extra columns: they will be added to the tsv files in the order the user input them
126147
logFile.extraColumns = {'Speed', 'is_Fixation'};
127148
128-
[cfg, expParameters] = createFilename(cfg, expParameters);
149+
[cfg] = createFilename(cfg);
129150
130151
% initialize the logFile variable
131-
[logFile] = saveEventsFile('init', expParameters, logFile);
152+
[logFile] = saveEventsFile('init', cfg, logFile);
132153
133154
% set the real length we really want
134155
logFile.extraColumns.Speed.length = 12;
135156
136157
% open the file
137-
logFile = saveEventsFile('open', expParameters, logFile);
158+
logFile = saveEventsFile('open', cfg, logFile);
138159
```
139160

140161

@@ -144,23 +165,23 @@ logFile = saveEventsFile('open', expParameters, logFile);
144165

145166
Get subject, run and session number and make sure they are positive integer values.
146167

147-
By default this will return `expParameters.session = 1` even if you asked it to omit enquiring about sessions. This means
168+
By default this will return `cfg.subject.session = 1` even if you asked it to omit enquiring about sessions. This means
148169
that the folder tree will always include a session folder.
149170

150171
```matlab
151-
[expParameters] = userInputs(cfg, expParameters)
172+
[cfg] = userInputs(cfg)
152173
```
153174

154-
if you use it with `expParameters.askGrpSess = [0 0]`
175+
if you use it with `cfg.subject.askGrpSess = [0 0]`
155176
it won't ask you about group or session
156177

157-
if you use it with `expParameters.askGrpSess = [1]`
178+
if you use it with `cfg.subject.askGrpSess = [1]`
158179
it will only ask you about group
159180

160-
if you use it with `expParameters.askGrpSess = [0 1]`
181+
if you use it with `cfg.subject.askGrpSess = [0 1]`
161182
it will only ask you about session
162183

163-
if you use it with `expParameters.askGrpSess = [1 1]`
184+
if you use it with `cfg.subject.askGrpSess = [1 1]`
164185
it will ask you about both
165186
this is the default
166187

@@ -190,6 +211,74 @@ no value is provided.
190211

191212
Check that we have all the fields that we need in the experiment parameters.
192213

214+
## CFG content
215+
216+
```matlab
217+
%% Can be modified by users
218+
% but their effect might only be effective after running
219+
% checkCFG
220+
221+
cfg.verbose = 0;
222+
223+
cfg.subject.subjectGrp = '';
224+
cfg.subject.sessionNb = 1;
225+
cfg.subject.askGrpSess = [true true];
226+
227+
% BOLD MRI details
228+
% some of those will be transferred to the correct fields in cfg.bids by checkCFG
229+
cfg.mri.repetitionTime = [];
230+
cfg.mri.contrastEnhancement = [];
231+
cfg.mri.phaseEncodingDirection = [];
232+
cfg.mri.reconstruction = [];
233+
cfg.mri.echo = [];
234+
cfg.mri.acquisition = [];
235+
236+
cfg.fileName.task = '';
237+
cfg.fileName.zeroPadding = 3; % amount of 0 padding the subject, session, run number
238+
239+
cfg.eyeTracker.do = false;
240+
241+
% content of the json side-car file for bold data
242+
cfg.bids.mri.RepetitionTime = [];
243+
cfg.bids.mri.SliceTiming = '';
244+
cfg.bids.mri.TaskName = '';
245+
cfg.bids.mri.Instructions = '';
246+
cfg.bids.mri.TaskDescription = '';
247+
248+
% content of the json side-car file for MEG
249+
cfg.bids.meg.TaskName = '';
250+
cfg.bids.meg.SamplingFrequency = [];
251+
cfg.bids.meg.PowerLineFrequency = [];
252+
cfg.bids.meg.DewarPosition = [];
253+
cfg.bids.meg.SoftwareFilters = [];
254+
cfg.bids.meg.DigitizedLandmarks = [];
255+
cfg.bids.meg.DigitizedHeadPoints = [];
256+
257+
% content of the datasetDescription.json file
258+
cfg.bids.datasetDescription.Name = '';
259+
cfg.bids.datasetDescription.BIDSVersion = '';
260+
cfg.bids.datasetDescription.License = '';
261+
cfg.bids.datasetDescription.Authors = {''};
262+
cfg.bids.datasetDescription.Acknowledgements = '';
263+
cfg.bids.datasetDescription.HowToAcknowledge = '';
264+
cfg.bids.datasetDescription.Funding = {''};
265+
cfg.bids.datasetDescription.ReferencesAndLinks = {''};
266+
cfg.bids.datasetDescription.DatasetDOI = '';
267+
268+
269+
%% Should not be modified by users
270+
% many of those fields are set up by checkCFG and you might get non BIDS valid
271+
% output if you touch those
272+
cfg.fileName.dateFormat = 'yyyymmddHHMM'; % actual date of the experiment that is appended to the filename
273+
cfg.fileName.modality
274+
cgf.fileName.suffix.mri
275+
cgf.fileName.suffix.meg
276+
cfg.fileName.stim
277+
cfg.fileName.events
278+
cfg.fileName.datasetDescription
279+
280+
```
281+
193282
## How to install
194283

195284
### Use the matlab package manager
@@ -261,6 +350,10 @@ Here are the naming templates used.
261350

262351
`sub-<label>[_ses-<label>]_task-<label>[_run-<index>]_eeg.<manufacturer_specific_extension>`
263352

353+
- MEG
354+
355+
???
356+
264357
- Eyetracker
265358

266359
`sub-<participant_label>[_ses-<label>][_acq-<label>]_task-<task_label>_eyetrack.<manufacturer_specific_extension>`

checkCFG.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
function cfg = checkCFG(cfg)
2+
% cfg = checkCFG(cfg)
3+
%
24
% check that we have all the fields that we need in the experiment parameters
35
% reuses a lot of code from the BIDS starter kit
46

checkCppBidsDependencies.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
function checkCppBidsDependencies
2-
1+
function checkCppBidsDependencies()
2+
% checkCppBidsDependencies()
3+
%
4+
35
pth = fileparts(mfilename('fullpath'));
46

57
checkSubmodule(fullfile(pth, 'lib', 'JSONio'));

convertSourceToRaw.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
function convertSourceToRaw(cfg)
2+
% convertSourceToRaw(cfg)
3+
%
4+
% attempts to convert a source dataset created with CPP_BIDS into a valid
5+
% BIDS data set.
6+
% - creates dummy README and CHANGE file
7+
% - copy source dir to raw dir
8+
% - remove the date suffix (_date-YYYYMMDDHHMM) from the files where it is present
9+
%
210

311
sourceDir = fullfile(cfg.dir.output, 'source');
412
rawDir = fullfile(cfg.dir.output, 'rawdata');

createBoldJson.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
function createBoldJson(cfg)
2+
% createBoldJson(cfg)
3+
%
4+
% Creates the side car JSON file for a BOLD functional run.
5+
% This will only contain the minimum BIDS requirement and will likey be less
6+
% complete than the info you could from DICOM conversion.
27

38
opts.Indent = ' ';
49

createDataDictionary.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
function createDataDictionary(cfg, logFile)
2+
% createDataDictionary(cfg, logFile)
3+
%
4+
% creates the data dictionary to be associated with a _events.tsv file
5+
% will create empty field that you can then fill in manually in the JSON
6+
% file
27

38
opts.Indent = ' ';
49

createDatasetDescription.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
function createDatasetDescription(cfg)
2+
% createDatasetDescription(cfg)
3+
%
4+
% creates the datasetDescription.json file that goes in the root of a BIDS
5+
% dataset
26

37
opts.Indent = ' ';
48

createFilename.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
%
88
% can work for behavioral experiment if cfg.device is set to 'PC'
99
% can work for fMRI experiment if cfg.device is set to 'scanner'
10-
% can work for simple eyetracking data if cfg.eyeTracker is set to 1
10+
% can work for simple eyetracking data if cfg.eyeTracker.do is set to 1
1111
%
1212
%
1313
% See test_createFilename in the test folder for more details on how to use it.

saveEventsFile.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
function [logFile] = saveEventsFile(action, cfg, logFile)
2+
% [logFile] = saveEventsFile(action, cfg, logFile)
3+
%
24
% Function to save output files for events that will be BIDS compliant.
35
%
46
% INPUTS
@@ -28,7 +30,7 @@
2830
% This creates the header with the obligatory 'onset', 'trial_type', 'duration' required
2931
% by BIDS and other columns can be specified in varargin.
3032
%
31-
% example : logFile = saveEventsFile('open', expParameters, [], 'direction', 'speed', 'target');
33+
% example : logFile = saveEventsFile('open', cfg, [], 'direction', 'speed', 'target');
3234
%
3335
% - 'save': will save the data contained in logfile by using the file ID logFile.fileID;
3436
% logfile must then contain:

0 commit comments

Comments
 (0)