Skip to content

Commit 136cd6e

Browse files
authored
Merge pull request #94 from cpp-lln-lab/dev
[ENH] Add tests and update design
2 parents 187e6b8 + 449a5a4 commit 136cd6e

36 files changed

+678
-371
lines changed

.github/workflows/miss_hit_quality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches:
66
- master
77
pull_request:
8-
branches: '*'
8+
branches: ['*']
99

1010
jobs:
1111
build:

.github/workflows/miss_hit_style.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches:
66
- master
77
pull_request:
8-
branches: '*'
8+
branches: ['*']
99

1010
jobs:
1111
build:

.github/workflows/moxunit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
name: CI
1+
name: tests and coverage
22

33
on:
44
push:
55
branches:
66
- master
77
pull_request:
8-
branches: '*'
8+
branches: ['*']
99

1010
jobs:
1111
build:

.gitignore

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
11
*DS_Store
22

3-
*.m~
4-
*.asv
5-
*octave-workspace
63

74
# exclude content of logfiles folders
85
*/logfiles/*
96
*/*/*/logfiles/*
107
*.tsv
118
*.mat
9+
10+
## virtual env
11+
env/
12+
venv/
13+
14+
## visual studio code
15+
.vscode
16+
17+
## MATLAB / OCTAVE gitignore template
18+
19+
# From : https://github.com/github/gitignore/blob/master/Global/MATLAB.gitignore
20+
21+
# Windows default autosave extension
22+
*.asv
23+
24+
# OSX / *nix default autosave extension
25+
*.m~
26+
27+
# Compiled MEX binaries (all platforms)
28+
*.mex*
29+
30+
# Packaged app and toolbox files
31+
*.mlappinstall
32+
*.mltbx
33+
34+
# Generated helpsearch folders
35+
helpsearch*/
36+
37+
# Simulink code generation folders
38+
slprj/
39+
sccprj/
40+
41+
# Matlab code generation folders
42+
codegen/
43+
44+
# Simulink autosave extension
45+
*.autosave
46+
47+
# Simulink cache files
48+
*.slxc
49+
50+
# Octave session info
51+
octave-workspace

README.md

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,19 @@
2929

3030
# fMRI localizers for visual motion
3131

32-
## Translational Motion
33-
3432
## Requirements
3533

36-
Make sure that the following toolboxes are installed and added to the matlab / octave path.
34+
Make sure that the following toolboxes are installed and added to the matlab / octave path. See the next section on how to install the submodule toolboxes.
3735

3836
For instructions see the following links:
3937

