Skip to content

Commit 548288b

Browse files
authored
Merge pull request #15 from Remi-Gau/remi-dev_save_output
[WIP] make behavioral and eyetracking output BIDS compliant
2 parents b469d1c + a79f829 commit 548288b

File tree

17 files changed

+981
-638
lines changed

17 files changed

+981
-638
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
# exclude content of logfiles folders
77
*/logfiles/*
88
*/*/*/logfiles/*
9+
*.tsv
10+
*.mat

Visual-loc_translational/setParameters.m

Lines changed: 87 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,164 @@
1-
function [ExpParameters, Cfg] = setParameters
1+
function [expParameters, cfg] = setParameters
22

3-
ExpParameters = struct; % Initialize the parameters variables
4-
Cfg = struct; % Initialize the general configuration variables
3+
% Initialize the parameters and general configuration variables
4+
expParameters = struct;
5+
cfg = struct;
56

6-
ExpParameters.task = 'VisualLoc';
7+
expParameters.task = 'VisualLoc';
78

9+
% by default the data will be stored in an output folder created where the
10+
% setParamters.m file is
11+
% change that if you want the data to be saved somewhere else
12+
expParameters.outputDir = fullfile(...
13+
fileparts(mfilename('fullpath')), '..', ...
14+
'output');
815

916
%% Debug mode settings
10-
Cfg.debug = true; % To test the script out of the scanner, skip PTB sync
11-
Cfg.testingSmallScreen = false; % To test on a part of the screen, change to 1
12-
Cfg.testingTranspScreen = true; % To test with trasparent full size screen
13-
Cfg.stimPosition = 'PC'; % 'Scanner': means that it removes the lower 1/3 of the screen (the coil hides the lower part of the screen)
17+
cfg.debug = true; % To test the script out of the scanner, skip PTB sync
18+
cfg.testingSmallScreen = false; % To test on a part of the screen, change to 1
19+
cfg.testingTranspScreen = true; % To test with trasparent full size screen
20+
cfg.stimPosition = 'pc'; % 'Scanner': means that it removes the lower 1/3 of the screen (the coil hides the lower part of the screen)
1421

1522

1623
%% MRI settings
17-
Cfg.device = 'PC'; % 'PC': does not care about trigger - otherwise use 'Scanner'
18-
Cfg.triggerKey = 't'; % Set the letter sent by the trigger to sync stimulation and volume acquisition
19-
Cfg.numTriggers = 4;
20-
Cfg.eyeTracker = false; % Set to 'true' if you are testing in MRI and want to record ET data
24+
cfg.device = 'scanner'; % 'PC': does not care about trigger - otherwise use 'Scanner'
25+
cfg.triggerKey = 't'; % Set the letter sent by the trigger to sync stimulation and volume acquisition
26+
cfg.numTriggers = 4;
27+
cfg.eyeTracker = false; % Set to 'true' if you are testing in MRI and want to record ET data
2128

2229

2330
%% Keyboards
2431

25-
% cfg.responseBox would be the device used by the participant to give his/her response:
32+
% cfg.responseBox would be the device used by the participant to give his/her response:
2633
% like the button box in the scanner or a separate keyboard for a behavioral experiment
2734
%
28-
% cfg.keyboard is the keyboard on which the experimenter will type or press the keys necessary
35+
% cfg.keyboard is the keyboard on which the experimenter will type or press the keys necessary
2936
% to start or abort the experiment.
3037
% The two can be different or the same.
3138

32-
% Using empty vectors should work for linux when to select the "main"
33-
% keyboard. You might have to try some other values for MacOS or Windows
34-
Cfg.keyboard = [];
35-
Cfg.responseBox = [];
39+
% Using empty vectors should work for linux and MacOS when to select the
40+
% "main" keyboard. You might have to try some other values for Windows
41+
cfg.keyboard = [];
42+
cfg.responseBox = [];
3643

3744

3845
%% Engine parameters
3946

4047
% Monitor parameters
41-
Cfg.monitorWidth = 42; % Monitor Width in cm
42-
Cfg.screenDistance = 134; % Distance from the screen in cm
43-
Cfg.diameterAperture = 8; % Diameter/length of side of aperture in Visual angles
48+
cfg.monitorWidth = 42; % Monitor Width in cm
49+
cfg.screenDistance = 134; % Distance from the screen in cm
50+
cfg.diameterAperture = 8; % Diameter/length of side of aperture in Visual angles
4451

4552
% Monitor parameters for PTB
46-
Cfg.screen = max(Screen('Screens')); % Main screen
47-
Cfg.white = [255 255 255];
48-
Cfg.black = [ 0 0 0 ];
49-
Cfg.red = [255 0 0 ];
50-
Cfg.grey = mean([Cfg.black; Cfg.white]);
51-
Cfg.backgroundColor = Cfg.black;
52-
Cfg.textColor = Cfg.white;
53-
Cfg.textFont = 'Courier New';
54-
Cfg.textSize = 18;
55-
Cfg.textStyle = 1;
53+
cfg.white = [255 255 255];
54+
cfg.black = [ 0 0 0 ];
55+
cfg.red = [255 0 0 ];
56+
cfg.grey = mean([cfg.black; cfg.white]);
57+
cfg.backgroundColor = cfg.black;
58+
cfg.textColor = cfg.white;
59+
cfg.textFont = 'Courier New';
60+
cfg.textSize = 18;
61+
cfg.textStyle = 1;
5662

5763
% Keyboard
58-
Cfg.escapeKey = 'Escape';
64+
cfg.escapeKey = 'Escape';
5965

6066

6167

62-
% The code below will help you decide which keyboard device to use for the partipant and the experimenter
68+
% The code below will help you decide which keyboard device to use for the partipant and the experimenter
6369

6470
% Computer keyboard to quit if it is necessary
6571
% Cfg.keyboard
66-
%
72+
%
6773
% For key presses for the subject
6874
% Cfg.responseBox
6975

70-
[Cfg.keyboardNumbers, Cfg.keyboardNames] = GetKeyboardIndices;
71-
Cfg.keyboardNumbers
72-
Cfg.keyboardNames
76+
[cfg.keyboardNumbers, cfg.keyboardNames] = GetKeyboardIndices;
77+
cfg.keyboardNumbers
78+
cfg.keyboardNames
7379

7480

75-
switch Cfg.device
81+
switch lower(cfg.device)
7682

7783

7884
% this part might need to be adapted because the "default" device
7985
% number might be different for different OS or set up
80-
81-
case 'PC'
86+
87+
case 'pc'
8288

83-
Cfg.keyboard = [];
84-
Cfg.responseBox = [];
89+
cfg.keyboard = [];
90+
cfg.responseBox = [];
8591

8692
if ismac
87-
Cfg.keyboard = [];
88-
Cfg.responseBox = [];
93+
cfg.keyboard = [];
94+
cfg.responseBox = [];
8995
end
90-
96+
9197
case 'scanner'
9298

9399
otherwise
94100

95101
% Cfg.keyboard = max(Cfg.keyboardNumbers);
96102
% Cfg.responseBox = min(Cfg.keyboardNumbers);
97103

98-
Cfg.keyboard = [];
99-
Cfg.responseBox = [];
104+
cfg.keyboard = [];
105+
cfg.responseBox = [];
100106

101107
end
102108

103109
%% Experiment Design
104-
ExpParameters.names = {'static','motion'};
105-
ExpParameters.possibleDirections = [-1 1]; % 1 motion , -1 static
106-
ExpParameters.numBlocks = size(ExpParameters.possibleDirections,2);
107-
ExpParameters.numRepetitions = 1; %AT THE MOMENT IT IS NOT SET IN THE MAIN SCRIPT
108-
ExpParameters.IBI = 0; %8;
109-
ExpParameters.ISI = 0.1; % Time between events in secs
110-
ExpParameters.onsetDelay = 5; % Number of seconds before the motion stimuli are presented
111-
ExpParameters.endDelay = 1; % Number of seconds after the end all the stimuli before ending the run
110+
expParameters.names = {'static','motion'};
111+
expParameters.possibleDirections = [-1 1]; % 1 motion , -1 static
112+
expParameters.numBlocks = size(expParameters.possibleDirections,2);
113+
expParameters.numRepetitions = 1; %AT THE MOMENT IT IS NOT SET IN THE MAIN SCRIPT
114+
expParameters.IBI = 0; %8;
115+
expParameters.ISI = 0.1; % Time between events in secs
116+
expParameters.onsetDelay = 5; % Number of seconds before the motion stimuli are presented
117+
expParameters.endDelay = 1; % Number of seconds after the end all the stimuli before ending the run
112118

113119

114120
%% Visual Stimulation
115-
ExpParameters.experimentType = 'Dots'; % Visual modality is in RDKs %NOT USED IN THE MAIN SCIPT
116-
ExpParameters.speedEvent = 8; % speed in visual angles
117-
ExpParameters.numEventsPerBlock = 12; % Number of events per block (should not be changed)
118-
ExpParameters.eventDuration = .9;
119-
ExpParameters.coh = 1; % Coherence Level (0-1)
120-
ExpParameters.maxDotsPerFrame = 300; % Maximum number dots per frame (Number must be divisible by 3)
121-
ExpParameters.dotLifeTime = 0.2; % Dot life time in seconds
122-
ExpParameters.dontClear = 0;
123-
ExpParameters.dotSize = 0.1; % Dot Size (dot width) in visual angles.
124-
ExpParameters.dotColor = Cfg.white;
121+
expParameters.experimentType = 'Dots'; % Visual modality is in RDKs %NOT USED IN THE MAIN SCIPT
122+
expParameters.speedEvent = 8; % speed in visual angles
123+
expParameters.numEventsPerBlock = 12; % Number of events per block (should not be changed)
124+
expParameters.eventDuration = 1;
125+
expParameters.coh = 1; % Coherence Level (0-1)
126+
expParameters.maxDotsPerFrame = 300; % Maximum number dots per frame (Number must be divisible by 3)
127+
expParameters.dotLifeTime = 1; % Dot life time in seconds
128+
expParameters.dontClear = 0;
129+
expParameters.dotSize = 0.1; % Dot Size (dot width) in visual angles.
130+
expParameters.dotColor = cfg.white;
125131

126132

127133
%% Task(s)
128134

129135
% Instruction
130-
ExpParameters.TaskInstruction = '1-Detect the RED fixation cross\n \n\n';
136+
expParameters.TaskInstruction = '1-Detect the RED fixation cross\n \n\n';
131137

132-
ExpParameters.responseKey = {'space'};
138+
expParameters.responseKey = {'space'};
133139

134140

135141
%% Task 1 - Fixation cross
136-
ExpParameters.Task1 = true; % true / false
142+
expParameters.Task1 = true; % true / false
137143

138-
if ExpParameters.Task1
144+
if expParameters.Task1
139145
% Used Pixels here since it really small and can be adjusted during the experiment
140-
ExpParameters.fixCrossDimPix = 10; % Set the length of the lines (in Pixels) of the fixation cross
141-
ExpParameters.lineWidthPix = 4; % Set the line width (in Pixels) for our fixation cross
142-
ExpParameters.maxNumFixationTargetPerBlock = 2;
143-
ExpParameters.fixationChangeDuration = 0.15; % In secs
144-
ExpParameters.xDisplacementFixCross = 0; % Manual displacement of the fixation cross
145-
ExpParameters.yDisplacementFixCross = 0; % Manual displacement of the fixation cross
146-
ExpParameters.fixationCrossColor = Cfg.white;
147-
ExpParameters.fixationCrossColorTarget = Cfg.red;
146+
expParameters.fixCrossDimPix = 10; % Set the length of the lines (in Pixels) of the fixation cross
147+
expParameters.lineWidthPix = 4; % Set the line width (in Pixels) for our fixation cross
148+
expParameters.maxNumFixationTargetPerBlock = 2;
149+
expParameters.targetDuration = 0.15; % In secs
150+
expParameters.xDisplacementFixCross = 0; % Manual displacement of the fixation cross
151+
expParameters.yDisplacementFixCross = 0; % Manual displacement of the fixation cross
152+
expParameters.fixationCrossColor = cfg.white;
153+
expParameters.fixationCrossColorTarget = cfg.red;
148154
end
149155

150156

151-
%% Setting some defaults: no need to change things here
152-
if mod(ExpParameters.maxDotsPerFrame,3) ~= 0
153-
error('Number of dots should be divisible by 3.')
154-
end
157+
% Setting some defaults: no need to change things here
158+
expParameters = checkCFG(expParameters);
159+
155160

156-
if Cfg.debug
161+
if cfg.debug
157162
fprintf('\n\n\n\n')
158163
fprintf('######################################## \n')
159164
fprintf('## DEBUG MODE, NOT THE SCANNER CODE ## \n')
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function expParameters = checkCFG(expParameters)
2+
% check that we have all the fields that we need in the experiment
3+
% parameters
4+
5+
if ~isfield(expParameters, 'outputDir')
6+
expParameters.outputDir = fullfile(...
7+
fileparts(mfilename('fullpath')), ...
8+
'..', ...
9+
'output');
10+
end
11+
12+
% set empty values for a series of field if they have not been specified
13+
fields2Check = { ...
14+
'ce', ...
15+
'dir', ... % For BIDS file naming: phase encoding direction of acquisition for fMRI
16+
'rec', ... % For BIDS file naming: reconstruction of fMRI images
17+
'echo', ... % For BIDS file naming: echo fMRI images
18+
'acq' % For BIDS file naming: acquisition of fMRI images
19+
};
20+
21+
for iField = 1:numel(fields2Check)
22+
if ~isfield(expParameters, fields2Check{iField})
23+
expParameters = setfield(expParameters, fields2Check{iField}, []); %#ok<SFLD>
24+
end
25+
end
26+
27+
28+
end

0 commit comments

Comments
 (0)