Skip to content

Commit 2304925

Browse files
authored
Merge pull request #52 from Remi-Gau/remi-MT_MST
localizer with "peripheral" motion (cross on one side and stim on the other)
2 parents c854e6f + db8c02b commit 2304925

22 files changed

+420
-270
lines changed

README.md

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,30 @@
55

66
[![Build Status](https://travis-ci.com/cpp-lln-lab/localizer_visual_motion.svg?branch=master)](https://travis-ci.com/cpp-lln-lab/localizer_visual_motion)
77

8-
<!-- vscode-markdown-toc -->
9-
10-
- 1. [Requirements](#Requirements)
11-
- 2. [Installation](#Installation)
12-
- 3. [Structure and function details](#Structureandfunctiondetails)
13-
_ 3.1. [visualLocTranslational](#visualLocTranslational)
14-
_ 3.2. [setParameters](#setParameters)
15-
_ 3.3. [subfun/doDotMo](#subfundoDotMo)
16-
_ 3.3.1. [Input:](#Input:)
17-
_ 3.3.2. [Output:](#Output:)
18-
_ 3.4. [subfun/expDesign](#subfunexpDesign)
19-
_ 3.4.1. [EVENTS](#EVENTS)
20-
_ 3.4.2. [TARGETS:](#TARGETS:)
21-
_ 3.4.3. [Input:](#Input:-1)
22-
_ 3.4.4. [Output:](#Output:-1)
23-
24-
<!-- vscode-markdown-toc-config
25-
numbering=true
26-
autoSave=true
27-
/vscode-markdown-toc-config -->
28-
<!-- /vscode-markdown-toc -->
8+
<!-- TOC -->
9+
- [fMRI localizers for visual motion](#fmri-localizers-for-visual-motion)
10+
- [Translational Motion](#translational-motion)
11+
- [Requirements](#requirements)
12+
- [Installation](#installation)
13+
- [Structure and function details](#structure-and-function-details)
14+
- [visualLocTranslational](#visualloctranslational)
15+
- [setParameters](#setparameters)
16+
- [Let the scanner pace the experiment](#let-the-scanner-pace-the-experiment)
17+
- [subfun/doDotMo](#subfundodotmo)
18+
- [Input](#input)
19+
- [Output](#output)
20+
- [subfun/expDesign](#subfunexpdesign)
21+
- [EVENTS](#events)
22+
- [TARGETS](#targets)
23+
- [Input](#input-1)
24+
- [Output](#output-1)
25+
<!-- TOC -->
2926

3027
# fMRI localizers for visual motion
3128

32-
# Translational Motion
29+
## Translational Motion
3330

34-
## 1. <a name='Requirements'></a>Requirements
31+
## Requirements
3532

3633
Make sure that the following toolboxes are installed and added to the matlab / octave path.
3734

@@ -45,7 +42,7 @@ For instructions see the following links:
4542
| [Matlab](https://www.mathworks.com/products/matlab.html) | >=2017 |
4643
| or [octave](https://www.gnu.org/software/octave/) | >=4.? |
4744

48-
## 2. <a name='Installation'></a>Installation
45+
## Installation
4946

5047
The CPP_BIDS and CPP_PTB dependencies are already set up as submodule to this repository.
5148
You can install it all with git by doing.
@@ -54,17 +51,17 @@ You can install it all with git by doing.
5451
git clone --recurse-submodules https://github.com/cpp-lln-lab/localizer_visual_motion.git
5552
```
5653

57-
## 3. <a name='Structureandfunctiondetails'></a>Structure and function details
54+
## Structure and function details
5855

59-
### 3.1. <a name='visualLocTranslational'></a>visualLocTranslational
56+
### visualLocTranslational
6057

6158
Running this script will show blocks of motion dots (soon also moving gratings) and static dots. Motion blocks will show dots(/gratings) moving in one of four directions (up-, down-, left-, and right-ward)
6259

6360
By default it is run in `Debug mode` meaning that it does not run care about subjID, run n., fMRI triggers, Eye Tracker, etc..
6461

6562
Any details of the experiment can be changed in `setParameters.m` (e.g., experiment mode, motion stimuli details, exp. design, etc.)
6663

67-
### 3.2. <a name='setParameters'></a>setParameters
64+
### setParameters
6865

6966
`setParameters.m` is the core engine of the experiment. It contains the following tweakable sections:
7067

@@ -105,40 +102,40 @@ if cfg.pacedByTriggers.do
105102
end
106103
```
107104

108-
### 3.3. <a name='subfundoDotMo'></a>subfun/doDotMo
105+
### subfun/doDotMo
109106

110-
#### 3.3.1. <a name='Input:'></a>Input:
107+
#### Input
111108

112109
- `cfg`: PTB/machine configurations returned by `setParameters` and `initPTB`
113110
- `expParameters`: parameters returned by `setParameters`
114111
- `logFile`: structure that stores the experiment logfile to be saved
115112

116-
#### 3.3.2. <a name='Output:'></a>Output:
113+
#### Output
117114

118115
- Event `onset`
119116
- Event `duration`
120117

121118
The dots are drawn on a square that contains the round aperture, then any dots outside of the aperture is turned into a NaN so effectively the actual number of dots on the screen at any given time is not the one that you input but a smaller number (nDots / Area of aperture) on average.
122119

123-
### 3.4. <a name='subfunexpDesign'></a>subfun/expDesign
120+
### subfun/expDesign
124121

125122
Creates the sequence of blocks and the events in them. The conditions are consecutive static and motion blocks (Gives better results than randomised). It can be run as a stand alone without inputs to display a visual example of possible design.
126123

127-
#### 3.4.1. <a name='EVENTS'></a>EVENTS
124+
#### EVENTS
128125

129126
The `numEventsPerBlock` should be a multiple of the number of "base" listed in the `motionDirections` and `staticDirections` (4 at the moment).
130127

131-
#### 3.4.2. <a name='TARGETS:'></a>TARGETS:
128+
#### TARGETS
132129

133130
- If there are 2 targets per block we make sure that they are at least 2 events apart.
134131
- Targets cannot be on the first or last event of a block
135132

136-
#### 3.4.3. <a name='Input:-1'></a>Input:
133+
#### Input
137134

138135
- `expParameters`: parameters returned by `setParameters`
139136
- `displayFigs`: a boolean to decide whether to show the basic design matrix of the design
140137

141-
#### 3.4.4. <a name='Output:-1'></a>Output:
138+
#### Output
142139

143140
- `expParameters.designBlockNames` is a cell array `(nr_blocks, 1)` with the name for each block
144141
- `expParameters.designDirections` is an array `(nr_blocks, numEventsPerBlock)` with the direction to present in a given block

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Documentation

initEnv.m

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
%
2-
% 1 - Check if version requirements
3-
% are satisfied and the packages are
4-
% are installed/loaded:
5-
% Octave > 4
6-
% - image
7-
% - optim
8-
% - struct
9-
% - statistics
10-
%
11-
% MATLAB >= R2015b
12-
%
13-
% 2 - Add project to the O/M path
1+
% (C) Copyright 2020 Agah Karakuzu
2+
% (C) Copyright 2019 CPP BIDS SPM-pipeline developpers
143

154
function initEnv
5+
% 1 - Check if version requirements
6+
% are satisfied and the packages are
7+
% are installed/loaded:
8+
% Octave > 4
9+
% - image
10+
% - optim
11+
% - struct
12+
% - statistics
13+
%
14+
% MATLAB >= R2015b
15+
%
16+
% 2 - Add project to the O/M path
1617

1718
octaveVersion = '4.0.3';
1819
matlabVersion = '8.6.0';
@@ -56,8 +57,8 @@
5657

5758
if numel(dir(libDirectory)) <= 2 % Means that the external is empty
5859
error(['Git submodules are not cloned!', ...
59-
'Try this in your terminal:', ...
60-
' git submodule update --recursive ']);
60+
'Try this in your terminal:', ...
61+
' git submodule update --recursive ']);
6162
else
6263
addDependencies();
6364
end

lib/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# External libraries and dependencies

miss_hit.cfg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# style guide (https://florianschanda.github.io/miss_hit/style_checker.html)
22
line_length: 100
33
regex_function_name: "[a-z]+(([A-Z]){1}[A-Za-z]+)*"
4-
suppress_rule: "copyright_notice"
54
exclude_dir: "lib"
5+
copyright_entity: "Mohamed Rezk"
6+
copyright_entity: "Agah Karakuzu"
7+
copyright_entity: "CPP visual motion localizer developpers"
68

79
# metrics limit for the code quality (https://florianschanda.github.io/miss_hit/metrics.html)
810
metric "cnest": limit 4

setParameters.m

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
% (C) Copyright 2020 CPP visual motion localizer developpers
2+
13
function [cfg] = setParameters()
24

35
% VISUAL LOCALIZER
@@ -9,21 +11,21 @@
911
% setParamters.m file is
1012
% change that if you want the data to be saved somewhere else
1113
cfg.dir.output = fullfile( ...
12-
fileparts(mfilename('fullpath')), '..', ...
13-
'output');
14+
fileparts(mfilename('fullpath')), '..', ...
15+
'output');
1416

1517
%% Debug mode settings
1618

1719
cfg.debug.do = false; % To test the script out of the scanner, skip PTB sync
1820
cfg.debug.smallWin = false; % To test on a part of the screen, change to 1
19-
cfg.debug.transpWin = false; % To test with trasparent full size screen
21+
cfg.debug.transpWin = true; % To test with trasparent full size screen
2022

2123
cfg.verbose = false;
2224

2325
%% Engine parameters
2426

2527
cfg.testingDevice = 'mri';
26-
cfg.eyeTracker.do = true;
28+
cfg.eyeTracker.do = false;
2729
cfg.audio.do = false;
2830

2931
cfg = setMonitor(cfg);
@@ -34,18 +36,24 @@
3436
% MRI settings
3537
cfg = setMRI(cfg);
3638

37-
cfg.pacedByTriggers.do = true;
39+
cfg.pacedByTriggers.do = false;
3840

3941
%% Experiment Design
4042

41-
% cfg.design.motionType = 'translation';
43+
% cfg.design.localizer = 'MT_MST';
44+
4245
% cfg.design.motionType = 'radial';
4346
cfg.design.motionType = 'translation';
47+
4448
cfg.design.motionDirections = [0 0 180 180];
4549
cfg.design.names = {'static'; 'motion'};
4650
cfg.design.nbRepetitions = 8;
4751
cfg.design.nbEventsPerBlock = 12; % DO NOT CHANGE
4852

53+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
54+
cfg.design.names = {'fixation_right'; 'fixation_left'};
55+
end
56+
4957
%% Timing
5058

5159
% FOR 7T: if you want to create localizers on the fly, the following must be
@@ -65,6 +73,10 @@
6573
% Number of seconds after the end all the stimuli before ending the run
6674
cfg.timing.endDelay = 3.6;
6775

76+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
77+
cfg.timing.IBI = 3.6;
78+
end
79+
6880
% reexpress those in terms of repetition time
6981
if cfg.pacedByTriggers.do
7082

@@ -81,6 +93,11 @@
8193
cfg.timing.onsetDelay = 0;
8294
% Number of seconds after the end all the stimuli before ending the run
8395
cfg.timing.endDelay = 2;
96+
97+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
98+
cfg.timing.IBI = 2;
99+
end
100+
84101
end
85102

86103
%% Visual Stimulation
@@ -92,21 +109,30 @@
92109
% Number of dots per visual angle square.
93110
cfg.dot.density = 1;
94111
% Dot life time in seconds
95-
cfg.dot.lifeTime = 10;
112+
cfg.dot.lifeTime = .15;
96113
% proportion of dots killed per frame
97-
cfg.dot.proportionKilledPerFrame = 0;
114+
cfg.dot.proportionKilledPerFrame = 0.005;
98115
% Dot Size (dot width) in visual angles.
99-
cfg.dot.size = .1;
116+
cfg.dot.size = .2;
100117
cfg.dot.color = cfg.color.white;
101118

102119
% Diameter/length of side of aperture in Visual angles
103120
cfg.aperture.type = 'none';
104121
cfg.aperture.width = []; % if left empty it will take the screen height
105122
cfg.aperture.xPos = 0;
106123

124+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
125+
cfg.aperture.type = 'circle';
126+
cfg.aperture.width = 7; % if left empty it will take the screen height
127+
cfg.aperture.xPos = 7;
128+
end
129+
107130
%% Task(s)
108131

109132
cfg.task.name = 'visual localizer';
133+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
134+
cfg.task.name = 'mt mst localizer';
135+
end
110136

111137
% Instruction
112138
cfg.task.instruction = '1-Detect the RED fixation cross\n \n\n';
@@ -115,24 +141,32 @@
115141
cfg.fixation.type = 'cross';
116142
cfg.fixation.colorTarget = cfg.color.red;
117143
cfg.fixation.color = cfg.color.white;
118-
cfg.fixation.width = .5;
144+
cfg.fixation.width = .25;
119145
cfg.fixation.lineWidthPix = 3;
120146
cfg.fixation.xDisplacement = 0;
121147
cfg.fixation.yDisplacement = 0;
122148

123149
cfg.target.maxNbPerBlock = 1;
124150
cfg.target.duration = 0.05; % In secs
125151

126-
cfg.extraColumns = {'direction', 'speed', 'target', 'event', 'block', 'keyName'};
152+
cfg.extraColumns = { ...
153+
'direction', ...
154+
'speed', ...
155+
'target', ...
156+
'event', ...
157+
'block', ...
158+
'keyName', ...
159+
'fixationPosition', ...
160+
'aperturePosition'};
127161

128162
end
129163

130164
function cfg = setKeyboards(cfg)
131165
cfg.keyboard.escapeKey = 'ESCAPE';
132166
cfg.keyboard.responseKey = { ...
133-
'r', 'g', 'y', 'b', ...
134-
'd', 'n', 'z', 'e', ...
135-
't'}; % dnze rgyb
167+
'r', 'g', 'y', 'b', ...
168+
'd', 'n', 'z', 'e', ...
169+
't'};
136170
cfg.keyboard.keyboard = [];
137171
cfg.keyboard.responseBox = [];
138172

@@ -145,7 +179,7 @@
145179
function cfg = setMRI(cfg)
146180
% letter sent by the trigger to sync stimulation and volume acquisition
147181
cfg.mri.triggerKey = 't';
148-
cfg.mri.triggerNb = 5;
182+
cfg.mri.triggerNb = 1;
149183

150184
cfg.mri.repetitionTime = 1.8;
151185

subfun/assignConditions.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
% (C) Copyright 2020 CPP visual motion localizer developpers
2+
3+
function [conditionNamesVector, CONDITON1_INDEX, CONDITON2_INDEX] = assignConditions(cfg)
4+
5+
[~, nbRepet] = getDesignInput(cfg);
6+
7+
conditionNamesVector = repmat(cfg.design.names, nbRepet, 1);
8+
9+
% Get the index of each condition
10+
nameCondition1 = 'static';
11+
nameCondition2 = 'motion';
12+
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
13+
nameCondition1 = 'fixation_right';
14+
nameCondition2 = 'fixation_left';
15+
end
16+
17+
CONDITON1_INDEX = find(strcmp(conditionNamesVector, nameCondition1));
18+
CONDITON2_INDEX = find(strcmp(conditionNamesVector, nameCondition2));
19+
20+
end

0 commit comments

Comments
 (0)