Skip to content

Commit 2beab04

Browse files
committed
Merge remote-tracking branch 'cpp-lln-lab/master'
2 parents eaaa605 + 169c53a commit 2beab04

File tree

10 files changed

+793
-100
lines changed

10 files changed

+793
-100
lines changed

.all-contributorsrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@
2626
"design",
2727
"doc"
2828
]
29+
},
30+
{
31+
"login": "CerenB",
32+
"name": "CerenB",
33+
"avatar_url": "https://avatars1.githubusercontent.com/u/10451654?v=4",
34+
"profile": "https://github.com/CerenB",
35+
"contributions": [
36+
"code",
37+
"design",
38+
"doc",
39+
"review"
40+
]
2941
}
3042
],
3143
"contributorsPerLine": 7,

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
# CPP_PTB
22

33
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4-
5-
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)
6-
4+
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
75
<!-- ALL-CONTRIBUTORS-BADGE:END -->
86

9-
This is List of Crossmodal Perpeption and Plasticity lab (CPP) PsychToolBox (PTB) toolbox.
7+
This is List of Crossmodal Perception and Plasticity lab (CPP) PsychToolBox (PTB) toolbox.
108

119
Those functions are mostly wrappers around some PTB functions to facilitate their use and to have a codebase to facilitate their reuse.
1210

@@ -19,7 +17,7 @@ For instructions see the following links:
1917