40-
| Requirements | Used version |
41-
| -------------------------------------------------------- | ------------ |
42-
| [CPP_BIDS](https://github.com/cpp-lln-lab/CPP_BIDS) | ? |
43-
| [CPP_PTB](https://github.com/cpp-lln-lab/CPP_PTB) | ? |
44-
| [PsychToolBox](http://psychtoolbox.org/) | >=3.0.14 |
45-
| [Matlab](https://www.mathworks.com/products/matlab.html) | >=2017 |
46-
| or [octave](https://www.gnu.org/software/octave/) | >=4.? |
38+
| Requirements | Used version |
39+
| --------------------------------------------------------------- | ------------ |
40+
| [CPP_BIDS](https://github.com/cpp-lln-lab/CPP_BIDS) (submodule) | 2.1.0 |
41+
| [CPP_PTB](https://github.com/cpp-lln-lab/CPP_PTB) (submodule) | 1.2.0 |
42+
| [PsychToolBox](http://psychtoolbox.org/) | >=3.0.14 |
43+
| [Matlab](https://www.mathworks.com/products/matlab.html) | >=2017 |
44+
| or [octave](https://www.gnu.org/software/octave/) | >=4.? |
4745

4846
## Installation
4947

@@ -56,11 +54,11 @@ git clone --recurse-submodules https://github.com/cpp-lln-lab/localizer_visual_m
5654

5755
## Structure and function details
5856

59-
### visualLocTranslational
57+
### visualMotionLocalizer
6058

61-
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)
59+
Running this script will show blocks of motion dots and static dots. Motion blocks will show dots moving in one of four directions (up-, down-, left-, and right-ward) (MT+ localizer) or dots moving inward and outward in the peripheral of the screen (MT/MST localizer).
6260

63-
By default it is run in `Debug mode` meaning that it does not run care about subjID, run n., fMRI triggers, Eye Tracker, etc..
61+
Run in `Debug mode` (see `setParameters.m`) it does not care about subjID, run n., Eye Tracker (soon, at the moment it needs to be set off manually), etc..
6462

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

@@ -85,7 +83,7 @@ Any details of the experiment can be changed in `setParameters.m` (e.g., experim
8583
Set `cfg.pacedByTriggers.do` to `true` and you can then set all the details in this `if` block
8684

8785
```matlab
88-
% Time is here in in terms of number repetition time (i.e MRI volumes)
86+
% Time is here in terms of `repetition time (TR)` (i.e. MRI volumes)
8987
if cfg.pacedByTriggers.do
9088
9189
cfg.pacedByTriggers.quietMode = true;
@@ -107,45 +105,65 @@ end
107105

108106
### subfun/doDotMo
109107

108+
Wrapper function that present the dot stimulation (static or motion) per event.
109+
110110
#### Input
111111

112-
- `cfg`: PTB/machine configurations returned by `setParameters` and `initPTB`
113-
- `expParameters`: parameters returned by `setParameters`
112+
- `cfg`: PTB/machine and experiment configurations returned by `setParameters` and `initPTB`
114113
- `logFile`: structure that stores the experiment logfile to be saved
114+
- `thisEvent`: structure that stores information about the event to present regarding the dots (static or motion, direction, etc.)
115+
- `thisFixation`: structure that stores information about the fixation cross task to present
116+
- `dots`: [...]
117+
- `iEvent`: index of the event of the block at the moment of the presentation
115118

116119
#### Output
117120

118121
- Event `onset`
119122
- Event `duration`
123+
- `dots`: [...]
120124

121-
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.
125+
> NB: 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.
122126
123-
### subfun/expDesign
127+
### subfun/expDesign(MtMst)
124128

125-
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.
129+
These functions, one per MT+ and one per MT/MST localizer, create the sequence of blocks and the events in them. The conditions are consecutive static and motion blocks (Gives better results than randomised).
126130

127-
#### EVENTS
131+
It can be run as a stand alone without inputs and display a visual example of the possible design. See `getMockConfig` to set up the mock configuration.
128132

129-
The `numEventsPerBlock` should be a multiple of the number of "base" listed in the `motionDirections` and `staticDirections` (4 at the moment).
133+
It computes the directions to display and the task(s), at the moment
134+
1. detection of change in the color of the fixation target
135+
2. detection of different speed of the moving dots [ W I P - if selected as a task it will give the same null output as if not selected ie no difference in speed]
130136

131-
#### TARGETS
137+
#### Events
132138

133-
- If there are 2 targets per block we make sure that they are at least 2 events apart.
134-
- Targets cannot be on the first or last event of a block
139+
The ``nbEventsPerBlock`` should be a multiple of the number of motion directions requested in ``motionDirections`` (which should be more than 1) e.g.:
140+
- MT localizer: `cfg.design.motionDirections = [ 0 90 180 270 ]; % right down left up`
141+
- MT_MST localizer: `cfg.design.motionDirections = [666 -666]; % outward inward`
135142

136-
#### Input
143+
#### Pseudorandomization rules:
137144

138-
- `expParameters`: parameters returned by `setParameters`
139-
- `displayFigs`: a boolean to decide whether to show the basic design matrix of the design
145+
- Directions:
146+
1. Directions are all presented in random orders in `numEventsPerBlock/nDirections` consecutive chunks. This evenly distribute the directions across the block.
147+
2. No same consecutive direction
140148

141-
#### Output
149+
- Color change detection of the fixation cross:
150+
1. If there are 2 targets per block we make sure that they are at least 2 events apart.
151+
2. Targets cannot be on the first or last event of a block.
152+
3. No less than 1 target per event position in the whole run
153+
154+
#### Input:
155+
- `cfg`: parameters returned by setParameters
156+
- `displayFigs`: a boolean to decide whether to show the basic design matrix of the design
142157

143-
- `expParameters.designBlockNames` is a cell array `(nr_blocks, 1)` with the name for each block
144-
- `expParameters.designDirections` is an array `(nr_blocks, numEventsPerBlock)` with the direction to present in a given block
145-
- `0 90 180 270` indicate the angle
146-
- `-1` indicates static
147-
- `expParameters.designSpeeds` is an array `(nr_blocks, numEventsPerBlock) * speedEvent`
148-
- `expParameters.designFixationTargets` is an array `(nr_blocks, numEventsPerBlock)` showing for each event if it should be accompanied by a target
158+
#### Output:
159+
- `cfg.design.blockNames`: cell array (nbBlocks, 1) with the condition name for each block
160+
- `cfg.design.nbBlocks`: integer for th etotal number of blocks in the run
161+
- `cfg.design.directions`: array (nbBlocks, nbEventsPerBlock) with the direction to present in a given event of a block.
162+
- 0 90 180 270 indicate the angle for translational motion direction
163+
- 666 -666 indicate in/out-ward direction in radial motion
164+
- -1 indicates static
165+
- `cfg.design.speeds`: array (nbBlocks, nbEventsPerBlock) indicate the dots speed in each event, the target is represented by a higher/lower value
166+
- `cfg.design.fixationTargets`: array (nbBlocks, numEventsPerBlock) showing for each event if it should be accompanied by a target
149167

150168
## Contributors ✨
151169

lib/CPP_BIDS

lib/CPP_PTB

Submodule CPP_PTB updated 159 files

miss_hit.cfg

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
project_root
2+
13
# style guide (https://florianschanda.github.io/miss_hit/style_checker.html)
24
line_length: 100
35
regex_function_name: "[a-z]+(([A-Z]){1}[A-Za-z]+)*"
6+
regex_parameter_name: "[a-z]+(([A-Z]){1}[A-Za-z0-9]+)*"
47
regex_script_name: "[a-z]+(([A-Z]){1}[A-Za-z]+)*"
58
exclude_dir: "lib"
69
copyright_entity: "Mohamed Rezk"
@@ -10,5 +13,5 @@ copyright_entity: "CPP visual motion localizer developpers"
1013
# metrics limit for the code quality (https://florianschanda.github.io/miss_hit/metrics.html)
1114
metric "cnest": limit 4
1215
metric "file_length": limit 500
13-
metric "cyc": limit 15
14-
metric "parameters": limit 7
16+
metric "cyc": limit 18
17+
metric "parameters": limit 8

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
miss_hit==0.9.22
1+
miss_hit==0.9.29
22
pre-commit

setParameters.m

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
% VISUAL LOCALIZER
66

7-
% Initialize the parameters and general configuration variables
7+
% Initialize the general configuration variables structure
88
cfg = struct();
99

1010
% by default the data will be stored in an output folder created where the
@@ -15,7 +15,7 @@
1515

1616
%% Debug mode settings
1717

18-
cfg.debug.do = false; % To test the script out of the scanner, skip PTB sync
18+
cfg.debug.do = true; % To test the script out of the scanner, skip PTB sync
1919
cfg.debug.smallWin = false; % To test on a part of the screen, change to 1
2020
cfg.debug.transpWin = false; % To test with trasparent full size screen
2121

@@ -26,7 +26,7 @@
2626
%% Engine parameters
2727

2828
cfg.testingDevice = 'mri';
29-
cfg.eyeTracker.do = true;
29+
cfg.eyeTracker.do = false;
3030
cfg.audio.do = false;
3131

3232
cfg = setMonitor(cfg);
@@ -38,7 +38,7 @@
3838
cfg = setMRI(cfg);
3939
% cfg.suffix.acquisition = '';
4040

41-
cfg.pacedByTriggers.do = true;
41+
cfg.pacedByTriggers.do = false;
4242

4343
%% Experiment Design
4444

@@ -57,13 +57,13 @@
5757

5858
% if you have static and motion and `nbRepetions` = 4, this will return 8 blocks (n blocks per
5959
% hemifield in case of MT/MST localizer)
60-
cfg.design.nbRepetitions = 10;
61-
cfg.design.nbEventsPerBlock = 10;
60+
cfg.design.nbRepetitions = 12;
61+
cfg.design.nbEventsPerBlock = 12;
6262

6363
%% Timing
6464

6565
% FOR 7T: if you want to create localizers on the fly, the following must be
66-
% multiples of the scanneryour sequence TR
66+
% multiples of the scanner sequence TR
6767
%
6868
% IBI
6969
% block length = (cfg.eventDuration + cfg.ISI) * cfg.design.nbEventsPerBlock
@@ -115,6 +115,8 @@
115115
% Dot Size (dot width) in visual angles.
116116
cfg.dot.size = .2;
117117
cfg.dot.color = cfg.color.white;
118+
% Static dots should change position at each event or not
119+
cfg.dot.staticReSeed = true;
118120

119121
% Diameter/length of side of aperture in Visual angles
120122
cfg.aperture.type = 'none';
@@ -130,7 +132,6 @@
130132

131133
% Fixation cross (in pixels)
132134
cfg.fixation.type = 'cross';
133-
cfg.fixation.colorTarget = cfg.color.red;
134135
cfg.fixation.color = cfg.color.white;
135136
cfg.fixation.width = .25;
136137
cfg.fixation.lineWidthPix = 3;
@@ -142,7 +143,12 @@
142143
cfg.target.duration = 0.1; % In secs
143144
cfg.target.type = 'fixation_cross';
144145
% 'fixation_cross' : the fixation cross changes color
145-
% 'static_repeat' : dots are in the same position
146+
% 'static_repeat' : static dots are in the same position as previous trials
147+
148+
cfg.fixation.colorTarget = cfg.fixation.color;
149+
if strcmp(cfg.target.type, 'fixation_cross')
150+
cfg.fixation.colorTarget = cfg.color.red;
151+
end
146152

147153
cfg.extraColumns = { ...
148154
'direction', ...

subfun/assignConditions.m

Lines changed: 0 additions & 23 deletions
This file was deleted.

subfun/diplayDesign.m renamed to subfun/design/diplayDesign.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
% (C) Copyright 2020 CPP visual motion localizer developpers
2-
31
function diplayDesign(cfg, displayFigs)
2+
%
3+
% (C) Copyright 2020 CPP visual motion localizer developpers
44

55
%% Visualize the design matrix
66
if displayFigs
@@ -44,7 +44,7 @@ function diplayDesign(cfg, displayFigs)
4444

4545
figure(2);
4646

47-
[motionDirections] = getDirectionBaseVectors(cfg);
47+
[~, motionDirections] = getDirectionBaseVectors(cfg);
4848
motionDirections = unique(motionDirections);
4949

5050
for iMotion = 1:length(motionDirections)

0 commit comments

Comments
 (0)