Skip to content

Commit 0f968f8

Browse files
authored
Merge pull request #44 from Remi-Gau/remi-simplify_saveEvents
Simplify save events
2 parents f0d6a46 + ecf30b0 commit 0f968f8

13 files changed

+644
-256
lines changed

README.md

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- [CPP_BIDS](#cpp_bids)
88
- [Usage](#usage)
9+
- [To save events.tsv file](#to-save-eventstsv-file)
910
- [Functions descriptions](#functions-descriptions)
1011
- [userInputs](#userinputs)
1112
- [createFilename](#createfilename)
@@ -24,6 +25,8 @@ A set of function for matlab and octave to create [BIDS-compatible](https://bids
2425

2526
## Usage
2627

28+
### To save events.tsv file
29+
2730
```matlab
2831
2932
% define the folder where the data will be saved
@@ -36,14 +39,12 @@ expParameters.task = 'testtask';
3639
% expParameters = userInputs;
3740
3841
% or declare it directly
39-
expParameters.subjectGrp = '';
4042
expParameters.subjectNb = 1;
41-
expParameters.sessionNb = 1;
4243
expParameters.runNb = 1;
4344
4445
% by default we assume you are running things on a behavioral PC with no eyetracker
45-
cfg.eyeTracker = false;
46-
cfg.testingDevice = 'PC';
46+
% cfg.eyeTracker = false;
47+
% cfg.testingDevice = 'PC';
4748
4849
% if the testing device is set to 'PC' then the data will be saved in the `beh` folder
4950
% if set to 'mri' then the data will be saved in the `func` folder
@@ -54,34 +55,88 @@ cfg.testingDevice = 'PC';
5455
% create the filenames: this include a step to check that all the information is there (checkCFG)
5556
[cfg, expParameters] = createFilename(cfg, expParameters);
5657
57-
% initialize the events files with the typical BIDS
58-
% columns (onsets, duration, trial_type)
59-
% and add some more in this case (Speed and is_Fixation)
60-
logFile = saveEventsFile('open', expParameters, [], 'Speed', 'is_Fixation');
58+
% initialize the events files with the typical BIDS columns (onsets, duration, trial_type)
59+
% logFile = saveEventsFile('open', expParameters);
6160
62-
% to initialize a stim file in case you want to store the info about the stimuli in it
63-
stimFile = saveEventsFile('open_stim', expParameters, []);
61+
% You can add some more in this case (Speed and is_Fixation)
62+
logFile.extraColumns = {'Speed', 'is_Fixation'};
63+
logFile = saveEventsFile('open', expParameters, logFile);
6464
65-
% create the information about 2 events that we want to save
65+
% The information about 2 events that we want to save
66+
% NOTE : If the user DOES NOT provide `onset`, `trial_type`, this events will be skipped.
6667
logFile(1,1).onset = 2;
6768
logFile(1,1).trial_type = 'motion_up';
6869
logFile(1,1).duration = 1;
69-
logFile(1,1).speed = 2;
70-
logFile(1,1).is_fixation = true;
70+
logFile(1,1).Speed = 2;
71+
logFile(1,1).is_Fixation = true;
7172
7273
logFile(2,1).onset = 3;
7374
logFile(2,1).trial_type = 'static';
7475
logFile(2,1).duration = 4;
75-
logFile(2,1).is_fixation = 3;
76+
logFile(2,1).is_Fixation = 3;
7677
7778
% add those 2 events to the events.tsv file
78-
saveEventsFile('save', expParameters, logFile, 'speed', 'is_fixation');
79+
saveEventsFile('save', expParameters, logFile);
7980
8081
% close the file
8182
saveEventsFile('close', expParameters, logFile);
8283
8384
```
8485

86+
If you want to save more complex events.tsv file you can save several columns at once.
87+
88+
```matlab
89+
expParameters.subjectNb = 1;
90+
expParameters.runNb = 1;
91+
expParameters.task = 'testtask';
92+
expParameters.outputDir = outputDir;
93+
94+
cfg.testingDevice = 'mri';
95+
96+
[cfg, expParameters] = createFilename(cfg, expParameters);
97+
98+
% You can specify how many columns we want for each variable
99+
% will set 1 columns with name Speed
100+
% will set 12 columns with names LHL24-01, LHL24-02, ...
101+
% will set 1 columns with name is_Fixation
102+
103+
logFile.extraColumns.Speed.length = 1;
104+
logFile.extraColumns.LHL24.length = 12;
105+
logFile.extraColumns.is_Fixation.length = 1;
106+
107+
logFile = saveEventsFile('open', expParameters, logFile);
108+
109+
logFile(1, 1).onset = 2;
110+
logFile(end, 1).trial_type = 'motion_up';
111+
logFile(end, 1).duration = 3;
112+
logFile(end, 1).Speed = 2;
113+
logFile(end, 1).is_Fixation = true;
114+
logFile(end, 1).LHL24 = 1:12;
115+
116+
saveEventsFile('save', expParameters, logFile);
117+
118+
saveEventsFile('close', expParameters, logFile);
119+
120+
```
121+
122+
If you have many columns to define but only a few with several columns, you can do this:
123+
124+
```matlab
125+
% define the extra columns: they will be added to the tsv files in the order the user input them
126+
logFile.extraColumns = {'Speed', 'is_Fixation'};
127+
128+
[cfg, expParameters] = createFilename(cfg, expParameters);
129+
130+
% dummy call to initialize the logFile variable
131+
logFile = saveEventsFile('open', expParameters, logFile);
132+
133+
% set the real length we really want
134+
logFile.extraColumns.Speed.length = 12;
135+
136+
% actual inititalization
137+
logFile = saveEventsFile('open', expParameters, logFile);
138+
```
139+
85140
## Functions descriptions
86141

87142
### userInputs
@@ -127,7 +182,11 @@ For the moment the date of acquisition is appended to the filename
127182

128183
Function to save output files for events that will be BIDS compliant.
129184

185+
If the user DOES NOT provide `onset`, `trial_type`, this events will be skipped. `duration` will be set to "NaN" if
186+
no value is provided.
187+
130188
### checkCFG
189+
131190
Check that we have all the fields that we need in the experiment parameters.
132191

133192
## How to install

checkCFG.m

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
% check that we have all the fields that we need in the experiment parameters
33

44
%% set the expParameters defaults
5-
5+
66
fieldsToSet.verbose = 0;
77
fieldsToSet.outputDir = fullfile( ...
8-
fileparts(mfilename('fullpath')), ...
9-
'..', ...
10-
'output');
8+
fileparts(mfilename('fullpath')), ...
9+
'..', ...
10+
'output');
1111

1212
fieldsToSet.subjectGrp = []; % in case no group was provided
13-
fieldsToSet.sessionNb = []; % in case no session was provided
13+
fieldsToSet.sessionNb = 1; % in case no session was provided
1414
fieldsToSet.askGrpSess = [true true];
15-
15+
1616
% BIDS
17-
17+
1818
% dataset description json
1919
% required
2020
fieldsToSet.bids.datasetDescription.json.Name = '';
@@ -27,7 +27,7 @@
2727
fieldsToSet.bids.datasetDescription.json.Funding = {''};
2828
fieldsToSet.bids.datasetDescription.json.ReferencesAndLinks = {''};
2929
fieldsToSet.bids.datasetDescription.json.DatasetDOI = '';
30-
30+
3131
% mri
3232
% for json
3333
fieldsToSet.MRI.repetitionTime = [];
@@ -37,38 +37,39 @@
3737
fieldsToSet.MRI.rec = []; % reconstruction of fMRI images
3838
fieldsToSet.MRI.echo = []; % echo fMRI images
3939
fieldsToSet.MRI.acq = []; % acquisition of fMRI images
40-
41-
%% loop through the defaults and set them in expParameters if they don't exist
42-
names = fieldnames(fieldsToSet);
43-
44-
for i = 1:numel(names)
45-
expParameters = setFieldToIfNotPresent(...
46-
expParameters, ...
47-
names{i}, ...
48-
getfield(fieldsToSet, names{i})); %#ok<GFLD>
49-
end
50-
40+
41+
expParameters = setDefaults(expParameters, fieldsToSet);
42+
5143
%% set the cfg defaults
52-
53-
clear fieldsToSet
44+
45+
clear fieldsToSet;
5446
fieldsToSet.testingDevice = 'pc';
5547
fieldsToSet.eyeTracker = false;
56-
57-
% loop through the defaults and set them in cfg if they don't exist
48+
49+
cfg = setDefaults(cfg, fieldsToSet);
50+
51+
end
52+
53+
function structure = setDefaults(structure, fieldsToSet)
54+
% loop through the defaults fiels to set and update if they don't exist
55+
5856
names = fieldnames(fieldsToSet);
59-
57+
6058
for i = 1:numel(names)
61-
cfg = setFieldToIfNotPresent(...
62-
cfg, ...
59+
60+
thisField = fieldsToSet.(names{i});
61+
62+
structure = setFieldToIfNotPresent( ...
63+
structure, ...
6364
names{i}, ...
64-
getfield(fieldsToSet, names{i})); %#ok<GFLD>
65+
thisField);
66+
6567
end
6668

6769
end
6870

69-
70-
function struct = setFieldToIfNotPresent(struct, fieldName, value)
71-
if ~isfield(struct, fieldName)
72-
struct = setfield(struct, fieldName, value); %#ok<SFLD>
71+
function structure = setFieldToIfNotPresent(structure, fieldName, value)
72+
if ~isfield(structure, fieldName)
73+
structure.(fieldName) = value;
7374
end
74-
end
75+
end

createFilename.m

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@
2121

2222
[cfg, expParameters] = checkCFG(cfg, expParameters);
2323

24+
if ~isfield(expParameters, 'task')
25+
error('createFilename: missing a task name. i.e expParameters.task');
26+
end
27+
28+
expParameters = getModality(cfg, expParameters);
29+
30+
expParameters = createDirectories(cfg, expParameters);
31+
32+
expParameters = setSuffixes(expParameters);
33+
34+
expParameters = setFilenames(cfg, expParameters);
35+
36+
talkToMe(cfg, expParameters);
37+
38+
end
39+
40+
function expParameters = getModality(cfg, expParameters)
2441
switch lower(cfg.testingDevice)
2542
case 'pc'
2643
modality = 'beh';
@@ -35,16 +52,8 @@
3552
otherwise
3653
modality = 'beh';
3754
end
38-
expParameters.modality = modality;
39-
40-
expParameters = createDirectories(cfg, expParameters);
41-
42-
expParameters = setSuffixes(expParameters);
43-
44-
expParameters = setFilenames(cfg, expParameters);
45-
46-
talkToMe(cfg, expParameters);
4755

56+
expParameters.modality = modality;
4857
end
4958

5059
function [subjectGrp, subjectNb, sessionNb, modality] = extractInput(expParameters)
@@ -54,6 +63,10 @@
5463
sessionNb = expParameters.sessionNb;
5564
modality = expParameters.modality;
5665

66+
if isempty(sessionNb)
67+
sessionNb = 1;
68+
end
69+
5770
end
5871

5972
function expParameters = createDirectories(cfg, expParameters)

miss_hit.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
line_length: 100
2-
regex_function_name: "[a-z]+(([A-Z]|[0-9]){1}[a-z]+)*"
2+
regex_function_name: "[a-z]+(([A-Z]){1}[A-Za-z]+)*"
33
suppress_rule: "copyright_notice"

0 commit comments

Comments
 (0)