2018
| Requirements | Used version |
2119
|----------------------------------------------------------|--------------|
22-
| [PsychToolBox](http://psychtoolbox.org/) Duuuuhh | >=3.0.14 |
20+
| [PsychToolBox](http://psychtoolbox.org/) Duuuuhh | >=3.0.14 |
2321
| [Matlab](https://www.mathworks.com/products/matlab.html) | 201?? |
2422
| or [octave](https://www.gnu.org/software/octave/) | 4.? |
2523

@@ -136,31 +134,49 @@ and returns a structure with an additional field with Pix suffix holding that ne
136134

137135
Define the parameters of the fixation cross in `cfg` and `expParameters` and this does the rest.
138136

137+
### eyeTracker
138+
139+
This will handle the Eye Tracker (EyeLink set up) and can be called to initialize the connection and start the calibration, start/stop eye(s) movement recordings and save the `*.edf` file (named with BIDS specification from cpp-lln-lab/CPP_BIDS).
140+
139141
### pressSpace4me
140142

141143
Use that to stop your script and only restart when the space bar is pressed.
142144

145+
## Annexes
146+
147+
### Experiment template [ WIP ]
148+
149+
### `devSandobox.m` stand-alone
150+
151+
This script is a stand-alone function that can be useful as a sandbox to develop the PTB audio/visual stimulation of your experiment. No input/output required.
152+
153+
Here, a tutorial from https://peterscarfe.com/contrastgratingdemo.html is provided for illustrative purpose (notice that some variable names are updated to our code style). For your use, you will delete that part.
154+
155+
It is composed of two parts:
156+
- a fixed structure that will initialize and close PTB in 'debug mode'
157+
(`PsychDebugWindowConfiguration`, `SkipSyncTests`)
158+
- the actual sandbox where to set your dynamic variables (the stimulation
159+
parameters) and the 'playground' where to develop the stimulation code
160+
161+
When you are happy with it, ideally you will move the vars in `setParameters.m` and the stimulation code in a separate function in `my-experiment-folder/subfun`. The code style and variable names are the same used in `cpp-lln-lab/CPP_PTB` github repo, therefore it should be easy to move everything in your experiment scripts (see the template that is annexed in `cpp-lln-lab/CPP_PTB`).
162+
143163
## Contributors ✨
144164

145165
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
146166

147167
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
148-
149168
<!-- prettier-ignore-start -->
150-
151169
<!-- markdownlint-disable -->
152-
153170
<table>
154171
<tr>
155172
<td align="center"><a href="https://remi-gau.github.io/"><img src="https://avatars3.githubusercontent.com/u/6961185?v=4" width="100px;" alt=""/><br /><sub><b>Remi Gau</b></sub></a><br /><a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=Remi-Gau" title="Code">💻</a> <a href="#design-Remi-Gau" title="Design">🎨</a> <a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=Remi-Gau" title="Documentation">📖</a></td>
156173
<td align="center"><a href="https://github.com/marcobarilari"><img src="https://avatars3.githubusercontent.com/u/38101692?v=4" width="100px;" alt=""/><br /><sub><b>marcobarilari</b></sub></a><br /><a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=marcobarilari" title="Code">💻</a> <a href="#design-marcobarilari" title="Design">🎨</a> <a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=marcobarilari" title="Documentation">📖</a></td>
174+
<td align="center"><a href="https://github.com/CerenB"><img src="https://avatars1.githubusercontent.com/u/10451654?v=4" width="100px;" alt=""/><br /><sub><b>CerenB</b></sub></a><br /><a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=CerenB" title="Code">💻</a> <a href="#design-CerenB" title="Design">🎨</a> <a href="https://github.com/cpp-lln-lab/CPP_PTB/commits?author=CerenB" title="Documentation">📖</a> <a href="https://github.com/cpp-lln-lab/CPP_PTB/pulls?q=is%3Apr+reviewed-by%3ACerenB" title="Reviewed Pull Requests">👀</a></td>
157175
</tr>
158176
</table>
159177

160178
<!-- markdownlint-enable -->
161-
162179
<!-- prettier-ignore-end -->
163-
164180
<!-- ALL-CONTRIBUTORS-LIST:END -->
165181

166182
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

demos/CPP_wait4TriggerDemo.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cd ..
2+
3+
cfg.device = 'Scanner';
4+
5+
cfg.numTriggers = 4;
6+
7+
cfg.triggerKey = 'space';
8+
9+
KbName('UnifyKeyNames');
10+
11+
wait4Trigger(cfg)

devSandbox.m

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
function devSandbox
2+
3+
% This script is a stand-alone function that can be useful as a sandbox to
4+
% develop the PTB audio/visual stimulation of your experiment. No input/output
5+
% required.
6+
%
7+
% Here, a tutorial from https://peterscarfe.com/contrastgratingdemo.html is
8+
% provided for illustrative purpose (notice that some variable names are updated
9+
% to our code style). For your use, you will delete that part.
10+
%
11+
% It is composed of two parts:
12+
% - a fixed structure that will initialize and close PTB in 'debug mode'
13+
% (`PsychDebugWindowConfiguration`, `SkipSyncTests`)
14+
% - the actual sandbox where to set your dynamic variables (the stimulation
15+
% parameters) and the 'playground' where to develop the stimulation code
16+
%
17+
% When you are happy with it, ideally you will move the vars in `setParameters.m`
18+
% and the stimulation code in a separate function in `my-experiment-folder/subfun`.
19+
% The code style and variable names are the same used in `cpp-lln-lab/CPP_PTB`
20+
% github repo, therefore it should be easy to move everything in your experiment
21+
% scripts (see the template that is annexed in `cpp-lln-lab/CPP_PTB`)
22+
23+
% Init the structure that will contain PTB setup
24+
cfg = struct;
25+
26+
% Set some colors to be choosen as background
27+
cfg.white = [255 255 255];
28+
cfg.black = [ 0 0 0 ];
29+
cfg.grey = mean([cfg.black; cfg.white]);
30+
31+
% Set the PTB window background manually
32+
cfg.backgroundColor = cfg.grey;
33+
34+
% Init PTB, see the Sub-Functions below
35+
cfg = devSandbox_initPTB(cfg);
36+
37+
%%
38+
% -------------------------------------------------------------------------
39+
% -------------------------- SET YOUR VARS HERE ---------------------------
40+
% -------------------------------------------------------------------------
41+
42+
% Define black and white
43+
white = WhiteIndex(cfg.screen);
44+
grey = white / 2;
45+
inc = white - grey;
46+
47+
% Grating size in pixels
48+
gratingSizePix = 600;
49+
50+
% Grating frequency in cycles / pixel
51+
freqCyclesPerPix = 0.01;
52+
53+
% Drift speed cycles per second
54+
cyclesPerSecond = 1;
55+
56+
% Contrast for our contrast modulation mask: 0 = mask has no effect, 1 = mask
57+
% will at its strongest part be completely opaque frameCounter.e. 0 and 100% contrast
58+
% respectively
59+
contrast = 0.8;
60+
61+
% We set PTB to wait one frame before re-drawing
62+
waitframes = 1;
63+
64+
% -------------------------------------------------------------------------
65+
%%
66+
67+
% Catch the error and restore your computer for debugging
68+
try
69+
70+
%%
71+
% -------------------------------------------------------------------------
72+
% ------------------------------ PLAYGROUND -------------------------------
73+
% -------------------------------------------------------------------------
74+
% Define Half-Size of the grating image.
75+
textureSize = gratingSizePix / 2;
76+
77+
% First we compute pixels per cycle rounded to the nearest pixel
78+
pixPerCycle = ceil(1 / freqCyclesPerPix);
79+
80+
% Frequency in Radians
81+
freqRad = freqCyclesPerPix * 2 * pi;
82+
83+
% This is the visible size of the grating
84+
visibleSize = 2 * textureSize + 1;
85+
86+
87+
% Define our grating. Note it is only 1 pixel high. PTB will make it a full
88+
% grating upon drawing
89+
x = meshgrid(-textureSize:textureSize + pixPerCycle, 1);
90+
grating = grey * cos(freqRad*x) + inc;
91+
92+
93+
% Make a two layer mask filled with the background colour
94+
mask = ones(1, numel(x), 2) * grey;
95+
96+
% Place the grating in the 'alpha' channel of the mask
97+
mask(:, :, 2)= grating .* contrast;
98+
99+
% Make our grating mask texture
100+
gratingMaskTex = Screen('MakeTexture', cfg.win, mask);
101+
102+
103+
% Make a black and white noise mask half the size of our grating. This will
104+
% be scaled upon drawing to make a "chunky" noise texture which our grating
105+
% will mask. Note the round function in here. For this demo we are simply
106+
% rounding the size to the nearest pixel, leaving PTB to do some scaling.
107+
noise = rand(round(visibleSize / 2)) .* white;
108+
109+
% Make our noise texture
110+
noiseTexture = Screen('MakeTexture', cfg.win, noise);
111+
112+
113+
% Make a destination rectangle for our textures and center this on the
114+
% screen
115+
dstRect = [0 0 visibleSize visibleSize];
116+
dstRect = CenterRect(dstRect, cfg.winRect);
117+
118+
% Calculate the wait duration
119+
waitDuration = waitframes * cfg.ifi;
120+
121+
% Recompute pixPerCycle, this time without the ceil() operation from above.
122+
% Otherwise we will get wrong drift speed due to rounding errors
123+
pixPerCycle = 1 / freqCyclesPerPix;
124+
125+
% Translate requested speed of the grating (in cycles per second) into
126+
% a shift value in "pixels per frame"
127+
shiftPerFrame = cyclesPerSecond * pixPerCycle * waitDuration;
128+
129+
% Sync us to the vertical retrace
130+
vbl = Screen('Flip', cfg.win);
131+
132+
% Set the frame counter to zero, we need this to 'drift' our grating
133+
frameCounter = 0;
134+
135+
% Loop until a key is pressed
136+
while ~KbCheck
137+
138+
% Calculate the xoffset for our window through which to sample our
139+
% grating
140+
xoffset = mod(frameCounter * shiftPerFrame, pixPerCycle);
141+
142+
% Now increment the frame counter for the next loop
143+
frameCounter = frameCounter + 1;
144+
145+
% Define our source rectangle for grating sampling
146+
srcRect = [xoffset 0 xoffset + visibleSize visibleSize];
147+
148+
% Draw noise texture to the screen
149+
Screen('DrawTexture', cfg.win, noiseTexture, [], dstRect, []);
150+
151+
% Draw grating mask
152+
Screen('DrawTexture', cfg.win, gratingMaskTex, srcRect, dstRect, []);
153+
154+
% Flip to the screen on the next vertical retrace
155+
vbl = Screen('Flip', cfg.win, vbl + (waitframes - 0.5) * cfg.ifi);
156+
157+
end
158+
159+
160+
161+
% -------------------------------------------------------------------------
162+
%%
163+
164+
% Close PTB, see the Sub-Functions below
165+
devSandbox_cleanUp
166+
167+
catch
168+
169+
devSandbox_cleanUp
170+
psychrethrow(psychlasterror);
171+
172+
end
173+
174+
175+
end
176+
177+
%% Sub-Functions
178+
function cfg = devSandbox_initPTB(cfg)
179+
180+
% Shorter version of `initPTB.m`
181+
182+
% Skip the PTB sync test
183+
Screen('Preference', 'SkipSyncTests', 2);
184+
185+
% Open a transparent window
186+
PsychDebugWindowConfiguration
187+
188+
% Here we call some default settings for setting up Psychtoolbox
189+
PsychDefaultSetup(2);
190+
191+
% Get the screen numbers and draw to the external screen if avaliable
192+
cfg.screen = max(Screen('Screens'));
193+
194+
% Open an on screen window
195+
[cfg.win, cfg.winRect] = Screen('OpenWindow', cfg.screen, cfg.backgroundColor);
196+
197+
% Get the size of the on screen window
198+
[cfg.winWidth, cfg.winHeight] = WindowSize(cfg.win);
199+
200+
% Query the frame duration
201+
cfg.ifi = Screen('GetFlipInterval', cfg.win);
202+
203+
% Get the Center of the Screen
204+
cfg.center = [cfg.winRect(3), cfg.winRect(4)]/2;
205+
206+
% Set up alpha-blending for smooth (anti-aliased) lines
207+
Screen('BlendFunction', cfg.win, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
208+
209+
end
210+
211+
function devSandbox_cleanUp
212+
213+
% A wrapper function to close all windows, ports, show mouse cursor, close keyboard queues
214+
% and give access back to the keyboards.
215+
216+
WaitSecs(0.5);
217+
218+
Priority(0);
219+
220+
ListenChar(0);
221+
KbQueueRelease();
222+
223+
ShowCursor
224+
225+
% Screen Close All
226+
sca;
227+
228+
% Close Psychportaudio if open
229+
if PsychPortAudio('GetOpenDeviceCount') ~= 0
230+
PsychPortAudio('Close');
231+
end
232+
233+
if ~ismac
234+
% remove PsychDebugWindowConfiguration
235+
clear Screen
236+
end
237+
238+
close all
239+
240+
241+
end

0 commit comments

Comments
 (0)