Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 32 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,30 @@

[![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)

<!-- vscode-markdown-toc -->

- 1. [Requirements](#Requirements)
- 2. [Installation](#Installation)
- 3. [Structure and function details](#Structureandfunctiondetails)
_ 3.1. [visualLocTranslational](#visualLocTranslational)
_ 3.2. [setParameters](#setParameters)
_ 3.3. [subfun/doDotMo](#subfundoDotMo)
_ 3.3.1. [Input:](#Input:)
_ 3.3.2. [Output:](#Output:)
_ 3.4. [subfun/expDesign](#subfunexpDesign)
_ 3.4.1. [EVENTS](#EVENTS)
_ 3.4.2. [TARGETS:](#TARGETS:)
_ 3.4.3. [Input:](#Input:-1)
_ 3.4.4. [Output:](#Output:-1)

<!-- vscode-markdown-toc-config
numbering=true
autoSave=true
/vscode-markdown-toc-config -->
<!-- /vscode-markdown-toc -->
<!-- TOC -->
- [fMRI localizers for visual motion](#fmri-localizers-for-visual-motion)
- [Translational Motion](#translational-motion)
- [Requirements](#requirements)
- [Installation](#installation)
- [Structure and function details](#structure-and-function-details)
- [visualLocTranslational](#visualloctranslational)
- [setParameters](#setparameters)
- [Let the scanner pace the experiment](#let-the-scanner-pace-the-experiment)
- [subfun/doDotMo](#subfundodotmo)
- [Input](#input)
- [Output](#output)
- [subfun/expDesign](#subfunexpdesign)
- [EVENTS](#events)
- [TARGETS](#targets)
- [Input](#input-1)
- [Output](#output-1)
<!-- TOC -->

# fMRI localizers for visual motion

# Translational Motion
## Translational Motion

## 1. <a name='Requirements'></a>Requirements
## Requirements

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

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

## 2. <a name='Installation'></a>Installation
## Installation

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

## 3. <a name='Structureandfunctiondetails'></a>Structure and function details
## Structure and function details

### 3.1. <a name='visualLocTranslational'></a>visualLocTranslational
### visualLocTranslational

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)

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

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

### 3.2. <a name='setParameters'></a>setParameters
### setParameters

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

Expand Down Expand Up @@ -105,40 +102,40 @@ if cfg.pacedByTriggers.do
end
```

### 3.3. <a name='subfundoDotMo'></a>subfun/doDotMo
### subfun/doDotMo

#### 3.3.1. <a name='Input:'></a>Input:
#### Input

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

#### 3.3.2. <a name='Output:'></a>Output:
#### Output

- Event `onset`
- Event `duration`

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.

### 3.4. <a name='subfunexpDesign'></a>subfun/expDesign
### subfun/expDesign

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.

#### 3.4.1. <a name='EVENTS'></a>EVENTS
#### EVENTS

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

#### 3.4.2. <a name='TARGETS:'></a>TARGETS:
#### TARGETS

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

#### 3.4.3. <a name='Input:-1'></a>Input:
#### Input

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

#### 3.4.4. <a name='Output:-1'></a>Output:
#### Output

- `expParameters.designBlockNames` is a cell array `(nr_blocks, 1)` with the name for each block
- `expParameters.designDirections` is an array `(nr_blocks, numEventsPerBlock)` with the direction to present in a given block
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Documentation
31 changes: 16 additions & 15 deletions initEnv.m
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
%
% 1 - Check if version requirements
% are satisfied and the packages are
% are installed/loaded:
% Octave > 4
% - image
% - optim
% - struct
% - statistics
%
% MATLAB >= R2015b
%
% 2 - Add project to the O/M path
% (C) Copyright 2020 Agah Karakuzu
% (C) Copyright 2019 CPP BIDS SPM-pipeline developpers

function initEnv
% 1 - Check if version requirements
% are satisfied and the packages are
% are installed/loaded:
% Octave > 4
% - image
% - optim
% - struct
% - statistics
%
% MATLAB >= R2015b
%
% 2 - Add project to the O/M path

octaveVersion = '4.0.3';
matlabVersion = '8.6.0';
Expand Down Expand Up @@ -56,8 +57,8 @@

if numel(dir(libDirectory)) <= 2 % Means that the external is empty
error(['Git submodules are not cloned!', ...
'Try this in your terminal:', ...
' git submodule update --recursive ']);
'Try this in your terminal:', ...
' git submodule update --recursive ']);
else
addDependencies();
end
Expand Down
2 changes: 1 addition & 1 deletion lib/CPP_PTB
1 change: 1 addition & 0 deletions lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# External libraries and dependencies
4 changes: 3 additions & 1 deletion miss_hit.cfg
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# style guide (https://florianschanda.github.io/miss_hit/style_checker.html)
line_length: 100
regex_function_name: "[a-z]+(([A-Z]){1}[A-Za-z]+)*"
suppress_rule: "copyright_notice"
exclude_dir: "lib"
copyright_entity: "Mohamed Rezk"
copyright_entity: "Agah Karakuzu"
copyright_entity: "CPP visual motion localizer developpers"

# metrics limit for the code quality (https://florianschanda.github.io/miss_hit/metrics.html)
metric "cnest": limit 4
Expand Down
64 changes: 49 additions & 15 deletions setParameters.m
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
% (C) Copyright 2020 CPP visual motion localizer developpers

function [cfg] = setParameters()

% VISUAL LOCALIZER
Expand All @@ -9,21 +11,21 @@
% setParamters.m file is
% change that if you want the data to be saved somewhere else
cfg.dir.output = fullfile( ...
fileparts(mfilename('fullpath')), '..', ...
'output');
fileparts(mfilename('fullpath')), '..', ...
'output');

%% Debug mode settings

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

cfg.verbose = false;

%% Engine parameters

cfg.testingDevice = 'mri';
cfg.eyeTracker.do = true;
cfg.eyeTracker.do = false;
cfg.audio.do = false;

cfg = setMonitor(cfg);
Expand All @@ -34,18 +36,24 @@
% MRI settings
cfg = setMRI(cfg);

cfg.pacedByTriggers.do = true;
cfg.pacedByTriggers.do = false;

%% Experiment Design

% cfg.design.motionType = 'translation';
% cfg.design.localizer = 'MT_MST';

% cfg.design.motionType = 'radial';
cfg.design.motionType = 'translation';

cfg.design.motionDirections = [0 0 180 180];
cfg.design.names = {'static'; 'motion'};
cfg.design.nbRepetitions = 8;
cfg.design.nbEventsPerBlock = 12; % DO NOT CHANGE

if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
cfg.design.names = {'fixation_right'; 'fixation_left'};
end

%% Timing

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

if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
cfg.timing.IBI = 3.6;
end

% reexpress those in terms of repetition time
if cfg.pacedByTriggers.do

Expand All @@ -81,6 +93,11 @@
cfg.timing.onsetDelay = 0;
% Number of seconds after the end all the stimuli before ending the run
cfg.timing.endDelay = 2;

if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
cfg.timing.IBI = 2;
end

end

%% Visual Stimulation
Expand All @@ -92,21 +109,30 @@
% Number of dots per visual angle square.
cfg.dot.density = 1;
% Dot life time in seconds
cfg.dot.lifeTime = 10;
cfg.dot.lifeTime = .15;
% proportion of dots killed per frame
cfg.dot.proportionKilledPerFrame = 0;
cfg.dot.proportionKilledPerFrame = 0.005;
% Dot Size (dot width) in visual angles.
cfg.dot.size = .1;
cfg.dot.size = .2;
cfg.dot.color = cfg.color.white;

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

if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
cfg.aperture.type = 'circle';
cfg.aperture.width = 7; % if left empty it will take the screen height
cfg.aperture.xPos = 7;
end

%% Task(s)

cfg.task.name = 'visual localizer';
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
cfg.task.name = 'mt mst localizer';
end

% Instruction
cfg.task.instruction = '1-Detect the RED fixation cross\n \n\n';
Expand All @@ -115,24 +141,32 @@
cfg.fixation.type = 'cross';
cfg.fixation.colorTarget = cfg.color.red;
cfg.fixation.color = cfg.color.white;
cfg.fixation.width = .5;
cfg.fixation.width = .25;
cfg.fixation.lineWidthPix = 3;
cfg.fixation.xDisplacement = 0;
cfg.fixation.yDisplacement = 0;

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

cfg.extraColumns = {'direction', 'speed', 'target', 'event', 'block', 'keyName'};
cfg.extraColumns = { ...
'direction', ...
'speed', ...
'target', ...
'event', ...
'block', ...
'keyName', ...
'fixationPosition', ...
'aperturePosition'};

end

function cfg = setKeyboards(cfg)
cfg.keyboard.escapeKey = 'ESCAPE';
cfg.keyboard.responseKey = { ...
'r', 'g', 'y', 'b', ...
'd', 'n', 'z', 'e', ...
't'}; % dnze rgyb
'r', 'g', 'y', 'b', ...
'd', 'n', 'z', 'e', ...
't'};
cfg.keyboard.keyboard = [];
cfg.keyboard.responseBox = [];

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

cfg.mri.repetitionTime = 1.8;

Expand Down
20 changes: 20 additions & 0 deletions subfun/assignConditions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
% (C) Copyright 2020 CPP visual motion localizer developpers

function [conditionNamesVector, CONDITON1_INDEX, CONDITON2_INDEX] = assignConditions(cfg)

[~, nbRepet] = getDesignInput(cfg);

conditionNamesVector = repmat(cfg.design.names, nbRepet, 1);

% Get the index of each condition
nameCondition1 = 'static';
nameCondition2 = 'motion';
if isfield(cfg.design, 'localizer') && strcmpi(cfg.design.localizer, 'MT_MST')
nameCondition1 = 'fixation_right';
nameCondition2 = 'fixation_left';
end

CONDITON1_INDEX = find(strcmp(conditionNamesVector, nameCondition1));
CONDITON2_INDEX = find(strcmp(conditionNamesVector, nameCondition2));

end
Loading