Skip to content

Commit 17901c0

Browse files
authored
Merge pull request #105 from Remi-Gau/misc
[INFRA, DOC, REF] Misc
2 parents e337d51 + 7fcb87f commit 17901c0

20 files changed

+941
-676
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*/logfiles/*
66
*/*/*/logfiles/*
77
*.tsv
8-
*.mat
98

109
output
10+
source
1111

1212
## virtual env
1313
env/

README.md

Lines changed: 30 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,19 @@
66
- [fMRI localizers for visual motion](#fmri-localizers-for-visual-motion)
77
- [Requirements](#requirements)
88
- [Installation](#installation)
9-
- [Structure and function details](#structure-and-function-details)
10-
- [visualMotionLocalizer](#visualmotionlocalizer)
11-
- [setParameters](#setparameters)
12-
- [Let the scanner pace the experiment](#let-the-scanner-pace-the-experiment)
13-
- [subfun/doDotMo](#subfundodotmo)
14-
- [Input](#input)
15-
- [Output](#output)
16-
- [subfun/design/expDesign](#subfundesignexpdesign)
17-
- [Events](#events)
18-
- [Pseudorandomization rules:](#pseudorandomization-rules)
19-
- [Input:](#input-1)
20-
- [Output:](#output-1)
9+
- [Set up and running](#set-up-and-running)
2110
- [Contributors ✨](#contributors-)
2211

2312
# fMRI localizers for visual motion
2413

14+
Running this script will show blocks of motion dots and static dots. Motion
15+
blocks will show:
16+
17+
- dots moving in one of four directions (up-, down-, left-, and right-ward) (MT+
18+
localizer)
19+
- or dots moving inward and outward in the peripheral of the screen (MT/MST
20+
localizer).
21+
2522
## Requirements
2623

2724
Make sure that the following toolboxes are installed and added to the matlab /
@@ -39,160 +36,45 @@ For instructions see the following links:
3936

4037
## Installation
4138

42-
The CPP_BIDS and CPP_PTB dependencies are already set up as submodule to this
39+
The CPP_BIDS and CPP_PTB dependencies are already set up as submodules to this
4340
repository. You can install it all with git by doing.
4441

4542
```bash
4643
git clone --recurse-submodules https://github.com/cpp-lln-lab/localizer_visual_motion.git
4744
```
4845

49-
## Structure and function details
50-
51-
### visualMotionLocalizer
52-
53-
Running this script will show blocks of motion dots and static dots. Motion
54-
blocks will show dots moving in one of four directions (up-, down-, left-, and
55-
right-ward) (MT+ localizer) or dots moving inward and outward in the peripheral
56-
of the screen (MT/MST localizer).
57-
58-
Run in `Debug mode` (see `setParameters.m`) it does not care about subjID, run
59-
n., Eye Tracker (soon, at the moment it needs to be set off manually), etc..
60-
61-
Any details of the experiment can be changed in `setParameters.m` (e.g.,
62-
experiment mode, motion stimuli details, exp. design, etc.)
46+
## Set up and running
6347

64-
### setParameters
48+
In the `main.m` script, you are meant
6549

66-
`setParameters.m` is the core engine of the experiment. It contains the
67-
following tweakable sections:
50+
- to set your configuration (`cfg`)
51+
- call `initEnv()` to add the relevant folders to the MATLAB path
52+
- call `cfg = checkParameters(cfg)` to set up any default configuration you did
53+
not set.
54+
- call `visualMotionLocalizer(cfg)` to run the localizer.
6855

69-
- Debug mode setting
70-
- MRI settings
71-
- Engine parameters:
72-
- Monitor parameters
73-
- Monitor parameters for PsychToolBox
74-
- Keyboards
75-
- Experiment Design
76-
- Visual Stimulation
77-
- Task(s)
78-
- Instructions
79-
- Task #1 parameters
80-
81-
#### Let the scanner pace the experiment
82-
83-
Set `cfg.pacedByTriggers.do` to `true` and you can then set all the details in
84-
this `if` block
56+
The minimalist script would thus look like:
8557

8658
```matlab
87-
% Time is here in terms of `repetition time (TR)` (i.e. MRI volumes)
88-
if cfg.pacedByTriggers.do
59+
clc;
60+
clear;
8961
90-
cfg.pacedByTriggers.quietMode = true;
91-
cfg.pacedByTriggers.nbTriggers = 1;
62+
%% Run MT+ localizer
9263
93-
cfg.timing.eventDuration = cfg.mri.repetitionTime / 2 - 0.04; % second
64+
cfg.design.localizer = 'MT';
65+
initEnv();
9466
95-
% Time between blocs in secs
96-
cfg.timing.IBI = 0;
97-
% Time between events in secs
98-
cfg.timing.ISI = 0;
99-
% Number of seconds before the motion stimuli are presented
100-
cfg.timing.onsetDelay = 0;
101-
% Number of seconds after the end all the stimuli before ending the run
102-
cfg.timing.endDelay = 2;
67+
cfg = checkParameters(cfg);
10368
104-
end
69+
% Run
70+
visualMotionLocalizer(cfg);
10571
```
10672

107-
### subfun/doDotMo
108-
109-
Wrapper function that present the dot stimulation (static or motion) per event.
110-
111-
#### Input
112-
113-
- `cfg`: PTB/machine and experiment configurations returned by `setParameters`
114-
and `initPTB`
115-
- `logFile`: structure that stores the experiment logfile to be saved
116-
- `thisEvent`: structure that stores information about the event to present
117-
regarding the dots (static or motion, direction, etc.)
118-
- `thisFixation`: structure that stores information about the fixation cross
119-
task to present
120-
- `dots`: [...]
121-
- `iEvent`: index of the event of the block at the moment of the presentation
122-
123-
#### Output
124-
125-
- Event `onset`
126-
- Event `duration`
127-
- `dots`: [...]
128-
129-
> NB: The dots are drawn on a square that contains the round aperture, then any
130-
> dots outside of the aperture is turned into a NaN so effectively the actual
131-
> number of dots on the screen at any given time is not the one that you input
132-
> but a smaller number (nDots / Area of aperture) on average.
133-
134-
### subfun/design/expDesign
135-
136-
This function and its companions creates the sequence of blocks (static/motion)
137-
and the events (the single directions) for MT+ and MT/MST localizers. The
138-
conditions are consecutive static and motion blocks (fixed in this order gives
139-
better results than randomised).
140-
141-
It can be run as a stand alone without inputs and displays a visual example of
142-
the possible design. See `getMockConfig` to set up the mock configuration.
143-
144-
It computes the directions to display and the task(s), at the moment:
145-
146-
1. detection of change in the color of the fixation target
147-
2. detection of different speed of the moving dots [ W I P - if selected as a
148-
task it will give the same null output as if not selected ie no difference in
149-
speed]
150-
151-
#### Events
152-
153-
The `nbEventsPerBlock` should be a multiple of the number of motion directions
154-
requested in `motionDirections` (which should be more than 1) e.g.:
155-
156-
- MT localizer:
157-
`cfg.design.motionDirections = [ 0 90 180 270 ]; % right down left up`
158-
- MT_MST localizer: `cfg.design.motionDirections = [666 -666]; % outward inward`
159-
160-
#### Pseudorandomization rules:
161-
162-
- Directions:
163-
164-
1. Directions are all presented in random orders in
165-
`numEventsPerBlock/nDirections` consecutive chunks. This evenly distribute
166-
the directions across the block.
167-
2. No same consecutive direction
168-
169-
- Color change detection of the fixation cross:
170-
171-
1. If there are 2 targets per block we make sure that they are at least 2 events
172-
apart.
173-
2. Targets cannot be on the first or last event of a block.
174-
3. No less than 1 target per event position in the whole run
175-
176-
#### Input:
177-
178-
- `cfg`: parameters returned by setParameters
179-
- `displayFigs`: a boolean to decide whether to show the basic design matrix of
180-
the design
181-
182-
#### Output:
73+
Type `help checkParameters` and see the [README in docs](./docs/README.md) to
74+
get more information about the configuration options.
18375

184-
- `cfg.design.blockNames`: cell array (nbBlocks, 1) with the condition name for
185-
each block
186-
- `cfg.design.nbBlocks`: integer for th etotal number of blocks in the run
187-
- `cfg.design.directions`: array (nbBlocks, nbEventsPerBlock) with the direction
188-
to present in a given event of a block.
189-
- 0 90 180 270 indicate the angle for translational motion direction
190-
- 666 -666 indicate in/out-ward direction in radial motion
191-
- -1 indicates static
192-
- `cfg.design.speeds`: array (nbBlocks, nbEventsPerBlock) indicate the dots
193-
speed in each event, the target is represented by a higher/lower value
194-
- `cfg.design.fixationTargets`: array (nbBlocks, numEventsPerBlock) showing for
195-
each event if it should be accompanied by a target
76+
Run in debug mode (set `cfg.debug.do = true`) it does not care about subjID, run
77+
n., Eye Tracker...
19678

19779
## Contributors ✨
19880

cfgMST.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function cfg = cfgMST(cfg)
2+
%
3+
% (C) Copyright 2020 CPP visual motion localizer developers
4+
5+
cfg.design.localizer = 'MT_MST';
6+
7+
cfg.design.nbRepetitions = 10;
8+
9+
cfg.design.nbEventsPerBlock = 10;
10+
11+
cfg.timing.eventDuration = 0.3; % 0.6 seconds
12+
13+
end

cfgMT.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function cfg = cfgMT(cfg)
2+
%
3+
% (C) Copyright 2020 CPP visual motion localizer developers
4+
5+
cfg.design.localizer = 'MT';
6+
7+
cfg.pacedByTriggers.do = true;
8+
9+
cfg.mri.triggerNb = 0;
10+
11+
cfg.design.nbRepetitions = 15;
12+
13+
cfg.timing.eventDuration = 0.43; % .86 second
14+
15+
end

docs/configurations.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Configurations
2+
3+
- [Configurations](#configurations)
4+
- [For MT localiser](#for-mt-localiser)
5+
- [Let the scanner pace the experiment](#let-the-scanner-pace-the-experiment)
6+
7+
## For MT localiser
8+
9+
These are all the options that can be tweaked.
10+
11+
```matlab
12+
cfg.aperture.type = 'none';
13+
cfg.aperture.width = [];
14+
cfg.aperture.xPos = 0.000000;
15+
cfg.audio.do = 0;
16+
cfg.bids.MRI.Instructions = '1-Detect the RED fixation cross';
17+
cfg.bids.MRI.TaskDescription = '';
18+
cfg.bids.mri.RepetitionTime = [];
19+
cfg.color.background = 0.000000, 0.000000, 0.000000;
20+
cfg.color.black = 0.000000, 0.000000, 0.000000;
21+
cfg.color.blue = 0.000000, 255.000000, 0.000000;
22+
cfg.color.green = 0.000000, 0.000000, 255.000000;
23+
cfg.color.grey = 127.500000, 127.500000, 127.500000;
24+
cfg.color.red = 255.000000, 0.000000, 0.000000;
25+
cfg.color.white = 255.000000, 255.000000, 255.000000;
26+
cfg.debug.do = 1;
27+
cfg.debug.smallWin = 1;
28+
cfg.debug.transpWin = 1;
29+
cfg.design.localizer = 'MT';
30+
cfg.design.motionDirections = 0.000000, 0.000000, 180.000000, 180.000000;
31+
cfg.design.motionType = 'translation';
32+
cfg.design.names{1} = 'static';
33+
cfg.design.names{2} = 'motion';
34+
cfg.design.nbEventsPerBlock = 12.000000;
35+
cfg.design.nbRepetitions = 12.000000;
36+
cfg.dot.coherence = 1.000000;
37+
cfg.dot.color = 255.000000, 255.000000, 255.000000;
38+
cfg.dot.density = 1.000000;
39+
cfg.dot.lifeTime = 0.400000;
40+
cfg.dot.proportionKilledPerFrame = 0.000000;
41+
cfg.dot.size = 0.200000;
42+
cfg.dot.speed = 15.000000;
43+
cfg.dot.staticReSeed = 1;
44+
cfg.extraColumns{1} = 'direction';
45+
cfg.extraColumns{2} = 'speedDegVA';
46+
cfg.extraColumns{3} = 'target';
47+
cfg.extraColumns{4} = 'event';
48+
cfg.extraColumns{5} = 'block';
49+
cfg.extraColumns{6} = 'keyName';
50+
cfg.extraColumns{7} = 'fixationPosition';
51+
cfg.extraColumns{8} = 'aperturePosition';
52+
cfg.eyeTracker.do = 0;
53+
cfg.fixation.color = 255.000000, 255.000000, 255.000000;
54+
cfg.fixation.colorTarget = 255.000000, 0.000000, 0.000000;
55+
cfg.fixation.lineWidthPix = 3.000000;
56+
cfg.fixation.type = 'cross';
57+
cfg.fixation.width = 0.250000;
58+
cfg.fixation.xDisplacement = 0.000000;
59+
cfg.fixation.yDisplacement = 0.000000;
60+
cfg.hideCursor = 0;
61+
cfg.keyboard.escapeKey = 'ESCAPE';
62+
cfg.keyboard.keyboard = [];
63+
cfg.keyboard.responseBox = [];
64+
cfg.keyboard.responseKey{1} = 'r';
65+
cfg.keyboard.responseKey{2} = 'g';
66+
cfg.keyboard.responseKey{3} = 'y';
67+
cfg.keyboard.responseKey{4} = 'b';
68+
cfg.keyboard.responseKey{5} = 'd';
69+
cfg.keyboard.responseKey{6} = 'n';
70+
cfg.keyboard.responseKey{7} = 'z';
71+
cfg.keyboard.responseKey{8} = 'e';
72+
cfg.keyboard.responseKey{9} = 't';
73+
cfg.mri.repetitionTime = 1.800000;
74+
cfg.mri.triggerKey = 't';
75+
cfg.mri.triggerNb = 5.000000;
76+
cfg.pacedByTriggers.do = 0;
77+
cfg.screen.monitorDistance = 95.000000;
78+
cfg.screen.monitorWidth = 25.000000;
79+
cfg.screen.resolution{1} = [];
80+
cfg.screen.resolution{2} = [];
81+
cfg.screen.resolution{3} = [];
82+
cfg.skipSyncTests = 1.000000;
83+
cfg.suffix.acquisition = '';
84+
cfg.target.duration = 0.100000;
85+
cfg.target.maxNbPerBlock = 1.000000;
86+
cfg.target.type = 'fixation_cross';
87+
cfg.task.instruction = '1-Detect the RED fixation cross';
88+
cfg.task.name = 'visual localizer';
89+
cfg.task.taskDescription = '';
90+
cfg.testingDevice = 'mri';
91+
cfg.text.color = 255.000000, 255.000000, 255.000000;
92+
cfg.text.font = 'Courier New';
93+
cfg.text.size = 18.000000;
94+
cfg.text.style = 1.000000;
95+
cfg.timing.IBI = 4.000000;
96+
cfg.timing.ISI = 0.100000;
97+
cfg.timing.endDelay = 5.000000;
98+
cfg.timing.eventDuration = 0.300000;
99+
cfg.timing.onsetDelay = 5.000000;
100+
cfg.verbose = 1.000000;
101+
```
102+
103+
##
104+
105+
Type help `expDesign` to get information on how to tweak your experiment design.
106+
107+
## Let the scanner pace the experiment
108+
109+
<!-- TODO check that this is still valid -->
110+
111+
Set `cfg.pacedByTriggers.do` to `true` and you can then set all the details in
112+
this `if` block
113+
114+
```matlab
115+
% Time is here in terms of `repetition time (TR)` (i.e. MRI volumes)
116+
if cfg.pacedByTriggers.do
117+
118+
cfg.pacedByTriggers.quietMode = true;
119+
cfg.pacedByTriggers.nbTriggers = 1;
120+
121+
cfg.timing.eventDuration = cfg.mri.repetitionTime / 2 - 0.04; % second
122+
123+
% Time between blocs in secs
124+
cfg.timing.IBI = 0;
125+
% Time between events in secs
126+
cfg.timing.ISI = 0;
127+
% Number of seconds before the motion stimuli are presented
128+
cfg.timing.onsetDelay = 0;
129+
% Number of seconds after the end all the stimuli before ending the run
130+
cfg.timing.endDelay = 2;
131+
132+
end
133+
```

0 commit comments

Comments
 (0)