Commit 5fe6b4c2 authored by Jesse Heckman's avatar Jesse Heckman
Browse files

vPrime updates

parent eda33323
function [exp,cfg] = pb_vReadExp(expfile)
% PB_VREADEXP()
function [block,cfg] = pb_vReadExp(expfile)
% PB_VREADEXP(expfile)
%
% PB_VREADEXP() ...
% PB_VREADEXP() reads experimental data from expfile and loads BLOCK and
% CFG parameters.
%
% See also ...
% See also PB_VRUNEXP
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
......@@ -12,30 +13,169 @@ function [exp,cfg] = pb_vReadExp(expfile)
if ~pb_fexist(expfile); return; end
fid = fopen(expfile,'r');
%% READ HEADER
%% HEADER
cfg = hread(fid);
exp = eread(fid);
cfg = struct;
cfg.comment = checkcomment(fid);
cfg = hread(fid,cfg);
n = cfg.Blocks;
%% EXP
block = struct([]);
block(1).signal = [];
block(1).trial = [];
bn = 0;
while ~feof(fid)
tline = fgetl(fid);
firstCell = sscanf(tline,'%s',1);
nchar = length(firstCell);
if strcmp(firstCell,'%'); firstCell = sscanf(tline,'%s',2); firstCell = firstCell(2:end-1); end
switch upper(firstCell)
case 'BLOCK'
% Updates counts for block
bn = bn+1; tn = 0; sn = 0;
fgetl(fid);
case 'TRIAL'
% Updates counts for trial
tn = tn+1; sn = 0;
case 'HOR'
% Writes horizontal vestibular signal for block
block(bn).signal.hor = readVest(tline);
case 'VER'
% Writes vertical vestibular signal for block
block(bn).signal.ver = readVest(tline);
case {'SND','SND1','SND2'}
% Updates count and writes stimulus
sn = sn+1;
par = sscanf(tline(nchar+1:end),'%d%d%d%f%d%d',[6,1]);
block(bn).trial(tn).stim(sn).modality = 'sound';
block(bn).trial(tn).stim(sn).X = par(1);
block(bn).trial(tn).stim(sn).Y = par(2);
block(bn).trial(tn).stim(sn).matfile = ['snd' num2str(par(3),'%03i') '.mat']; % for sphere
block(bn).trial(tn).stim(sn).wavfile = ['snd' num2str(par(3),'%03i') '.wav']; % double, for hoop
block(bn).trial(tn).stim(sn).parameters = par(3); % for sphereMinor
block(bn).trial(tn).stim(sn).matfile = ['snd' num2str(par(3),'%03i') '.mat'];
block(bn).trial(tn).stim(sn).wavfile = ['snd' num2str(par(3),'%03i') '.wav']; % double
block(bn).trial(tn).stim(sn).intensity = par(4);
block(bn).trial(tn).stim(sn).onevent = par(5);
block(bn).trial(tn).stim(sn).ondelay = par(6);
block(bn).trial(tn).stim(sn).offevent = par(5); % default duration
block(bn).trial(tn).stim(sn).offdelay = par(6)+150; % default duration
case {'LED','LED1','LED2'}
% Updates count and writes stimulus
sn = sn+1;
par = sscanf(tline(nchar+1:end),'%d%d%d%d%d%d%d',[7,1]);
block(bn).trial(tn).stim(sn).modality = 'LED';
block(bn).trial(tn).stim(sn).X = par(1);
block(bn).trial(tn).stim(sn).Y = par(2);
block(bn).trial(tn).stim(sn).intensity = par(3);
block(bn).trial(tn).stim(sn).intensity = par(3); % hoop: range 0-255, sphere range 1-50
block(bn).trial(tn).stim(sn).onevent = par(4);
block(bn).trial(tn).stim(sn).ondelay = par(5);
block(bn).trial(tn).stim(sn).offevent = par(6);
block(bn).trial(tn).stim(sn).offdelay = par(7);
case 'TRG0'
% Updates count and writes stimulus
sn = sn+1;
par = sscanf(tline(nchar+1:end),'%d%d%d%d%d',[5,1]);
block(bn).trial(tn).stim(sn).modality = 'trigger';
if par(1) == 1
block(bn).trial(tn).stim(sn).detect = 'rise';
elseif par==2
block(bn).trial(tn).stim(sn).detect = 'fall';
end
block(bn).trial(tn).stim(sn).channel = par(2);
block(bn).trial(tn).stim(sn).onevent = par(3);
block(bn).trial(tn).stim(sn).ondelay = par(4);
block(bn).trial(tn).stim(sn).event = par(5);
case 'ACQ'
% Updates count and writes stimulus
sn = sn+1;
par = sscanf(tline(nchar+1:end),'%d%d',[2,1]); % could also be 3
block(bn).trial(tn).stim(sn).modality = 'data acquisition';
block(bn).trial(tn).stim(sn).onevent = par(1);
block(bn).trial(tn).stim(sn).ondelay = par(2);
end
end
%% CHECK OUT
fclose(fid);
end
function header = hread(fid)
tline = fgetl(fid);
while ~contains(tline,'%% HEADER') % find header
tline = fgetl(fid);
function comment = checkcomment(fid)
isComment = true;
cnt = 0; % counter
comment = cell(1);
while isComment % do this for every line that starts with '%'
position = ftell(fid); % find the position in the file
str = fscanf(fid,'%s',1); % read the string (moving the position in the file)
commentline = fgetl(fid); % get the entire line (again repositioning)
isComment = strncmp(str,'%',1); % and check whether the first string of the line actually indicated a comment
if ~isempty(commentline) && isComment
cnt = cnt+1;
comment(cnt) = {commentline};
end
end
tmp = fgetl(fid);
fseek(fid,position,'bof');
end
function cfg = hread(fid,cfg)
cnt = 0;
isBody = false;
header = cell(1);
header.ITI = [];
while ~isBody
position = ftell(fid);
str = fscanf(fid,'%s',1);
isBody = strcmp(str,'~~~');
if ~isBody
fseek(fid,position,'bof');
cnt = cnt+1;
header(cnt) = {fscanf(fid,'%s',1)};
switch lower(header{cnt})
case 'iti' % Inter-trial interval
cfg.(header{cnt}) = fscanf(fid,'%d %d',[2 1]); % 2 integers: minimum and maximum possible inter trial interval
case 'motor' % Motor
cfg.(header{cnt}) = fscanf(fid,'%s',1); % String: yes or no
otherwise
cfg.(header{cnt}) = fscanf(fid,'%d',1); % Integer
end
checkcomment(fid);
end
end
end
function experiment = eread(fid)
experiment = fid;
function signal = readVest(line)
types = {'none','sine','noise','step'};
n = str2num(erase(sscanf(line,'%s',2),sscanf(line,'%s',1)))+1;
type = types{n};
signal.type = type;
if ~strcmp(type,'none')
signal.amplitude = str2double(erase(sscanf(line,'%s',3),sscanf(line,'%s',2)));
signal.duration = str2double(erase(sscanf(line,'%s',4),sscanf(line,'%s',3)));
end
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %
% Part of Programmeer Beer Toolbox (PBToolbox) %
......
function pb_vRunExp(Exp,h)
function pb_vRunExp(expinfo,h)
% PB_VRUNEXP(varargin)
%
% PB_VRUNEXP() forms the core body of experimental paradigms in the VC, and
......@@ -12,9 +12,9 @@ function pb_vRunExp(Exp,h)
%% INITIALIZE
% load & read experiment
[experiment, cfg] = pb_vReadExp(Exp.expfile); % struct
nblocks = cfg.nblocks;
nTotTrials = cfg.ntrials;
[block, cfg] = pb_vReadExp(expinfo.expfile); % struct
nblocks = cfg.Blocks;
nTotTrials = cfg.Trials;
......@@ -23,8 +23,10 @@ function pb_vRunExp(Exp,h)
% iterate experiment
for iBlock = 1:nblocks
nTrials = Experiment(iBlock).info.ntrials; % ntrials in block
signal = Experiment(iBlock).info.veststim; % IMPORTANT: veststim has to be a struct with hor and vert component!
nTrials = length(block(iBlock).trial);
signal = block(iBlock).signal;
pb_vSafety(signal); % Checks for safe vestibular parameters!!
for iTrial = 1:nTrials
......
function pb_vSafety(signal)
% PB_VSAFETY()
%
% PB_VSAFETY() ...
%
% See also ...
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
if ~strcmp(signal.hor.type,'none')
if signal.hor.duration > 300
error('Unsafe signal: Horizontal duration too long!')
end
if signal.hor.amplitude > 20
error('Unsafe signal: Horizontal amplitude too large!')
end
end
if ~strcmp(signal.ver.type,'none')
if signal.ver.duration > 300
error('Unsafe signal: Vertical duration too long!')
end
if signal.ver.amplitude > 50
error('Unsafe signal: Horizontal amplitude too large!')
end
end
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %
% Part of Programmeer Beer Toolbox (PBToolbox) %
% Written by: Jesse J. Heckman (2018) %
% %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment