|
5 | 5 | % adapted by M.Rezk to localize MT/MST (Huk,2002) |
6 | 6 | % re-adapted by MarcoB and RemiG 2020 |
7 | 7 |
|
8 | | -%% |
9 | | - |
10 | 8 | % Clear all the previous stuff |
11 | 9 | % clc; clear; |
12 | 10 | if ~ismac |
13 | | - close all; |
14 | | - clear Screen; |
| 11 | + close all; |
| 12 | + clear Screen; |
15 | 13 | end |
16 | 14 |
|
17 | | -% make sure we got access to all the required functions and inputs |
18 | | -addpath(genpath(fullfile(pwd, 'subfun'))) |
19 | | - |
20 | | -[expParameters, cfg] = setParameters; |
| 15 | +getOnlyPress = 1; |
21 | 16 |
|
22 | | -% set and load all the parameters to run the experiment |
23 | | -expParameters = userInputs(cfg, expParameters); |
| 17 | +more off; |
24 | 18 |
|
25 | | -expParameters = createFilename(cfg, expParameters); |
| 19 | +% make sure we got access to all the required functions and inputs |
| 20 | +initEnv(); |
26 | 21 |
|
27 | | -expParameters %#ok<NOPTS> |
| 22 | +cfg = setParameters; |
| 23 | +cfg = userInputs(cfg); |
| 24 | +cfg = createFilename(cfg); |
28 | 25 |
|
29 | 26 | %% Experiment |
30 | 27 |
|
31 | 28 | % Safety loop: close the screen if code crashes |
32 | 29 | try |
33 | | - |
| 30 | + |
| 31 | + % % % REFACTOR THIS FUNCTION |
| 32 | + [cfg] = loadAudioFiles(cfg); |
| 33 | + |
34 | 34 | %% Init the experiment |
35 | 35 | [cfg] = initPTB(cfg); |
36 | | - |
| 36 | + |
37 | 37 | % % Convert some values from degrees to pixels |
38 | 38 | % cfg = deg2Pix('diameterAperture', cfg, cfg); |
39 | 39 | % expParameters = deg2Pix('dotSize', expParameters, cfg); |
40 | | - |
41 | | - |
42 | | - [el] = eyeTracker('Calibration', cfg, expParameters); |
43 | | - |
| 40 | + |
| 41 | + [el] = eyeTracker('Calibration', cfg); |
| 42 | + |
44 | 43 | % % % REFACTOR THIS FUNCTION |
45 | | - [expParameters] = expDesign(expParameters); |
46 | | - % % % |
47 | | - |
| 44 | + [cfg] = expDesign(cfg); |
| 45 | + |
48 | 46 | % Prepare for the output logfiles with all |
49 | | - logFile = saveEventsFile('open', expParameters, [], ... |
| 47 | + logFile = saveEventsFile('open', cfg, [], ... |
50 | 48 | 'direction', 'speed', 'target', 'event', 'block'); |
51 | | - |
52 | | - logFile |
53 | | - |
54 | | - % % % REFACTOR THIS FUNCTION |
55 | | - [expParameters] = loadAudioFiles(cfg, expParameters); |
56 | | - phandle = PsychPortAudio('Open',[],[],1,expParameters.freq,2); |
57 | | - % % % |
58 | | - |
59 | | - % Prepare for fixation Cross |
60 | | - if expParameters.Task1 |
61 | | - |
62 | | - cfg.xCoords = [-expParameters.fixCrossDimPix expParameters.fixCrossDimPix 0 0] ... |
63 | | - + expParameters.xDisplacementFixCross; |
64 | | - |
65 | | - cfg.yCoords = [0 0 -expParameters.fixCrossDimPix expParameters.fixCrossDimPix] ... |
66 | | - + expParameters.yDisplacementFixCross; |
67 | | - |
68 | | - cfg.allCoords = [cfg.xCoords; cfg.yCoords]; |
69 | | - |
70 | | - end |
71 | | - |
72 | | - % Wait for space key to be pressed |
73 | | - pressSpace4me |
74 | | - |
| 49 | + |
| 50 | + % disp(cfg); |
| 51 | + |
| 52 | + standByScreen(cfg); |
| 53 | + |
75 | 54 | % prepare the KbQueue to collect responses |
76 | | - getResponse('init', cfg, expParameters, 1); |
77 | | - getResponse('start', cfg, expParameters, 1); |
78 | | - |
79 | | - % Show instructions |
80 | | - if expParameters.Task1 |
81 | | - DrawFormattedText(cfg.win,expParameters.TaskInstruction,... |
82 | | - 'center', 'center', cfg.textColor); |
83 | | - Screen('Flip', cfg.win); |
84 | | - end |
85 | | - |
| 55 | + getResponse('init', cfg.keyboard.responseBox, cfg); |
| 56 | + |
86 | 57 | % Wait for Trigger from Scanner |
87 | | - wait4Trigger(cfg) |
88 | | - |
89 | | - % Show the fixation cross |
90 | | - if expParameters.Task1 |
91 | | - drawFixationCross(cfg, expParameters, expParameters.fixationCrossColor) |
92 | | - Screen('Flip',cfg.win); |
93 | | - end |
94 | | - |
| 58 | + waitForTrigger(cfg); |
| 59 | + |
95 | 60 | %% Experiment Start |
96 | | - cfg.experimentStart = GetSecs; |
97 | | - |
98 | | - WaitSecs(expParameters.onsetDelay); |
99 | | - |
| 61 | + cfg = getExperimentStart(cfg); |
| 62 | + |
| 63 | + getResponse('start', cfg.keyboard.responseBox); |
| 64 | + |
| 65 | + WaitSecs(cfg.onsetDelay); |
| 66 | + |
100 | 67 | %% For Each Block |
101 | | - |
102 | | - stopEverything = 0; |
103 | | - |
104 | | - for iBlock = 1:expParameters.numBlocks |
105 | | - |
106 | | - if stopEverything |
107 | | - break; |
108 | | - end |
109 | | - |
110 | | - fprintf('\n - Running Block %.0f \n',iBlock) |
111 | | - |
112 | | - eyeTracker('StartRecording', cfg, expParameters); |
113 | | - |
| 68 | + |
| 69 | + for iBlock = 1:cfg.numBlocks |
| 70 | + |
| 71 | + fprintf('\n - Running Block %.0f \n', iBlock); |
| 72 | + |
| 73 | + eyeTracker('StartRecording', cfg); |
| 74 | + |
114 | 75 | % For each event in the block |
115 | | - for iEvent = 1:expParameters.numEventsPerBlock |
116 | | - |
117 | | - |
| 76 | + for iEvent = 1:cfg.numEventsPerBlock |
| 77 | + |
118 | 78 | % Check for experiment abortion from operator |
119 | | - [keyIsDown, ~, keyCode] = KbCheck(cfg.keyboard); |
120 | | - if keyIsDown && keyCode(KbName(cfg.escapeKey)) |
121 | | - stopEverything = 1; |
122 | | - warning('OK let us get out of here') |
123 | | - break; |
124 | | - end |
125 | | - |
126 | | - |
| 79 | + checkAbort(cfg, cfg.keyboard.keyboard); |
| 80 | + |
127 | 81 | % set direction, speed of that event and if it is a target |
128 | 82 | thisEvent.trial_type = 'dummy'; |
129 | | - thisEvent.direction = expParameters.designDirections(iBlock,iEvent); |
130 | | - thisEvent.speed = expParameters.designSpeeds(iBlock,iEvent); |
131 | | - thisEvent.target = expParameters.designFixationTargets(iBlock,iEvent); |
132 | | - |
| 83 | + thisEvent.direction = cfg.designDirections(iBlock, iEvent); |
| 84 | + thisEvent.speed = cfg.designSpeeds(iBlock, iEvent); |
| 85 | + thisEvent.target = cfg.designFixationTargets(iBlock, iEvent); |
| 86 | + |
133 | 87 | % play the sounds and collect onset and duration of the event |
134 | | - [onset, duration] = doAudMot(cfg, expParameters, thisEvent, phandle); |
135 | | - |
| 88 | + [onset, duration] = doAudMot(cfg, thisEvent, cfg.audio.pahandle); |
| 89 | + |
136 | 90 | thisEvent.event = iEvent; |
137 | 91 | thisEvent.block = iBlock; |
138 | 92 | thisEvent.duration = duration; |
139 | 93 | thisEvent.onset = onset - cfg.experimentStart; |
140 | | - |
| 94 | + |
141 | 95 | % Save the events txt logfile |
142 | 96 | % we save event by event so we clear this variable every loop |
143 | 97 | thisEvent.fileID = logFile.fileID; |
144 | | - |
145 | | - saveEventsFile('save', expParameters, thisEvent, ... |
| 98 | + |
| 99 | + saveEventsFile('save', cfg, thisEvent, ... |
146 | 100 | 'direction', 'speed', 'target', 'event', 'block'); |
147 | | - |
148 | | - clear thisEvent |
149 | | - |
150 | | - |
| 101 | + |
| 102 | + clear thisEvent; |
| 103 | + |
151 | 104 | % collect the responses and appends to the event structure for |
152 | 105 | % saving in the tsv file |
153 | | - responseEvents = getResponse('check', cfg, expParameters); |
154 | | - |
155 | | - if ~isempty(responseEvents(1).onset) |
156 | | - |
157 | | - responseEvents.fileID = logFile.fileID; |
158 | | - |
159 | | - for iResp = 1:size(responseEvents, 1) |
160 | | - responseEvents(iResp).onset = ... |
161 | | - responseEvents(iResp).onset - cfg.experimentStart; |
162 | | - responseEvents(iResp).target = expParameters.designFixationTargets(iBlock,iEvent); |
163 | | - responseEvents(iResp).event = iEvent; |
164 | | - responseEvents(iResp).block = iBlock; |
165 | | - end |
166 | | - |
167 | | - saveEventsFile('save', expParameters, responseEvents, ... |
168 | | - 'direction', 'speed', 'target', 'event', 'block'); |
169 | | - end |
170 | | - |
| 106 | + responseEvents = getResponse('check', cfg.keyboard.responseBox, cfg, ... |
| 107 | + getOnlyPress); |
| 108 | + |
| 109 | + triggerString = ['trigger']; |
| 110 | + saveResponsesAndTriggers(responseEvents, cfg, logFile, triggerString); |
| 111 | + |
171 | 112 | % wait for the inter-stimulus interval |
172 | | - WaitSecs(expParameters.ISI); |
173 | | - |
174 | | - getResponse('flush', cfg, expParameters); |
175 | | - |
| 113 | + WaitSecs(cfg.ISI); |
| 114 | + |
176 | 115 | end |
177 | | - |
178 | | - eyeTracker('StopRecordings', cfg, expParameters); |
179 | | - |
180 | | - WaitSecs(expParameters.IBI); |
181 | | - |
| 116 | + |
| 117 | + eyeTracker('StopRecordings', cfg); |
| 118 | + |
| 119 | + WaitSecs(cfg.IBI); |
| 120 | + |
182 | 121 | end |
183 | | - |
| 122 | + |
184 | 123 | % End of the run for the BOLD to go down |
185 | | - WaitSecs(expParameters.endDelay); |
186 | | - |
| 124 | + WaitSecs(cfg.endDelay); |
| 125 | + |
187 | 126 | % Close the logfiles |
188 | | - saveEventsFile('close', expParameters, logFile); |
189 | | - |
190 | | - getResponse('stop', cfg, expParameters, 1); |
191 | | - |
192 | | - totalExperimentTime = GetSecs-cfg.experimentStart; |
193 | | - |
194 | | - eyeTracker('Shutdown', cfg, expParameters); |
195 | | - |
| 127 | + saveEventsFile('close', cfg, logFile); |
| 128 | + |
| 129 | + getResponse('stop', cfg.keyboard.responseBox); |
| 130 | + getResponse('release', cfg.keyboard.responseBox); |
| 131 | + |
| 132 | + totalExperimentTime = GetSecs - cfg.experimentStart; |
| 133 | + |
| 134 | + eyeTracker('Shutdown', cfg); |
| 135 | + |
196 | 136 | % save the whole workspace |
197 | | - matFile = fullfile(expParameters.outputDir, strrep(expParameters.fileName.events,'tsv', 'mat')); |
| 137 | + matFile = fullfile(cfg.dir.output, strrep(cfg.fileName.events, 'tsv', 'mat')); |
198 | 138 | if IsOctave |
199 | 139 | save(matFile, '-mat7-binary'); |
200 | 140 | else |
201 | 141 | save(matFile, '-v7.3'); |
202 | 142 | end |
203 | | - |
204 | | - cleanUp() |
205 | | - |
| 143 | + |
| 144 | + cleanUp(); |
| 145 | + |
206 | 146 | catch |
207 | | - |
208 | | - cleanUp() |
| 147 | + |
| 148 | + cleanUp(); |
209 | 149 | psychrethrow(psychlasterror); |
210 | | - |
| 150 | + |
211 | 151 | end |
0 commit comments