diff --git a/README.md b/README.md index d5b363a..cd21372 100644 --- a/README.md +++ b/README.md @@ -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 + + +- 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) + + + + +## 1. 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. 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. @@ -21,10 +49,9 @@ 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. Structure and function details -### audioLocTranslational +### 3.1. 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) @@ -32,7 +59,7 @@ By default it is run in `Debug mode` meaning that it does not care about subjID, Any details of the experiment can be changed in `setParameters.m` (e.g., experiment mode, motion stimuli details, exp. design, etc.) -### setParameters +### 3.2. setParameters `setParameters.m` is the core engine of the experiment. It contains the following tweakable sections: @@ -49,21 +76,26 @@ Any details of the experiment can be changed in `setParameters.m` (e.g., experim - Instructions - Task #1 parameters -### subfun/expDesign +### 3.3. 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. 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. 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. 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. 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 @@ -71,8 +103,10 @@ The `numEventsPerBlock` should be a multiple of the number of "base" listed in t - `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. 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. subfun/wait4Trigger + Simple functions that counts the triggers sent by the MRI computer to the stimulation computer to sync brain volume recordings and stimulation. diff --git a/audioLocTranslational.m b/audioLocTranslational.m index 63e7262..c235df2 100644 --- a/audioLocTranslational.m +++ b/audioLocTranslational.m @@ -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); @@ -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( ... diff --git a/setParameters.m b/setParameters.m index 42ed4a6..ef7a88f 100644 --- a/setParameters.m +++ b/setParameters.m @@ -31,7 +31,7 @@ % MRI settings cfg = setMRI(cfg); - + cfg.pacedByTriggers.do = true; %% Experiment Design @@ -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 @@ -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 = []; diff --git a/subfun/doAuditoryMotion.m b/subfun/doAuditoryMotion.m index cd3c364..0c4c99f 100644 --- a/subfun/doAuditoryMotion.m +++ b/subfun/doAuditoryMotion.m @@ -1,5 +1,5 @@ function [onset, duration] = doAuditoryMotion(cfg, thisEvent) - + % Play the auditopry stimulation of moving in 4 directions or static noise bursts % % DIRECTIONS @@ -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'; @@ -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; @@ -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; diff --git a/subfun/expDesign.m b/subfun/expDesign.m index 091f170..e94afd1 100644 --- a/subfun/expDesign.m +++ b/subfun/expDesign.m @@ -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);