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
62 changes: 48 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
[![](https://img.shields.io/badge/Octave-CI-blue?logo=Octave&logoColor=white)](https://github.com/cpp-lln-lab/localizer_auditory_motion/actions)
![](https://github.com/cpp-lln-lab/localizer_auditory_motion/workflows/CI/badge.svg)

[![codecov](https://codecov.io/gh/cpp-lln-lab/localizer_auditory_motion/branch/master/graph/badge.svg)](https://codecov.io/gh/cpp-lln-lab/localizer_auditory_motion)

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


# Auditory Translational Motion

## Requirements
<!-- vscode-markdown-toc -->

- 1. [Requirements](#Requirements)
- 2. [Installation](#Installation)
- 3. [Structure and function details](#Structureandfunctiondetails)
_ 3.1. [audioLocTranslational](#audioLocTranslational)
_ 3.2. [setParameters](#setParameters)
_ 3.3. [subfun/expDesign](#subfunexpDesign)
_ 3.3.1. [EVENTS](#EVENTS)
_ 3.3.2. [TARGETS:](#TARGETS:)
_ 3.3.3. [Input:](#Input:)
_ 3.3.4. [Output:](#Output:)
_ 3.4. [subfun/eyeTracker](#subfuneyeTracker) \* 3.5. [subfun/wait4Trigger](#subfunwait4Trigger)

<!-- vscode-markdown-toc-config
numbering=true
autoSave=true
/vscode-markdown-toc-config -->
<!-- /vscode-markdown-toc -->

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

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

For instructions see the following links:

| Requirements | Used version |
|----------------------------------------------------------|--------------|
| -------------------------------------------------------- | ------------ |
| [PsychToolBox](http://psychtoolbox.org/) | >=3.0.14 |
| [Matlab](https://www.mathworks.com/products/matlab.html) | >=2017b |
| or [octave](https://www.gnu.org/software/octave/) | >=4.? |

## Installation
## 2. <a name='Installation'></a>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 @@ -21,18 +49,17 @@ You can install it all with git by doing.
git clone --recurse-submodules https://github.com/cpp-lln-lab/localizer_auditory_motion.git
```

## Structure and function details

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

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

Running this script will play blocks of motion/static sounds. Motion blocks will play sounds 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 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.)

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

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

Expand All @@ -49,30 +76,37 @@ Any details of the experiment can be changed in `setParameters.m` (e.g., experim
- Instructions
- Task #1 parameters

### subfun/expDesign
### 3.3. <a name='subfunexpDesign'></a>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 a possible design.

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

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

#### TARGETS:
#### 3.3.2. <a name='TARGETS:'></a>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

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

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

#### Output:
#### 3.3.4. <a name='Output:'></a>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
- `0 90 180 270` indicate the angle
- `-1` indicates static
- `expParameters.designSpeeds` is an array `(nr_blocks, numEventsPerBlock) * speedEvent`
- `expParameters.designFixationTargets` is an array `(nr_blocks, numEventsPerBlock)` showing for each event if it should be accompanied by a target

### subfun/eyeTracker
### 3.4. <a name='subfuneyeTracker'></a>subfun/eyeTracker

Eyetracker script, still to be debugged. Will probably moved in the CPP_PTB package. It deals with the calibration (dufault or custom), eye movements recording and saving the files.

### subfun/wait4Trigger
### 3.5. <a name='subfunwait4Trigger'></a>subfun/wait4Trigger

Simple functions that counts the triggers sent by the MRI computer to the stimulation computer to sync brain volume recordings and stimulation.
6 changes: 3 additions & 3 deletions audioLocTranslational.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@
[cfg] = initPTB(cfg);

[el] = eyeTracker('Calibration', cfg);

[cfg] = expDesign(cfg);

% Prepare for the output logfiles with all
logFile.extraColumns = cfg.extraColumns;
logFile = saveEventsFile('open', cfg, logFile);

% disp(cfg);
% disp(cfg);

% Show experiment instruction
standByScreen(cfg);
Expand Down Expand Up @@ -84,7 +84,7 @@
thisEvent.direction = cfg.design.directions(iBlock, iEvent);
% thisEvent.speed = cfg.design.speeds(iBlock, iEvent);
thisEvent.target = cfg.design.fixationTargets(iBlock, iEvent);

% we wait for a trigger every 2 events
if cfg.pacedByTriggers.do && mod(iEvent, 2) == 1
waitForTrigger( ...
Expand Down
8 changes: 4 additions & 4 deletions setParameters.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

% MRI settings
cfg = setMRI(cfg);

cfg.pacedByTriggers.do = true;

%% Experiment Design
Expand All @@ -41,7 +41,7 @@
cfg.design.motionType = 'translation';
cfg.design.names = {'static'; 'motion'};
cfg.design.motionDirections = [-1 -1 1 1];
cfg.design.nbRepetitions = 14;
cfg.design.nbRepetitions = 14;
cfg.design.nbEventsPerBlock = 12;

%% Timing
Expand Down Expand Up @@ -130,10 +130,10 @@

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

Expand Down
34 changes: 17 additions & 17 deletions subfun/doAuditoryMotion.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function [onset, duration] = doAuditoryMotion(cfg, thisEvent)

% Play the auditopry stimulation of moving in 4 directions or static noise bursts
%
% DIRECTIONS
Expand All @@ -14,15 +14,15 @@
% - onset in machine time
% - duration in seconds
%

%% Get parameters

direction = thisEvent.direction(1);
isTarget = thisEvent.target(1);
targetDuration = cfg.target.duration;

soundData = cfg.soundData;

switch direction
case -1
fieldName = 'S';
Expand All @@ -35,18 +35,18 @@
case 180
fieldName = 'L';
end

if isTarget == 1
fieldName = [fieldName '_T'];
end

sound = soundData.(fieldName);

% Start the sound presentation
PsychPortAudio('FillBuffer', cfg.audio.pahandle, sound);
PsychPortAudio('Start', cfg.audio.pahandle);
onset = GetSecs;

% draw first fixation and get a first visual time stamp
% ideally we would want to synch that first time stamp and the sound start
thisFixation.fixation = cfg.fixation;
Expand All @@ -56,29 +56,29 @@
end
drawFixation(thisFixation);
vbl = Screen('Flip', cfg.screen.win);

while 1

% set default cross cross color but update if target time is not
% finished
thisFixation.fixation.color = cfg.fixation.color;
if GetSecs < (onset + targetDuration) && isTarget == 1
thisFixation.fixation.color = cfg.fixation.colorTarget;
end

drawFixation(thisFixation);
vbl = Screen('Flip', cfg.screen.win, vbl + cfg.screen.ifi);

status = PsychPortAudio('GetStatus', cfg.audio.pahandle);
if ~status.Active
break;
break
end

end

% Get the end time
waitForEndOfPlayback = 1; % hard coding that will need to be moved out
[onset, ~, ~, estStopTime] = PsychPortAudio('Stop', cfg.audio.pahandle, ...
waitForEndOfPlayback);

duration = estStopTime - onset;
4 changes: 2 additions & 2 deletions subfun/expDesign.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
if nargin < 1 || isempty(cfg)
error('give me something to work with');
end
fprintf('\n\nCreating design.\n\n')

fprintf('\n\nCreating design.\n\n');

[NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK, MAX_TARGET_PER_BLOCK] = getInput(cfg);
[~, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg);
Expand Down