This commit is contained in:
Jan-Bernard Marsman 2018-06-12 14:49:55 +02:00
parent 1edacb997d
commit d2cf032fab
230 changed files with 3192360 additions and 0 deletions

BIN
PDToolkit/.DS_Store vendored Normal file

Binary file not shown.

BIN
PDToolkit/@PDExperiment/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,87 @@
classdef PDExperiment
properties
name
description
filename
subjects
date
handle
settings = PDSettings
% struct('BaselineCorrection', 0,...
% 'FilterSize', 100, ...
% 'BlinkExtension', [10 10],...
% 'MaximumBlinkSize', 1000,...
% 'QualityThreshold',50);
%
% bl_types = {'None',...
% 'Average', ...
% 'Min', ...
% 'Percentile', ...
% 'Offset (fitted line)'};
aggregates %= PDAggregate;
end
methods
function[obj] = PDExperiment(varargin)
if nargin > 0
if strcmp(class(varargin{1}), 'PDSubject')
obj.subjects = varargin{1};
for s = 1:length(obj.subjects)
obj.subjects(s).index = s;
obj.subjects(s).name = sprintf('Subject %d', s);
end
else
if exist(varargin{1},'dir')
obj = obj.buildExperiment(varargin{1});
else
if strcmp(varargin{1}, 'placeholder');
% create an empty PDExperiment object (for GUI purposes)
else
error('Incorrect path entered / No PDSubjects entered');
end
end
end
if nargin ==1
if (strcmp(varargin{1}, 'placeholder'))
else
obj = obj.askForBaseline;
end
else
if ischar(varargin{2})
is_bl_type = find(strcmp(obj.bl_types, varargin{2}));
if isempty(is_bl_type)
warning('Baseline correction type is unknown.');
obj = obj.askForBaseline;
else
obj.settings.BaselineCorrection = is_bl_type;
try
obj.settings.BaselineCorrectionPercentile = varargin{3};
catch
end
end
else
obj.settings.BaselineCorrection = varargin{2};
end
end
else
error('No subjects entered');
end
obj = obj.consolidateSettings;
end
end
end

View File

@ -0,0 +1,108 @@
function[e] = add_aggregate(varargin)
e = varargin{1}
%% magical stuff so we are not overwriting...
fig = gcf;%e.handle(2);
figure(fig);
plotwindow_id = num2str(fig);
subj_pop = findobj('Tag', ['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag', ['sess_pop.' plotwindow_id]);
trial_pop = findobj('Tag', ['trial_pop.' plotwindow_id]);
select_edit = findobj('Tag', ['select_edit.' plotwindow_id]);
subject_val = get(subj_pop, 'Value');
session_val = get(sess_pop, 'Value');
trial_val = get(trial_pop, 'Value');
select_edit = get(select_edit, 'String');
subject_strings = cellstr(get(subj_pop, 'String'));
session_strings = cellstr(get(sess_pop, 'String'));
trial_strings = cellstr(get(trial_pop, 'String'));
if iscell(subject_val)
subjects = subject_strings{subject_val{1}};
else
subjects = subject_strings{subject_val};
end
if iscell(session_val)
sessions = session_val{1};
else
sessions = session_val;
end
if iscell(trial_val)
trials = trial_strings{trial_val{1}};
else
trials = trial_strings{trial_val};
end
tmp = get(fig, 'UserData');
if isempty(tmp)
tmp;
end
switch subjects
case 1
subjects = 1:length(e.subjects);
case 2
subjects = tmp.selected_subjects;
end
switch sessions
case 1
sessions= 1:length(e.subjects(1).sessions);
case 2
sessions = tmp.selected_subjects;
end
switch trials
case 1
trials = 1:length(e.subjects(1).sessions(1).trials);
case 2
trials = tmp.selected_subjects;
end
groupname = inputdlg('Give a name for the group');
if isempty(groupname)
return;
end
color = uisetcolor('Choose a color');
if length(color) ==1
return;
end
agg_id = length(e.aggregates)+1
if (length(color) == 1)
color = repmat(color, 1,3);
end
e.aggregates(agg_id).name = groupname;
e.aggregates(agg_id).subjects = subjects;
e.aggregates(agg_id).sessions = sessions;
e.aggregates(agg_id).trials = trials;
e.aggregates(agg_id).color = color;
e.aggregates(agg_id).mean = [];
e.aggregates(agg_id).std = [];
e.aggregates(agg_id).var = [];
e.aggregates(agg_id).error.name = 'None';
%e.aggregates(agg_id).variance = variance;
e = e.update_aggregates;
assignin('base','e',e);

View File

@ -0,0 +1,45 @@
function[obj] = askForBaseline(obj)
bl_types = {'None',...
'Average', ...
'Min', ...
'Lowest n% average', ...
'Offset (fitted line)',...
'Fixed point'};
np_types = [10 15 20 25 50];
np_labels= {'10%',...
'15%', ...
'20%', ...
'25%', ...
'50%',...
'Other'};
[s,OkClicked] = listdlg('PromptString','Select a baseline correction:',...
'SelectionMode','single',...
'ListString',bl_types, 'ListSize', [150 75]);
if OkClicked
if (s == 4)
[s2,OkClicked] = listdlg('PromptString','Select a percentile:',...
'SelectionMode','single',...
'ListString',np_labels, 'ListSize', [150 75]);
if (s2 == 6)
wrong_answer =1;
while wrong_answer
line = inputdlg({'Other percentile :'}, 'Percentile', 1, {'25'});
answer = str2num(line{1});
wrong_answer = ~((answer > 0) && (answer < 100));
end
percentile = answer;
else
percentile = np_types(s2);
end
obj.settings.BaselineCorrection = [s-1 percentile];
else
obj.settings.BaselineCorrection = [s-1];
end
end

View File

@ -0,0 +1,17 @@
function[e] = buildExperiment(obj, path)
e = obj;
folder_contents = dir(path);
folders = [folder_contents.isdir];
folder_ind = find(folders);
j=1;
for s = 3:length(folder_ind) % 1 and 2 are . and ..
%% load subject s
subject_path = [path filesep folder_contents(folder_ind(s)).name];
subjects(j) = PDSubject(subject_path);
j=j+1;
end
e.subjects = subjects;

View File

@ -0,0 +1,155 @@
function[e] = build_averages(e)
plotwindow = figure;
plotwindow_id = num2str(plotwindow);
pos = get(plotwindow, 'Position');
pos(3) = 900;
set(plotwindow, 'Position', pos);
set(plotwindow, 'Color', [1 1 1]);
e.handle(2) = plotwindow;
subj_pop = uicontrol('Style','popupmenu');
sess_pop = uicontrol('Style','popupmenu');
trial_pop = uicontrol('Style','popupmenu');
add_group_btn = uicontrol('Style', 'pushbutton');
rem_group_btn = uicontrol('Style', 'pushbutton');
subj_pop_string = 'All subjects|Selection of subjects'; subj_pop_vals =[999 998];
sess_pop_string = 'All sessions|First sessions|Second sessions'; sess_pop_vals =[999 998 997];
trial_pop_string = 'All trials|Selection of trials';
for s = 1:length(e.subjects)
subj_pop_string = [subj_pop_string '|' e.subjects(s).name];
subj_pop_vals = [subj_pop_vals s];
end
set(subj_pop, 'Position', [10 400 150 20]);
set(subj_pop, 'String', subj_pop_string);
set(subj_pop, 'Value', 1);
set(subj_pop, 'Callback', 'e.enable_selection_edit(''subject'')');
set(subj_pop, 'FontName', 'Verdana');
set(subj_pop, 'FontWeight', 'bold');
set(subj_pop, 'FontSize', 11);
sel=get(subj_pop, 'Value');
for s = 1:length(e.subjects(sel).sessions);
sess_pop_string = [sess_pop_string '|' e.subjects(sel).sessions(s).name];
sess_pop_vals = [sess_pop_vals s];
end
set(sess_pop, 'Position', [10 375 150 20]);
set(sess_pop, 'String', sess_pop_string);
set(sess_pop, 'Value', 1);
set(sess_pop, 'Callback', 'e.enable_selection_edit(''session'')');
set(sess_pop, 'FontName', 'Verdana');
set(sess_pop, 'FontWeight', 'bold');
set(sess_pop, 'FontSize', 11);
selsess = get(sess_pop, 'Value');
set(sess_pop, 'Position', [10 375 150 20]);
set(sess_pop, 'String', sess_pop_string);
set(sess_pop, 'Value', 1);
set(sess_pop, 'Callback', '');
set(sess_pop, 'FontName', 'Verdana');
set(sess_pop, 'FontWeight', 'bold');
set(sess_pop, 'FontSize', 11);
unique_matches = unique({e.subjects(1).sessions(1).labels.match});
unique_labels = unique({e.subjects(1).sessions(1).labels.label});
for t = 1:length(unique_matches)
trial_pop_string = [trial_pop_string '|' unique_matches{t}];
end
for t = 1:length(unique_labels)
trial_pop_string = [trial_pop_string '|' unique_labels{t}];
end
set(trial_pop, 'Position', [10 350 150 20]);
set(trial_pop, 'String', trial_pop_string);
set(trial_pop, 'Value', 1);
set(trial_pop, 'Callback', 'e.enable_selection_edit(''trial'')');
set(trial_pop, 'FontName', 'Verdana');
set(trial_pop, 'FontWeight', 'bold');
set(trial_pop, 'FontSize', 11);
select_edit(1) = uicontrol('Style', 'edit');
select_edit(2) = uicontrol('Style', 'edit');
select_edit(3) = uicontrol('Style', 'edit');
set(select_edit(1), 'Position', [170 400 150 20]);
set(select_edit(2), 'Position', [170 375 150 20]);
set(select_edit(3), 'Position', [170 350 150 20]);
set(select_edit, 'Visible' ,'off');
set(select_edit, 'String', []);
set(select_edit, 'FontName', 'Verdana');
set(select_edit, 'FontWeight', 'bold');
set(select_edit, 'FontSize', 11);
set(select_edit, 'Enable' ,'off');
set(select_edit(1), 'Tag', ['selection_edit.subject.' plotwindow_id]);
set(select_edit(1), 'Callback', 'e.evaluate_selection(''subject'')');
set(select_edit(2), 'Tag', ['selection_edit.session.' plotwindow_id]);
set(select_edit(2), 'Callback', 'e.evaluate_selection(''session'')');
set(select_edit(3), 'Tag', ['selection_edit.trial.' plotwindow_id]);
set(select_edit(3), 'Callback', 'e.evaluate_selection(''trial'')');
plot([]);
pos = get(gca, 'Position');
set(gca, 'Position', [.225 .275 .6 .7]);
set(gca, 'FontName', 'Verdana');
set(gca, 'FontWeight', 'bold');
set(gca, 'FontSize', 10);
set(gca, 'Box', 'on');
set(add_group_btn, 'Position', [10 190 70 20]);
set(rem_group_btn, 'Position', [90 190 70 20]);
set(add_group_btn, 'String', 'Add');
set(add_group_btn, 'Callback', @e.add_aggregate);
set(rem_group_btn, 'String', 'Remove');
set(rem_group_btn, 'Callback', 'e.remove_aggregate');
jList = java.util.ArrayList;
%% set Tags
set(subj_pop, 'Tag', ['subj_pop.' plotwindow_id]);
set(sess_pop, 'Tag', ['sess_pop.' plotwindow_id]);
set(trial_pop, 'Tag', ['trial_pop.' plotwindow_id]);
%% list aggregates
agg_strings={};
for i = 1:length(e.aggregates)
add_strings{i,1} = 1;
color_str = ['#' sprintf('%02s', dec2hex(e.aggregates(i).color(1)*255)) ...
sprintf('%02s', dec2hex(e.aggregates(i).color(2)*255)) ...
sprintf('%02s', dec2hex(e.aggregates(i).color(3)*255))];
agg_strings{i,2} = ['<html><li color=' color_str '><font color=#000000>'...
e.aggregates(i).name{1} ...
'</font></li></html>'];
%agg_strings{i,3} = e.aggregates(i).error.name;
end
cheaders = {'', 'Name', 'Error'};
cformats = {'logical' ,'char', {'None', 'Std', 'Var'}};
editable = [true false true],
table = uitable('Position', [10 215 150 125], ...
'Data', agg_strings, ...
'ColumnName', cheaders, ...
'ColumnFormat', cformats, ...
'ColumnWidth', {20 'auto' 65},...
'ColumnEditable', editable, ...
'RowName',[]);
%set(table, 'ButtonDownFcn', 'e.select_aggregate');
set(table, 'CellSelectionCallback', @e.select_aggregate);
set(table, 'ButtonDownFcn', @e.button_down_on_aggregate);
set(table, 'Tag', 'aggragate_table');

View File

@ -0,0 +1,104 @@
function[e] = calculate_aggregate(e, index);
%
% Extract aggregated data based on parameters / selection of
% subjects/sessions/trials
%
aggregate = e.aggregates(index);
try
tmp = aggregate.trials;
aggregate.trials = str2num(aggregate.trials);
if (isempty(aggregate.trials))
aggregate.trials = tmp;
end
catch
end
%% rewrite all subjects to list of subjects...
if strcmp(aggregate.subjects, 'All subjects')
e.aggregates(index).subjects = 1:length(e.subjects);
end
if strcmp(aggregate.sessions, 'All sessions')
e.aggregates(index).sessions = 1:length(e.subjects(1).sessions);
end
aggregate = e.aggregates(index);
stimulus_onsets = {};
idx =1;
for sub = 1:length(aggregate.subjects)
subject_id = aggregate.subjects(sub);
for sess = 1:length(aggregate.sessions)
sess_id = aggregate.sessions(sess);
%trial_query = aggregate.trials;
trials = aggregate.trials{subject_id}{sess_id};
%aggregate.e.get_trials_based_on_label(e.subjects(subject_id).sessions(sess_id), trial_query);
for t = 1:length(trials)
trial_id = trials(t);
trial_list(idx) = e.subjects(subject_id).sessions(sess_id).trials(trial_id).data;
stimulus_onsets{idx} = e.subjects(subject_id).sessions(sess_id).trials(trial_id).stimulus_onset - ...
e.subjects(subject_id).sessions(sess_id).trials(trial_id).trial_start;
idx = idx + 1;
end
end
end
if isempty(find(~cellfun(@isempty,stimulus_onsets)));
display('return?');
return;
end
min_onset = min([stimulus_onsets{:}]);
max_onset = min([stimulus_onsets{:}]);
diffs = [stimulus_onsets{:}] - min_onset;
max_diff = max(diffs);
clear trials
for t = 1:length(trial_list)
try
trials{t} = [ nan(1,max_diff - diffs(t)) trial_list(t).baseline_corrected.filtered(diffs(t)+1:end-max_diff)' ];
catch
display('error');
end
end
min_trial_length = min(cellfun(@length, trials));
for t = 1:length(trial_list)
try
trial_mat(t,:) = trials{t}(1:min_trial_length);
catch
end
end
mean_trial = mean(trial_mat);
std_trial = std(trial_mat);
var_trial = var(trial_mat);
l = length(mean_trial);
mean_trial([1:e.settings.FilterSize end-e.settings.FilterSize:end]) = NaN;
std_trial([1:e.settings.FilterSize end-e.settings.FilterSize:end]) = NaN;
var_trial([1:e.settings.FilterSize end-e.settings.FilterSize:end]) = NaN;
aggregate.mean = mean_trial;
aggregate.std = std_trial;
aggregate.var = var_trial;
e.aggregates(index).data = aggregate;

View File

@ -0,0 +1,7 @@
function[e] = calculate_aggregates(e)
for a = 1:length(e.aggregates)
display(sprintf('calculating aggregate %d...', a));
e = e.calculate_aggregate(a);
end

View File

@ -0,0 +1,6 @@
function[obj] = consolidateSettings(obj);
for s = 1:length(obj.subjects)
obj.subjects(s) = obj.subjects(s).setSettings(obj.settings);
end

View File

@ -0,0 +1,51 @@
function[e] = enable_selection_edit(e, type)
fig = gcf;%e.handle(2);
plotwindow_id = num2str(fig);
figure(fig);
if strcmp(type,'subject'), code = 'subj'; end
if strcmp(type,'session'), code = 'sess'; end
if strcmp(type,'trial'), code = 'trial'; end
% Only continue if selection edit is requested:
popup = findobj('Tag', [code '_pop.' plotwindow_id]);
select_edit = findobj('Tag', ['selection_edit.' type '.' plotwindow_id]);
if ~(get(popup,'Value') == 2)
uicontrol(popup);
set(select_edit, 'Visible', 'off');
return
end
tmp = get(fig, 'UserData');
select_edit = findobj('Tag', ['selection_edit.' type '.' plotwindow_id]);
string = '';
if ~isempty(tmp)
switch type
case 'subject'
if isfield(tmp, 'selected_subjects')
string = num2str(tmp.selected_subjects);
end
case 'session'
if isfield(tmp, 'selected_sessions')
string = num2str(tmp.selected_sessions);
end
case 'trial'
if isfield(tmp, 'selected_trials')
string = num2str(tmp.selected_trials);
end
end
set(select_edit, 'String', string);
set(select_edit, 'Callback', ['e.evaluate_selection(''' type ''')']);
set(select_edit, 'UserData', type);
else
end
set(fig, 'UserData', tmp);
set(select_edit, 'Visible', 'on');
set(select_edit, 'Enable', 'on');
uicontrol(select_edit);

View File

@ -0,0 +1,69 @@
function[] = evaluate_selection(e, type)
if strcmp(type,'subject'), code = 'subj'; end
if strcmp(type,'session'), code = 'sess'; end
if strcmp(type,'trial'), code = 'trial'; end
plotwindow = gcf;
plotwindow_id = num2str(plotwindow);
fig = gcf;
plotwindow_id = num2str(fig);
select_edit = findobj('Tag', ['selection_edit.' type '.' plotwindow_id]);
selection_cell = get(select_edit, 'String');
try
selection = eval(str2num(selection_cell));
catch
selection = str2num(selection_cell);
if ~isnumeric(selection)
msgbox('Could not parse entered data');
end
end
%fig = e.handle(2);
tmp = get(fig, 'UserData');
if (strcmp(type, 'subject'))
selection = intersect(selection, 1:length(e.subjects));
if isempty(selection)
display('Empty selection');
else
set(select_edit,'String', num2str(selection));
tmp.selected_subjects = selection;
end
end
if (strcmp(type, 'session'))
tmp.selected_sessions = selection;
end
if (strcmp(type, 'trial'))
tmp.selected_trials = selection;
end
set(fig, 'UserData', tmp);
%% Add the selection to the list and set the popup
popup = findobj('Tag', [code '_pop.' plotwindow_id]);
pop_string = get(popup,'String');
itemsize= size(pop_string);
new_item = num2str(selection);
newsize = max(length(new_item), itemsize(2));
pop_string(:,itemsize(2)+1:newsize) = ' ';
new_item(end+1:newsize)= ' ';
pop_string(itemsize(1)+1,:) = new_item;
[ui ui_ind] = unique(cellstr(pop_string));
set(popup, 'String', pop_string(sort(ui_ind),:));
set(popup, 'Value', length(ui_ind));
set(select_edit, 'Visible', 'off');
assignin('base','e',e);

View File

@ -0,0 +1,189 @@
function[data] = export_data(e, file_out, varargin)
% Export routine for the PDExperiment class:
%
% Exports a datatable with relevant properties and statistics
%
% Thresholding:
%
% Quality -> Thresholding.Quality = [0/1],
% Default Quality Threshold adopted from
% PDExperiment class, can be altered in
% extra parameter QualityThreshold
%
% Baseline -> Thresholding.Baseline = [0/1]
% Check whether baseline is within range
% BaselineThreshold specifies this setting
%
% BlinkCount -> Thresholding.BlinkCount = [0/1]
% Check whether BlinkCount is within range
% BlinkCountThreshold specifies this setting
%
% MissingLabels -> Thresholding.MissingLabels = [0/1]
% MissingLabels is an optional cell array
% to filter trials without those labels/fieldnames
%
% MatchingLabels -> Thresholding.Label = [0/1]
% MatchingLabels is an optional cell array
% to filter labels with a certain value
%
settings = struct('Delimiter', ',',...
'LineEndings', '\n',...
'Thresholding', struct('Quality', 0, ...
'Baseline', 0, ...
'BlinkCount', 0, ...
'MissingLabels',0,...
'Label',0), ...), ...
'QualityThreshold', e.settings.QualityThreshold, ...
'BaselineThreshold', [],...
'BlinkCountThreshold', Inf, ...
'MissingLabels', {},...
'MatchingLabels', {});
settings(1).QualityThreshold = e.settings.QualityThreshold;
settings = parse(settings, varargin);
max_typelength = -1; max_tl_ind = -1;
for i = 1:length(e.subjects(1).sessions(1).trials)
if max_typelength < length(fieldnames(e.subjects(1).sessions(1).trials(i).type))
max_tl_ind = i;
end
max_typelength = max(max_typelength, length(fieldnames(e.subjects(1).sessions(1).trials(i).type)));
end
types = fieldnames(e.subjects(1).sessions(1).trials(max_tl_ind).type);
type_header = '';format_type_header ='';
for t = 1:length(types)
type_header = [type_header types{t} sep '# of chars' sep];
format_type_header = [format_type_header str_f sep];
end
header = ['Subject' sep ...
'Datafile' sep ...
'Subject Id' sep ...
'Session' sep ...
'Trial' sep ...
'Quality (%)' sep ...
'BlinkCount' sep ...
type_header, ...
'Baseline (raw)' sep ...
'Max' sep ...
'TimeOfMax (rel to s.o.)' sep ...
'Mean' sep ...
'Median' sep ...
'Mode' sep ...
'Q1 (25%)' sep ...
'Q2 (median)' sep ...
'Q3 (75%)' sep ...
'AUC' le];
format = [str_f sep ... % subject
str_f sep ... % datafile
int_f sep ... % subject id
int_f sep ... % session
int_f sep ... % trial
dec_f sep ... % quality
int_f sep ... % blinkcount
'%s' ... % types are formatted within trial, so string with no formatting
dec_f sep ... % baseline
dec_f sep ... % max
dec_f sep ... % maxtime
dec_f sep ... % mean
dec_f sep ... % median
dec_f sep ... % mode
dec_f sep ... % q1
dec_f sep ... % q2
dec_f sep ... % q3
dec_f le]; % AUC
data = {};
for s = 1:length(e.subjects)
for sess = 1:length(e.subjects(s).sessions)
for t = 1:length(e.subjects(s).sessions(sess).trials)
trial = e.subjects(s).sessions(sess).trials(t);
%Continue with the next trial if thresholding is enabled and
%trial suffers quality
if ((settings.Thresholding.Quality) && (trial.quality < settings.QualityThreshold))
continue;
end
if ((settings.Thresholding.Quality) && (trial.quality < settings.QualityThreshold))
continue;
end
%% Baseline items can be skipped
if (strmatch(trial.type.TRIAL_VAR_stim, 'Baseline'))
continue;
end
tt_string = ''; % build string containg type identifiers
for tt = 1:length(types)
if isfield(trial.type,types{tt})
if ischar(trial.type.(types{tt}))
numchars = length(strtrim(trial.type.(types{tt})));
else
numchars = -1;
end
trial_type_value = trial.type.(types{tt});
tt_string = [tt_string ...
sprintf([str_f sep], strrep(trial_type_value(1,:),'"', '')) ...
sprintf([int_f sep], numchars)];
else
tt_string = [tt_string ...
sprintf([str_f sep], ''), ...
sprintf([int_f sep], numchars)];
end
end
if ~isempty(trial.stats)
fprintf(fp, format, ...
e.subjects(s).name, ...
e.subjects(s).sessions(sess).datafile, ...
s, ...
sess, ...
t, ...
trial.quality, ...
trial.blink_count, ...
tt_string, ...
trial.baseline, ...
trial.stats.max.value, ...
trial.stats.max.time, ...
trial.stats.mean, ...
trial.stats.median, ...
trial.stats.mode, ...
trial.stats.q1, ...
trial.stats.q2, ...
trial.stats.q3, ...
trial.stats.auc);
end
end
end
end
fclose(fp);
display(sprintf('\t*) Statistics written to %s', file_out));
function[settings] = parse(settings,varlist);
if length(varlist)<2;return;end
f=fieldnames(settings);
for k=2:2:length(varlist);
if ~any(strcmp(varlist{k-1},f));
error(sprintf('invalid field %s\n',varlist{k-1}));
end
if isstruct(varlist{k})
substructfields = fieldnames(varlist{k});
for sf = 1:length(substructfields)
settings(1).(varlist{k-1}).(substructfields{sf}) = varlist{k}.(substructfields{sf});
end
else
settings=setfield(settings,varlist{k-1},varlist{k});
end
end

View File

@ -0,0 +1,224 @@
function[] = export_stats(e, file_out, varargin)
% Export routine for the PDExperiment class:
%
% Writes a textfile with relevant properties and statistics
% Options: Delimiter -> ','
%
% Thresholding:
%
% Quality -> Thresholding.Quality = [0/1],
% Default Quality Threshold adopted from
% PDExperiment class, can be altered in
% extra parameter QualityThreshold
%
% Baseline -> Thresholding.Baseline = [0/1]
% Check whether baseline is within range
% BaselineThreshold specifies this setting
%
% BlinkCount -> Thresholding.BlinkCount = [0/1]
% Check whether BlinkCount is within range
% BlinkCountThreshold specifies this setting
%
% MissingLabels -> Thresholding.MissingLabels = [0/1]
% MissingLabels is an optional cell array
% to filter trials without those labels/fieldnames
%
% MatchingLabels -> Thresholding.Label = [0/1]
% MatchingLabels is an optional cell array
% to filter labels with a certain value
%
settings = struct('Delimiter', ',',...
'LineEndings', '\n',...
'Thresholding', struct('Quality', 0, ...
'Baseline', 0, ...
'BlinkCount', 0, ...
'MissingLabels',0,...
'Label',0), ...), ...
'QualityThreshold', e.settings.QualityThreshold, ...
'BaselineThreshold', [],...
'BlinkCountThreshold', Inf, ...
'MissingLabels', {},...
'MatchingLabels', {});
settings(1).QualityThreshold = e.settings.QualityThreshold;
settings(1).Delimiter = ',';
settings(1).LineEndings = '\n';
settings = parse(settings, varargin);
fp = fopen(file_out, 'w+');
fprintf(fp,'%s\\n', repmat('-',1,100));
fprintf(fp,'\tExport on:\t %s\n', datestr(now));
%sprintf('\tPDParser version:\t%s\n', num2str(e.version));
sep = settings.Delimiter; % separator
le = settings.LineEndings; %'\n'; % line ending
int_f = '%d'; % integer format
dec_f = '%8.4f'; % decimal format
str_f = '"%s"'; %string format
max_typelength = -1; max_tl_ind = -1;
for i = 1:length(e.subjects(1).sessions(1).trials)
if max_typelength < length(fieldnames(e.subjects(1).sessions(1).trials(i).type))
max_tl_ind = i;
end
max_typelength = max(max_typelength, length(fieldnames(e.subjects(1).sessions(1).trials(i).type)));
end
types = fieldnames(e.subjects(1).sessions(1).trials(max_tl_ind).type);
type_header = '';format_type_header ='';
for t = 1:length(types)
type_header = [type_header types{t} sep '# of chars' sep];
format_type_header = [format_type_header str_f sep];
end
cov_header = []; cov_format = [];
for i =1:length(e.subjects(1).covariates)
cov_header = [cov_header sprintf('Covariate%d', i) sep];
cov_format = [cov_format int_f sep];
end
header = ['Subject' sep ...
cov_header ...
'Datafile' sep ...
'Subject Id' sep ...
'Session' sep ...
'Trial' sep ...
'Quality (%)' sep ...
'BlinkCount' sep ...
type_header, ...
'Baseline (raw)' sep ...
'Max' sep ...
'TimeOfMax (rel to s.o.)' sep ...
'Mean' sep ...
'Median' sep ...
'Mode' sep ...
'Q1 (25%)' sep ...
'Q2 (median)' sep ...
'Q3 (75%)' sep ...
'AUC' ];
format = [str_f sep ... % subject
'%s' ... % covariates
str_f sep ... % datafile
int_f sep ... % subject id
int_f sep ... % session
int_f sep ... % trial
dec_f sep ... % quality
int_f sep ... % blinkcount
'%s' ... % types are formatted within trial, so string with no formatting
dec_f sep ... % baseline
dec_f sep ... % max
dec_f sep ... % maxtime
dec_f sep ... % mean
dec_f sep ... % median
dec_f sep ... % mode
dec_f sep ... % q1
dec_f sep ... % q2
dec_f sep ... % q3
dec_f le]; % AUC
fprintf(fp,'%s\n', repmat('-',1,100));
fprintf(fp, '%s', header);
fprintf(fp, '\n');
for s = 1:length(e.subjects)
covariates = [];
for cov =1:length(e.subjects(1).covariates)
covariates = [covariates sprintf([dec_f sep], e.subjects(s).covariates(cov))];
end
for sess = 1:length(e.subjects(s).sessions)
for t = 1:length(e.subjects(s).sessions(sess).trials)
trial = e.subjects(s).sessions(sess).trials(t);
%Continue with the next trial if thresholding is enabled and
%trial suffers quality
if ((~isempty(settings.Thresholding)) && (settings.Thresholding.Quality) && (trial.quality < settings.QualityThreshold))
continue;
end
if ((~isempty(settings.Thresholding)) && (settings.Thresholding.Quality) && (trial.quality < settings.QualityThreshold))
continue;
end
%% Baseline items can be skipped
if (strmatch(trial.type.TRIAL_VAR_stim, 'Baseline'))
continue;
end
tt_string = ''; % build string containg type identifiers
for tt = 1:length(types)
if isfield(trial.type,types{tt})
if ischar(trial.type.(types{tt}))
numchars = length(strtrim(trial.type.(types{tt})));
else
numchars = -1;
end
trial_type_value = trial.type.(types{tt});
tt_string = [tt_string ...
sprintf([str_f sep], strrep(trial_type_value(1,:),'"', '')) ...
sprintf([int_f sep], numchars)];
else
tt_string = [tt_string ...
sprintf([str_f sep], ''), ...
sprintf([int_f sep], numchars)];
end
end
if ~isempty(trial.stats)
fprintf(fp, format, ...
e.subjects(s).name, ...
covariates,...
e.subjects(s).sessions(sess).datafile, ...
s, ...
sess, ...
t, ...
trial.quality, ...
trial.blink_count, ...
tt_string, ...
trial.baseline, ...
trial.stats.max.value, ...
trial.stats.max.time, ...
trial.stats.mean, ...
trial.stats.median, ...
trial.stats.mode, ...
trial.stats.q1, ...
trial.stats.q2, ...
trial.stats.q3, ...
trial.stats.auc);
end
end
end
end
fclose(fp);
display(sprintf('\t*) Statistics written to %s', file_out));
function[settings] = parse(settings,varlist);
if length(varlist)<2;return;end
f=fieldnames(settings);
for k=2:2:length(varlist);
if ~any(strcmp(varlist{k-1},f));
error(sprintf('invalid field %s\n',varlist{k-1}));
end
if isstruct(varlist{k})
substructfields = fieldnames(varlist{k});
for sf = 1:length(substructfields)
settings(1).(varlist{k-1}).(substructfields{sf}) = varlist{k}.(substructfields{sf});
end
else
settings=setfield(settings,varlist{k-1},varlist{k});
end
end

View File

@ -0,0 +1,18 @@
function[list_out] = getIndexFromSubjectName(e, list_in)
list_out = [];
for s = 1:length(list_in)
found = 0; index =1;
while ~found
if ~isempty(strmatch(e.subjects(index).name, sprintf('Subject %d', list_in(s)), 'exact'))
found = 1;
list_out = [list_out index];
end
index = index +1;
if index > length(e.subjects)
break;
end
end
end

View File

@ -0,0 +1,7 @@
function[mat time] = get_aggregate_data(exp, index)
%
% return matrix of trials for aggregate,
% i.e. a reverse lookup of all trials which are used for the aggregate
%
% this function is used in statistics for permutation

View File

@ -0,0 +1,38 @@
function[trial_list] = get_trials_based_on_label(e, session, trial_query)
trial_list = [];
if strcmp(trial_query, 'All trials')
trial_list= 1:length(session.trials);
return
end
if ~isempty(trial_query)
label_list = {};
match_list = {};
ind=1;
for t = 1:length(session.trials)
for l = 1:length(session.trials(t).labels)
label_list{ind} = session.trials(t).labels(l).label;
match_list{ind} = session.trials(t).labels(l).match;
trial_ids(ind) = t;
ind=ind+1;
end
end
m_m = regexp(trial_query, match_list);
m_l = regexp(trial_query, label_list);
matches = find(~cellfun(@isempty,m_l));
labels = find(~cellfun(@isempty,m_l));
trial_list = sort([matches, labels]);
end

View File

@ -0,0 +1,22 @@
function[text] = info(obj)
text{1} = sprintf('Information on PD Experiment: %s\n', obj.name);
text{2} = repmat('-', 1, 100);
text{3} = sprintf('Contains %2d subjects', length(obj.subjects));
for s = 1:length(obj.subjects)
subj = obj.subjects(s);
text{end+1} = sprintf('\t*) Subject %d : %d sessions', s, length(subj.sessions));
for sess = 1:length(subj.sessions);
session = subj.sessions(sess);
text{end+1} = sprintf('\t\t*) Session %d : ', s);
text{end+1} = sprintf('\t\t\to) - %d trials', length(session.trials));
text{end+1} = sprintf('\t\t\to) - filename : %s', session.datafile);
end
end
if nargin == 0
display(text)
end

View File

@ -0,0 +1,141 @@
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 2 blinks filtered ( 8 missing data events); quality : 83 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 0 blinks filtered ( 6 missing data events); quality : 86 percent
*) 0 blinks filtered ( 1 missing data events); quality : 95 percent
*) 0 blinks filtered ( 3 missing data events); quality : 90 percent
*) 0 blinks filtered ( 3 missing data events); quality : 89 percent
*) 0 blinks filtered ( 5 missing data events); quality : 88 percent
*) 2 blinks filtered ( 5 missing data events); quality : 87 percent
*) 0 blinks filtered ( 4 missing data events); quality : 90 percent
*) 0 blinks filtered ( 3 missing data events); quality : 90 percent
*) 1 blinks filtered ( 5 missing data events); quality : 69 percent
*) 2 blinks filtered ( 8 missing data events); quality : 83 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 3 blinks filtered ( 6 missing data events); quality : 82 percent
*) 0 blinks filtered ( 3 missing data events); quality : 89 percent
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 1 blinks filtered ( 4 missing data events); quality : 92 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 1 blinks filtered ( 5 missing data events); quality : 83 percent
*) 1 blinks filtered ( 3 missing data events); quality : 93 percent
*) 0 blinks filtered ( 3 missing data events); quality : 89 percent
*) 2 blinks filtered ( 5 missing data events); quality : 81 percent
*) 0 blinks filtered ( 3 missing data events); quality : 85 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 1 blinks filtered ( 5 missing data events); quality : 84 percent
*) 0 blinks filtered ( 3 missing data events); quality : 86 percent
*) 0 blinks filtered ( 3 missing data events); quality : 84 percent
*) 1 blinks filtered ( 3 missing data events); quality : 55 percent
*) 0 blinks filtered ( 3 missing data events); quality : 88 percent
*) 0 blinks filtered ( 5 missing data events); quality : 76 percent
*) 0 blinks filtered ( 3 missing data events); quality : 76 percent
*) 0 blinks filtered ( 3 missing data events); quality : 83 percent
*) 0 blinks filtered ( 3 missing data events); quality : 88 percent
*) 0 blinks filtered ( 2 missing data events); quality : 91 percent
*) 1 blinks filtered ( 5 missing data events); quality : 78 percent
*) 0 blinks filtered ( 4 missing data events); quality : 78 percent
*) 0 blinks filtered ( 3 missing data events); quality : 89 percent
*) 1 blinks filtered ( 3 missing data events); quality : 91 percent
*) 0 blinks filtered ( 4 missing data events); quality : 88 percent
*) 0 blinks filtered ( 3 missing data events); quality : 84 percent
*) 1 blinks filtered ( 4 missing data events); quality : 60 percent
*) 0 blinks filtered ( 2 missing data events); quality : 79 percent
*) 1 blinks filtered ( 2 missing data events); quality : 91 percent
*) 1 blinks filtered ( 4 missing data events); quality : 81 percent
*) 2 blinks filtered ( 4 missing data events); quality : 83 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 1 blinks filtered ( 5 missing data events); quality : 86 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 1 blinks filtered ( 5 missing data events); quality : 79 percent
*) 2 blinks filtered ( 5 missing data events); quality : 63 percent
*) 0 blinks filtered ( 3 missing data events); quality : 84 percent
*) 1 blinks filtered ( 2 missing data events); quality : 91 percent
*) 1 blinks filtered ( 6 missing data events); quality : 82 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 2 blinks filtered ( 3 missing data events); quality : 91 percent
*) 1 blinks filtered ( 5 missing data events); quality : 85 percent
*) 2 blinks filtered ( 4 missing data events); quality : 87 percent
*) 0 blinks filtered ( 2 missing data events); quality : 90 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 1 missing data events); quality : 96 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 1 blinks filtered ( 3 missing data events); quality : 90 percent
*) 1 blinks filtered ( 2 missing data events); quality : 82 percent
*) 0 blinks filtered ( 2 missing data events); quality : 89 percent
*) 2 blinks filtered ( 5 missing data events); quality : 79 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 3 missing data events); quality : 92 percent
*) 0 blinks filtered ( 4 missing data events); quality : 84 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 2 missing data events); quality : 92 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 1 missing data events); quality : 94 percent
*) 0 blinks filtered ( 3 missing data events); quality : 85 percent
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 0 blinks filtered ( 2 missing data events); quality : 93 percent
*) 0 blinks filtered ( 3 missing data events); quality : 90 percent
*) 2 blinks filtered ( 3 missing data events); quality : 91 percent
*) 0 blinks filtered ( 2 missing data events); quality : 91 percent
*) 0 blinks filtered ( 2 missing data events); quality : 81 percent
*) 1 blinks filtered ( 4 missing data events); quality : 87 percent
*) 1 blinks filtered ( 4 missing data events); quality : 72 percent
*) 2 blinks filtered ( 5 missing data events); quality : 80 percent
*) 0 blinks filtered ( 3 missing data events); quality : 91 percent
*) 0 blinks filtered ( 1 missing data events); quality : 93 percent
*) 1 blinks filtered ( 5 missing data events); quality : 84 percent
*) 0 blinks filtered ( 3 missing data events); quality : 88 percent
*) 0 blinks filtered ( 1 missing data events); quality : 93 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 96 percent
*) 1 blinks filtered ( 1 missing data events); quality : 88 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 96 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 95 percent
*) 0 blinks filtered ( 3 missing data events); quality : 95 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 2 blinks filtered ( 3 missing data events); quality : 94 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 0 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 1 blinks filtered ( 1 missing data events); quality : 96 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 96 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 100 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 96 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 2 missing data events); quality : 94 percent
*) 1 blinks filtered ( 4 missing data events); quality : 85 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 100 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 0 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 97 percent
*) 0 blinks filtered ( 0 missing data events); quality : 97 percent

View File

@ -0,0 +1,802 @@
function cancel = multiWaitbar( label, varargin )
%multiWaitbar: add, remove or update an entry on the multi waitbar
%
% multiWaitbar(LABEL,VALUE) adds a waitbar for the specified label, or
% if it already exists updates the value. LABEL must be a string and
% VALUE a number between zero and one or the string 'Close' to remove the
% entry Setting value equal to 0 or 'Reset' will cause the progress bar
% to reset and the time estimate to be re-initialized.
%
% multiWaitbar(LABEL,COMMAND,VALUE,...) or
% multiWaitbar(LABEL,VALUE,COMMAND,VALUE,...)
% passes one or more command/value pairs for changing the named waitbar
% entry. Possible commands include:
% 'Value' Set the value of the named waitbar entry. The
% corresponding value must be a number between 0 and 1.
% 'Increment' Increment the value of the named waitbar entry. The
% corresponding value must be a number between 0 and 1.
% 'Color' Change the color of the named waitbar entry. The
% value must be an RGB triple, e.g. [0.1 0.2 0.3], or a
% single-character color name, e.g. 'r', 'b', 'm'.
% 'Relabel' Change the label of the named waitbar entry. The
% value must be the new name.
% 'Reset' Set the named waitbar entry back to zero and reset its
% timer. No value need be specified.
% 'CanCancel' [on|off] should a "cancel" button be shown for this bar
% (default 'off').
% 'CancelFcn' Function to call in the event that the user cancels.
% 'ResetCancel' Reset the "cancelled" flag for an entry (ie. if you
% decide not to cancel).
% 'Close' Remove the named waitbar entry.
% 'Busy' Puts this waitbar in "busy mode" where a small bar
% bounces back and forth. Return to normal progress display
% using the 'Reset' command.
%
% cancel = multiWaitbar(LABEL,VALUE) also returns whether the user has
% clicked the "cancel" button for this entry (true or false). Two
% mechanisms are provided for cancelling an entry if the 'CanCancel'
% setting is 'on'. The first is just to check the return argument and if
% it is true abort the task. The second is to set a 'CancelFcn' that is
% called when the user clicks the cancel button, much as is done for
% MATLAB's built-in WAITBAR. In either case, you can use the
% 'ResetCancel' command if you don't want to cancel after all.
%
% multiWaitbar('CLOSEALL') closes the waitbar window.
%
% Example:
% multiWaitbar( 'CloseAll' );
% multiWaitbar( 'Task 1', 0 );
% multiWaitbar( 'Task 2', 0.5, 'Color', 'b' );
% multiWaitbar( 'Task 3', 'Busy');
% multiWaitbar( 'Task 1', 'Value', 0.1 );
% multiWaitbar( 'Task 2', 'Increment', 0.2 );
% multiWaitbar( 'Task 3', 'Reset' ); % Disables "busy" mode
% multiWaitbar( 'Task 3', 'Value', 0.3 );
% multiWaitbar( 'Task 2', 'Close' );
% multiWaitbar( 'Task 3', 'Close' );
% multiWaitbar( 'Task 1', 'Close' );
%
% Example:
% multiWaitbar( 'Task 1', 0, 'CancelFcn', @(a,b) disp( ['Cancel ',a] ) );
% for ii=1:100
% abort = multiWaitbar( 'Task 1', ii/100 );
% if abort
% % Here we would normally ask the user if they're sure
% break
% else
% pause( 1 )
% end
% end
% multiWaitbar( 'Task 1', 'Close' )
%
% Example:
% multiWaitbar( 'CloseAll' );
% multiWaitbar( 'Red...', 7/7, 'Color', [0.8 0.0 0.1] );
% multiWaitbar( 'Orange...', 6/7, 'Color', [1.0 0.4 0.0] );
% multiWaitbar( 'Yellow...', 5/7, 'Color', [0.9 0.8 0.2] );
% multiWaitbar( 'Green...', 4/7, 'Color', [0.2 0.9 0.3] );
% multiWaitbar( 'Blue...', 3/7, 'Color', [0.1 0.5 0.8] );
% multiWaitbar( 'Indigo...', 2/7, 'Color', [0.4 0.1 0.5] );
% multiWaitbar( 'Violet...', 1/7, 'Color', [0.8 0.4 0.9] );
%
% Thanks to Jesse Hopkins for suggesting the "busy" mode.
% Author: Ben Tordoff
% Copyright 2007-2014 The MathWorks, Inc.
persistent FIGH;
cancel = false;
% Check basic inputs
error( nargchk( 1, inf, nargin ) ); %#ok<NCHKN> - kept for backwards compatibility
if ~ischar( label )
error( 'multiWaitbar:BadArg', 'LABEL must be the name of the progress entry (i.e. a string)' );
end
% Try to get hold of the figure
if isempty( FIGH ) || ~ishandle( FIGH )
FIGH = findall( 0, 'Type', 'figure', 'Tag', 'multiWaitbar:Figure' );
if isempty(FIGH)
FIGH = iCreateFig();
else
FIGH = handle( FIGH(1) );
end
end
% Check for close all and stop early
if any( strcmpi( label, {'CLOSEALL','CLOSE ALL'} ) )
iDeleteFigure(FIGH);
return;
end
% Make sure we're on-screen
if ~strcmpi( FIGH.Visible, 'on' )
FIGH.Visible = 'on';
end
% Get the list of entries and see if this one already exists
entries = getappdata( FIGH, 'ProgressEntries' );
if isempty(entries)
idx = [];
else
idx = find( strcmp( label, {entries.Label} ), 1, 'first' );
end
bgcol = getappdata( FIGH, 'DefaultProgressBarBackgroundColor' );
% If it doesn't exist, create it
needs_redraw = false;
entry_added = isempty(idx);
if entry_added
% Create a new entry
defbarcolor = getappdata( FIGH, 'DefaultProgressBarColor' );
entries = iAddEntry( FIGH, entries, label, 0, defbarcolor, bgcol );
idx = numel( entries );
end
% Check if the user requested a cancel
if nargout
cancel = entries(idx).Cancel;
end
% Parse the inputs. We shortcut the most common case as an efficiency
force_update = false;
if nargin==2 && isnumeric( varargin{1} )
entries(idx).LastValue = entries(idx).Value;
entries(idx).Value = max( 0, min( 1, varargin{1} ) );
entries(idx).Busy = false;
needs_update = true;
else
[params,values] = iParseInputs( varargin{:} );
needs_update = false;
for ii=1:numel( params )
switch upper( params{ii} )
case 'BUSY'
entries(idx).Busy = true;
needs_update = true;
case 'VALUE'
entries(idx).LastValue = entries(idx).Value;
entries(idx).Value = max( 0, min( 1, values{ii} ) );
entries(idx).Busy = false;
needs_update = true;
case {'INC','INCREMENT'}
entries(idx).LastValue = entries(idx).Value;
entries(idx).Value = max( 0, min( 1, entries(idx).Value + values{ii} ) );
entries(idx).Busy = false;
needs_update = true;
case {'COLOR','COLOUR'}
entries(idx).CData = iMakeColors( values{ii}, 16 );
needs_update = true;
force_update = true;
case {'RELABEL', 'UPDATELABEL'}
% Make sure we have a string as the value and that it
% doesn't already appear
if ~ischar( values{ii} )
error( 'multiWaitbar:BadString', 'Value for ''Relabel'' must be a string.' );
end
if ismember( values{ii}, {entries.Label} )
error( 'multiWaitbar:NameAlreadyExists', 'Cannot relabel an entry to a label that already exists.' );
end
entries(idx).Label = values{ii};
needs_update = true;
force_update = true;
case {'CANCANCEL'}
if ~ischar( values{ii} ) || ~any( strcmpi( values{ii}, {'on','off'} ) )
error( 'multiWaitbar:BadString', 'Parameter ''CanCancel'' must be a ''on'' or ''off''.' );
end
entries(idx).CanCancel = strcmpi( values{ii}, 'on' );
entries(idx).Cancel = false;
needs_redraw = true;
case {'RESETCANCEL'}
entries(idx).Cancel = false;
needs_redraw = true;
case {'CANCELFCN'}
if ~isa( values{ii}, 'function_handle' )
error( 'multiWaitbar:BadFunction', 'Parameter ''CancelFcn'' must be a valid function handle.' );
end
entries(idx).CancelFcn = values{ii};
if ~entries(idx).CanCancel
entries(idx).CanCancel = true;
end
needs_redraw = true;
case {'CLOSE','DONE'}
if ~isempty(idx)
% Remove the selected entry
entries = iDeleteEntry( entries, idx );
end
if isempty( entries )
iDeleteFigure( FIGH );
% With the window closed, there's nothing else to do
return;
else
needs_redraw = true;
end
% We can't continue after clearing the entry, so jump out
break;
otherwise
error( 'multiWaitbar:BadArg', 'Unrecognized command: ''%s''', params{ii} );
end
end
end
% Now work out what to update/redraw
if needs_redraw
setappdata( FIGH, 'ProgressEntries', entries );
iRedraw( FIGH );
% NB: Redraw includes updating all bars, so never need to do both
elseif needs_update
[entries(idx),needs_redraw] = iUpdateEntry( entries(idx), force_update );
setappdata( FIGH, 'ProgressEntries', entries );
% NB: if anything was updated onscreen, "needs_redraw" is now true.
end
if entry_added || needs_redraw
% If the shape or size has changed, do a full redraw, including events
drawnow();
end
% If we have any "busy" entries, start the timer, otherwise stop it.
myTimer = getappdata( FIGH, 'BusyTimer' );
if any([entries.Busy])
if strcmpi(myTimer.Running,'off')
start(myTimer);
end
else
if strcmpi(myTimer.Running,'on')
stop(myTimer);
end
end
end % multiWaitbar
%-------------------------------------------------------------------------%
function [params, values] = iParseInputs( varargin )
% Parse the input arguments, extracting a list of commands and values
idx = 1;
params = {};
values = {};
if nargin==0
return;
end
if isnumeric( varargin{1} )
params{idx} = 'Value';
values{idx} = varargin{1};
idx = idx + 1;
end
while idx <= nargin
param = varargin{idx};
if ~ischar( param )
error( 'multiWaitbar:BadSyntax', 'Additional properties must be supplied as property-value pairs' );
end
params{end+1,1} = param; %#ok<AGROW>
values{end+1,1} = []; %#ok<AGROW>
switch upper( param )
case {'DONE','CLOSE','RESETCANCEL'}
% No value needed, and stop
break;
case {'BUSY'}
% No value needed but parsing should continue
idx = idx + 1;
case {'RESET','ZERO','SHOW'}
% All equivalent to saying ('Value', 0)
params{end} = 'Value';
values{end} = 0;
idx = idx + 1;
otherwise
if idx==nargin
error( 'multiWaitbar:BadSyntax', 'Additional properties must be supplied as property-value pairs' );
end
values{end,1} = varargin{idx+1};
idx = idx + 2;
end
end
if isempty( params )
error( 'multiWaitbar:BadSyntax', 'Must specify a value or a command' );
end
end % iParseInputs
%-------------------------------------------------------------------------%
function fobj = iCreateFig()
% Create the progress bar group window
bgcol = get(0,'DefaultUIControlBackgroundColor');
f = figure( ...
'Name', 'Progress', ...
'Tag', 'multiWaitbar:Figure', ...
'Color', bgcol, ...
'MenuBar', 'none', ...
'ToolBar', 'none', ...
'WindowStyle', 'normal', ... % We don't want to be docked!
'HandleVisibility', 'off', ...
'IntegerHandle', 'off', ...
'Visible', 'off', ...
'NumberTitle', 'off' );
% Resize and centre on the first screen
screenSize = get(0,'ScreenSize');
figSz = [360 42];
figPos = ceil((screenSize(1,3:4)-figSz)/2);
fobj = handle( f );
fobj.Position = [figPos, figSz];
setappdata( fobj, 'ProgressEntries', [] );
% Make sure we have the image
defbarcolor = [0.8 0.0 0.1];
barbgcol = uint8( 255*0.75*bgcol );
setappdata( fobj, 'DefaultProgressBarBackgroundColor', barbgcol );
setappdata( fobj, 'DefaultProgressBarColor', defbarcolor );
setappdata( fobj, 'DefaultProgressBarSize', [350 16] );
% Create the timer to use for "Busy" mode, being sure to delete any
% existing ones
delete( timerfind('Tag', 'MultiWaitbarTimer') );
myTimer = timer( ...
'TimerFcn', @(src,evt) iTimerFcn(f), ...
'Period', 0.02, ...
'ExecutionMode', 'FixedRate', ...
'Tag', 'MultiWaitbarTimer' );
setappdata( fobj, 'BusyTimer', myTimer );
% Setup the resize function after we've finished setting up the figure to
% avoid excessive redraws
fobj.ResizeFcn = @iRedraw;
fobj.CloseRequestFcn = @iCloseFigure;
end % iCreateFig
%-------------------------------------------------------------------------%
function cdata = iMakeColors( baseColor, height )
% Creates a shiny bar from a single base color
lightColor = [1 1 1];
badColorErrorID = 'multiWaitbar:BadColor';
badColorErrorMsg = 'Colors must be a three element vector [R G B] or a single character (''r'', ''g'' etc.)';
if ischar(baseColor)
switch upper(baseColor)
case 'K'
baseColor = [0.1 0.1 0.1];
case 'R'
baseColor = [0.8 0 0];
case 'G'
baseColor = [0 0.6 0];
case 'B'
baseColor = [0 0 0.8];
case 'C'
baseColor = [0.2 0.8 0.9];
case 'M'
baseColor = [0.6 0 0.6];
case 'Y'
baseColor = [0.9 0.8 0.2];
case 'W'
baseColor = [0.9 0.9 0.9];
otherwise
error( badColorErrorID, badColorErrorMsg );
end
else
if numel(baseColor) ~= 3
error( badColorErrorID, badColorErrorMsg );
end
if isa( baseColor, 'uint8' )
baseColor = double( baseColor ) / 255;
elseif isa( baseColor, 'double' )
if any(baseColor>1) || any(baseColor<0)
error( 'multiWaitbar:BadColorValue', 'Color values must be in the range 0 to 1 inclusive.' );
end
else
error( badColorErrorID, badColorErrorMsg );
end
end
% By this point we should have a double precision 3-element vector.
cols = repmat( baseColor, [height, 1] );
breaks = max( 1, round( height * [1 25 50 75 88 100] / 100 ) );
cols(breaks(1),:) = 0.6*baseColor;
cols(breaks(2),:) = lightColor - 0.4*(lightColor-baseColor);
cols(breaks(3),:) = baseColor;
cols(breaks(4),:) = min( baseColor*1.2, 1.0 );
cols(breaks(5),:) = min( baseColor*1.4, 0.95 ) + 0.05;
cols(breaks(6),:) = min( baseColor*1.6, 0.9 ) + 0.1;
y = 1:height;
cols(:,1) = max( 0, min( 1, interp1( breaks, cols(breaks,1), y, 'pchip' ) ) );
cols(:,2) = max( 0, min( 1, interp1( breaks, cols(breaks,2), y, 'pchip' ) ) );
cols(:,3) = max( 0, min( 1, interp1( breaks, cols(breaks,3), y, 'pchip' ) ) );
cdata = uint8( 255 * cat( 3, cols(:,1), cols(:,2), cols(:,3) ) );
end % iMakeColors
%-------------------------------------------------------------------------%
function cdata = iMakeBackground( baseColor, height )
% Creates a shaded background
if isa( baseColor, 'uint8' )
baseColor = double( baseColor ) / 255;
end
ratio = 1 - exp( -0.5-2*(1:height)/height )';
cdata = uint8( 255 * cat( 3, baseColor(1)*ratio, baseColor(2)*ratio, baseColor(3)*ratio ) );
end % iMakeBackground
%-------------------------------------------------------------------------%
function entries = iAddEntry( parent, entries, label, value, color, bgcolor )
% Add a new entry to the progress bar
% Create bar coloring
psize = getappdata( parent, 'DefaultProgressBarSize' );
cdata = iMakeColors( color, 16 );
% Create background image
barcdata = iMakeBackground( bgcolor, psize(2) );
% Work out the size in advance
labeltext = uicontrol( 'Style', 'Text', ...
'String', label, ...
'Parent', parent, ...
'HorizontalAlignment', 'Left' );
etatext = uicontrol( 'Style', 'Text', ...
'String', '', ...
'Parent', parent, ...
'HorizontalAlignment', 'Right' );
progresswidget = uicontrol( 'Style', 'Checkbox', ...
'String', '', ...
'Parent', parent, ...
'Position', [5 5 psize], ...
'CData', barcdata );
cancelwidget = uicontrol( 'Style', 'PushButton', ...
'String', '', ...
'FontWeight', 'Bold', ...
'Parent', parent, ...
'Position', [5 5 16 16], ...
'CData', iMakeCross( 8 ), ...
'Callback', @(src,evt) iCancelEntry( src, label ), ...
'Visible', 'off' );
mypanel = uipanel( 'Parent', parent, 'Units', 'Pixels' );
newentry = struct( ...
'Label', label, ...
'Value', value, ...
'LastValue', inf, ...
'Created', tic(), ...
'LabelText', labeltext, ...
'ETAText', etatext, ...
'ETAString', '', ...
'Progress', progresswidget, ...
'ProgressSize', psize, ...
'Panel', mypanel, ...
'BarCData', barcdata, ...
'CData', cdata, ...
'BackgroundCData', barcdata, ...
'CanCancel', false, ...
'CancelFcn', [], ...
'CancelButton', cancelwidget, ...
'Cancel', false, ...
'Busy', false );
if isempty( entries )
entries = newentry;
else
entries = [entries;newentry];
end
% Store in figure before the redraw
setappdata( parent, 'ProgressEntries', entries );
if strcmpi( get( parent, 'Visible' ), 'on' )
iRedraw( parent, [] );
else
set( parent, 'Visible', 'on' );
end
end % iAddEntry
%-------------------------------------------------------------------------%
function entries = iDeleteEntry( entries, idx )
delete( entries(idx).LabelText );
delete( entries(idx).ETAText );
delete( entries(idx).CancelButton );
delete( entries(idx).Progress );
delete( entries(idx).Panel );
entries(idx,:) = [];
end % iDeleteEntry
%-------------------------------------------------------------------------%
function entries = iCancelEntry( src, name )
figh = ancestor( src, 'figure' );
entries = getappdata( figh, 'ProgressEntries' );
if isempty(entries)
% The entries have been lost - nothing can be done.
return
end
idx = find( strcmp( name, {entries.Label} ), 1, 'first' );
% Set the cancel flag so that the user is told on next update
entries(idx).Cancel = true;
setappdata( figh, 'ProgressEntries', entries );
% If a user function is supplied, call it
if ~isempty( entries(idx).CancelFcn )
feval( entries(idx).CancelFcn, name, 'Cancelled' );
end
end % iCancelEntry
%-------------------------------------------------------------------------%
function [entry,updated] = iUpdateEntry( entry, force )
% Update one progress bar
% Deal with busy entries separately
if entry.Busy
entry = iUpdateBusyEntry(entry);
updated = true;
return;
end
% Some constants
marker_weight = 0.8;
% Check if the label needs updating
updated = force;
val = entry.Value;
lastval = entry.LastValue;
% Now update the bar
psize = entry.ProgressSize;
filled = max( 1, round( val*psize(1) ) );
lastfilled = max( 1, round( lastval*psize(1) ) );
% We do some careful checking so that we only redraw what we have to. This
% makes a small speed difference, but every little helps!
if force || (filled<lastfilled)
% Create the bar background
startIdx = 1;
bgim = entry.BackgroundCData(:,ones( 1, psize(1)-filled ),:);
barim = iMakeBarImage(entry.CData, startIdx, filled);
progresscdata = [barim,bgim];
% Add light/shadow around the markers
markers = round( (0.1:0.1:val)*psize(1) );
markers(markers<startIdx | markers>(filled-2)) = [];
highlight = [marker_weight*entry.CData, 255 - marker_weight*(255-entry.CData)];
for ii=1:numel( markers )
progresscdata(:,markers(ii)+[-1,0],:) = highlight;
end
% Set the image into the checkbox
entry.BarCData = progresscdata;
set( entry.Progress, 'cdata', progresscdata );
updated = true;
elseif filled > lastfilled
% Just need to update the existing data
progresscdata = entry.BarCData;
startIdx = max(1,lastfilled-1);
% Repmat is the obvious way to fill the bar, but BSXFUN is often
% faster. Indexing is obscure but faster still.
progresscdata(:,startIdx:filled,:) = iMakeBarImage(entry.CData, startIdx, filled);
% Add light/shadow around the markers
markers = round( (0.1:0.1:val)*psize(1) );
markers(markers<startIdx | markers>(filled-2)) = [];
highlight = [marker_weight*entry.CData, 255 - marker_weight*(255-entry.CData)];
for ii=1:numel( markers )
progresscdata(:,markers(ii)+[-1,0],:) = highlight;
end
entry.BarCData = progresscdata;
set( entry.Progress, 'CData', progresscdata );
updated = true;
end
% As an optimization, don't update any text if the bar didn't move and the
% percentage hasn't changed
decval = round( val*100 );
lastdecval = round( lastval*100 );
if ~updated && (decval == lastdecval)
return
end
% Now work out the remaining time
minTime = 3; % secs
if val <= 0
% Zero value, so clear the eta
entry.Created = tic();
elapsedtime = 0;
etaString = '';
else
elapsedtime = round(toc( entry.Created )); % in seconds
% Only show the remaining time if we've had time to estimate
if elapsedtime < minTime
% Not enough time has passed since starting, so leave blank
etaString = '';
else
% Calculate a rough ETA
eta = elapsedtime * (1-val) / val;
etaString = iGetTimeString( eta );
end
end
if ~isequal( etaString, entry.ETAString )
set( entry.ETAText, 'String', etaString );
entry.ETAString = etaString;
updated = true;
end
% Update the label too
if force || elapsedtime > minTime
if force || (decval ~= lastdecval)
labelstr = [entry.Label, sprintf( ' (%d%%)', decval )];
set( entry.LabelText, 'String', labelstr );
updated = true;
end
end
end % iUpdateEntry
function eta = iGetTimeString( remainingtime )
if remainingtime > 172800 % 2 days
eta = sprintf( '%d days', round(remainingtime/86400) );
else
if remainingtime > 7200 % 2 hours
eta = sprintf( '%d hours', round(remainingtime/3600) );
else
if remainingtime > 120 % 2 mins
eta = sprintf( '%d mins', round(remainingtime/60) );
else
% Seconds
remainingtime = round( remainingtime );
if remainingtime > 1
eta = sprintf( '%d secs', remainingtime );
elseif remainingtime == 1
eta = '1 sec';
else
eta = ''; % Nearly done (<1sec)
end
end
end
end
end % iGetTimeString
%-------------------------------------------------------------------------%
function entry = iUpdateBusyEntry( entry )
% Update a "busy" progress bar
% Make sure the widget is still OK
if ~ishandle(entry.Progress)
return
end
% Work out the new position. Since the bar is 0.1 long and needs to bounce,
% the position varies from 0 up to 0.9 then back down again. We achieve
% this with judicious use of "mod" with 1.8.
entry.Value = mod(entry.Value+0.01,1.8);
val = entry.Value;
if val>0.9
% Moving backwards
val = 1.8-val;
end
psize = entry.ProgressSize;
startIdx = max( 1, round( val*psize(1) ) );
endIdx = max( 1, round( (val+0.1)*psize(1) ) );
barLength = endIdx - startIdx + 1;
% Create the image
bgim = entry.BackgroundCData(:,ones( 1, psize(1) ),:);
barim = iMakeBarImage(entry.CData, 1, barLength);
bgim(:,startIdx:endIdx,:) = barim;
% Put it into the widget
entry.BarCData = bgim;
set( entry.Progress, 'CData', bgim );
end % iUpdateBusyEntry
%-------------------------------------------------------------------------%
function barim = iMakeBarImage(strip, startIdx, endIdx)
shadow1_weight = 0.4;
shadow2_weight = 0.7;
barLength = endIdx - startIdx + 1;
% Repmat is the obvious way to fill the bar, but BSXFUN is often
% faster. Indexing is obscure but faster still.
barim = strip(:,ones(1, barLength),:);
% Add highlight to the start of the bar
if startIdx <= 2 && barLength>=2
barim(:,1,:) = 255 - shadow1_weight*(255-strip);
barim(:,2,:) = 255 - shadow2_weight*(255-strip);
end
% Add shadow to the end of the bar
if endIdx>=4 && barLength>=2
barim(:,end,:) = shadow1_weight*strip;
barim(:,end-1,:) = shadow2_weight*strip;
end
end % iMakeBarImage
%-------------------------------------------------------------------------%
function iCloseFigure( fig, evt ) %#ok<INUSD>
% Closing the figure just makes it invisible
set( fig, 'Visible', 'off' );
end % iCloseFigure
%-------------------------------------------------------------------------%
function iDeleteFigure( fig )
% Actually destroy the figure
busyTimer = getappdata( fig, 'BusyTimer' );
stop( busyTimer );
delete( busyTimer );
delete( fig );
end % iDeleteFigure
%-------------------------------------------------------------------------%
function iRedraw( fig, evt ) %#ok<INUSD>
entries = getappdata( fig, 'ProgressEntries' );
fobj = handle( fig );
p = fobj.Position;
% p = get( fig, 'Position' );
border = 5;
textheight = 16;
barheight = 16;
panelheight = 10;
N = max( 1, numel( entries ) );
% Check the height is correct
heightperentry = textheight+barheight+panelheight;
requiredheight = 2*border + N*heightperentry - panelheight;
if ~isequal( p(4), requiredheight )
p(2) = p(2) + p(4) - requiredheight;
p(4) = requiredheight;
% In theory setting the position should re-trigger this callback, but
% in practice it doesn't, probably because we aren't calling "drawnow".
set( fig, 'Position', p )
end
ypos = p(4) - border;
width = p(3) - 2*border;
setappdata( fig, 'DefaultProgressBarSize', [width barheight] );
for ii=1:numel( entries )
set( entries(ii).LabelText, 'Position', [border ypos-textheight width*0.75 textheight] );
set( entries(ii).ETAText, 'Position', [border+width*0.75 ypos-textheight width*0.25 textheight] );
ypos = ypos - textheight;
if entries(ii).CanCancel
set( entries(ii).Progress, 'Position', [border ypos-barheight width-barheight+1 barheight] );
entries(ii).ProgressSize = [width-barheight barheight];
set( entries(ii).CancelButton, 'Visible', 'on', 'Position', [p(3)-border-barheight ypos-barheight barheight barheight] );
else
set( entries(ii).Progress, 'Position', [border ypos-barheight width+1 barheight] );
entries(ii).ProgressSize = [width barheight];
set( entries(ii).CancelButton, 'Visible', 'off' );
end
ypos = ypos - barheight;
set( entries(ii).Panel, 'Position', [-500 ypos-500-panelheight/2 p(3)+1000 500] );
ypos = ypos - panelheight;
entries(ii) = iUpdateEntry( entries(ii), true );
end
setappdata( fig, 'ProgressEntries', entries );
end % iRedraw
function cdata = iMakeCross( sz )
% Create a cross-shape icon of size sz*sz*3
cdata = diag(ones(sz,1),0) + diag(ones(sz-1,1),1) + diag(ones(sz-1,1),-1);
cdata = cdata + flip(cdata,2);
% Convert zeros to nans (transparent) and non-zeros to zero (black)
cdata(cdata == 0) = nan;
cdata(~isnan(cdata)) = 0;
% Convert to RGB
cdata = cat( 3, cdata, cdata, cdata );
end % iMakeCross
function iTimerFcn(fig)
% Timer callback for updating stuff every so often
entries = getappdata( fig, 'ProgressEntries' );
for ii=1:numel(entries)
if entries(ii).Busy
entries(ii) = iUpdateBusyEntry(entries(ii));
end
end
setappdata( fig, 'ProgressEntries', entries );
end % iTimerFcn

View File

@ -0,0 +1,41 @@
function[e] = onClickPlotAxes(varargin)
e = varargin{1};
obj = varargin{2};
handle = varargin{3};
location = get(obj, 'CurrentPoint');
previous_location = get(obj, 'UserData');
subj_pop = findobj('Tag','subj_pop');
sess_pop = findobj('Tag','sess_pop');
tmpsubj=get(subj_pop, 'Value');
if (iscell(tmpsubj)), selsubj = tmpsubj{1}; else selsubj = tmpsubj;end;
tmpsess=get(subj_pop, 'Value');
if (iscell(tmpsubj)), selsess = tmpsess{1}; else selsess = tmpsess;end;
if isempty(selsess) selsess = 1; end; if isempty(selsubj) selsubj = 1; end;
e.subjects(selsubj).sessions(selsess).sampling_rate
sampling_rate = e.subjects(selsubj).sessions(selsess).sampling_rate;
new_location.x = location(1,1);
new_location.y = location(1,2);
if isfield(previous_location, 'x');
delta_t = abs(new_location.x -previous_location.x);
units = 'ms';
if (delta_t > 1e3)
units = 's';
delta_t = delta_t/1e3;
end
display(sprintf('Delta time : %3.2f %s', delta_t, units));
end
previous_location = new_location;
set(obj, 'UserData', previous_location);

View File

@ -0,0 +1,12 @@
function[output_text e] = onDataPointClick(e, unused, varargin)
varargin
% e = varargin{1};
% obj = varargin{2};
% event_obj = varargin{3};
%
% pos = get(event_obj, 'Position')
% display(['clicked at pos : ' pos]);
e.
output_text = {'test1111'};

View File

@ -0,0 +1,154 @@
function[e] = plot(e)
plotwindow = figure;
set(plotwindow, 'Color', [1 1 1]);
e.handle = plotwindow;
options.raw = 0;
options.logtransformed = 0;
options.interpolated = 0;
options.filtered = 0;
options.blinks = 0;
options.markers = 0;
options.labels = 0;
options.baseline = 0;
options.baseline_corrected = 0;
options.deconvolution = 0;
options.drawing = options;
options.drawing.raw = {'-', [1 0 0], 3};
options.drawing.logtransformed = {'-', [0 0 1], 3};
options.drawing.interpolated = {'-', [0.5 0 0], 3};
options.drawing.filtered= {'--', [0 0.5 0], 3};
options.drawing.markers = {'--', [0.5 0 0], 3};
options.drawing.baseline= {'--', [0 0 1], 3};
options.drawing.baseline_corrected= {'--', [0 0 0], 3};
set(plotwindow, 'UserData', options);
subj_pop = uicontrol('Style','popupmenu');
sess_pop = uicontrol('Style','popupmenu');
subj_pop_string = ''; subj_pop_vals =[];
sess_pop_string = ''; sess_pop_vals =[];
for s = 1:length(e.subjects)
if s > 1
subj_pop_string = [subj_pop_string '|' e.subjects(s).name];
else
subj_pop_string = [e.subjects(s).name];
end
subj_pop_vals = [subj_pop_vals s];
end
set(subj_pop, 'Position', [20 20 150 20]);
set(subj_pop, 'String', subj_pop_string);
set(subj_pop, 'Value', 1);
set(subj_pop, 'Callback', 'e.set_plot_subject');
set(subj_pop, 'FontName', 'Verdana');
set(subj_pop, 'FontWeight', 'bold');
set(subj_pop, 'FontSize', 11);
sel=get(subj_pop, 'Value');
for s = 1:length(e.subjects(sel).sessions);
if s > 1
sess_pop_string = [sess_pop_string '|' e.subjects(sel).sessions(s).name];
else
sess_pop_string = [e.subjects(sel).sessions(s).name];
end
sess_pop_vals = [sess_pop_vals s];
end
set(sess_pop, 'Position', [175 20 150 20]);
set(sess_pop, 'String', sess_pop_string);
set(sess_pop, 'Value', 1);
set(sess_pop, 'Callback', 'e.set_plot_sess');
set(sess_pop, 'FontName', 'Verdana');
set(sess_pop, 'FontWeight', 'bold');
set(sess_pop, 'FontSize', 11);
selsess = get(sess_pop, 'Value');
trial_slider = uicontrol('Style','slider');
trial_edit = uicontrol('Style','edit');
set(trial_slider, 'Position', [335 20 150 20]);
set(trial_slider, 'Min', 1);
set(trial_slider, 'Max', length(e.subjects(sel).sessions(selsess).trials));
set(trial_slider, 'Value', 1);
set(trial_slider, 'Callback', 'e.set_plot_trial_slider');
set(trial_slider, 'SliderStep',[1/length(e.subjects(sel).sessions(selsess).trials) 5/length(e.subjects(sel).sessions(selsess).trials)]);
set(trial_edit, 'Position', [ 495 20 60 20]);
set(trial_edit, 'String', 1);
set(trial_edit, 'Callback', 'e.set_plot_trial_edit');
set(trial_edit, 'FontName', 'Verdana');
set(trial_edit, 'FontWeight', 'bold');
set(trial_edit, 'FontSize', 11);
options_toggle = uicontrol('Style', 'toggle')
set(options_toggle, 'Position', [480 390 70 30]);
set(options_toggle, 'String', 'Options');
set(options_toggle', 'Callback', 'e.togglePlotOptions');
bl_type = e.bl_types{e.settings.BaselineCorrection};
jList = java.util.ArrayList;
i=0;
jList.add(i,'<html><font name="Verdana" size=1><b>Raw trial</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Logtransformed trial</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Interpolated trial</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Filtered trial</b></font></html>');i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Blinks</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Markers</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Labels</b></font></html>'); i = i+1;
jList.add(i,['<html><font name="Verdana" size=1><b>Baseline (' bl_type ')</b></font></html>']); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Baseline corrected</b></font></html>'); i = i+1;
jList.add(i,'<html><font name="Verdana" size=1><b>Deconvolved modelfit</b></font></html>'); i = i+1;
jCBList = com.mathworks.mwswing.checkboxlist.CheckBoxList(jList);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCBList);
posfig = get(gcf, 'Position');
%center = [((posfig(3) /2) - 75) ((posfig(4) /2) - 100)];
[jhCBList,hContainer] = javacomponent(jScrollPane,[400 270 150,110],gcf);
set(jCBList, 'ValueChangedCallback', @e.setPlotOptions);
jCBModel = jCBList.getCheckModel;
jCBModel.uncheckAll;
jCBModel.checkIndex(1);
%% set Tags
plotwindow_id = get_plotwindow_id(gcf);
set(subj_pop, 'Tag', ['subj_pop.' plotwindow_id]);
set(sess_pop, 'Tag', ['sess_pop.' plotwindow_id]);
set(trial_edit, 'Tag', ['trial_edit.' plotwindow_id]);
set(trial_slider, 'Tag', ['trial_slider.' plotwindow_id]);
set(options_toggle, 'Tag', ['options_toggle.' plotwindow_id]);
plot(e.subjects(1).sessions(1).trials(1));
pos = get(gca, 'Position');
set(gca, 'Position', [.1 .2 .8 .7]);
set(gca, 'FontName', 'Verdana');
set(gca, 'FontWeight', 'bold');
set(gca, 'FontSize', 10);
set(gca, 'Box', 'on');
%trial_slider = uicontrol('Style', 'slider')
%fig_pos = get(gcf,'Position');
%set(h, 'Position', [20 20 (fig_pos(3) - 20) 20]);
%set(h, 'Min', 1); set(h, 'Max',
set(gca,'ButtonDownFcn',@e.onClickPlotAxes);
dcm = datacursormode(gcf);
set(dcm, 'UpdateFcn', @e.onDataPointClick);
datacursormode on;

View File

@ -0,0 +1,9 @@
function[e] = plot_aggregate(e, index, highlighted)
display(sprintf('plotting %d', index));
hold on;
plot(e.aggregates(index).mean, 'LineWidth', 3, 'Color', e.aggregates(index).color);

View File

@ -0,0 +1,28 @@
function[e] = plot_aggregates(e, table, event)
data = get(table, 'Data');
if ~isempty(event)
if ~isempty(event.Indices)
selected = event.Indices(1); % selected row
end
end
e = evalin('base', 'e');
for a = 1:length(e.aggregates)
if (data{a,1})
highlight=0;
if ~isempty(event)
if ~isempty(event.Indices)
if (event.Indices(2) > 1) %% row highlighted
highlight=1;
end
end
end
plot_aggregate(e, a, highlight);
end
end

View File

@ -0,0 +1,18 @@
function[obj] = preprocess(obj);
progressbar = waitbar(0, 'Preprocessing subjects...');
p= get(progressbar, 'Position'); p(2)=p(2)+100;
set(progressbar,'Position', p, 'Color', [1 1 1]);
t = get(get(progressbar, 'Children'), 'Title');
set(t, 'FontSize', 15, 'FontWeight', 'bold', 'FontName', 'Tahoma');
set(progressbar,'Visible','on');
for s = 1:length(obj.subjects)
waitbar(s/length(obj.subjects), progressbar, sprintf('Preprocessing data for subject %d...', s));
obj.subjects(s) = obj.subjects(s).preprocess(obj.settings);
end
close(progressbar);
end

View File

@ -0,0 +1,6 @@
function[obj] = removeDuplicateLabels(obj)
for s = 1:length(obj.subjects)
obj.subjects(s) = obj.subjects(s).removeDuplicateLabels;
end

View File

@ -0,0 +1,16 @@
function[e] = remove_aggregate(e)
fig = e.handle(2);
figure(fig);
group_list = findobj('Tag', 'group_list');
selected_group = get(group_list, 'Value')
%e.aggregates(selected_group) = [];
for i =selected_group+1:length(e.aggregates)
e.aggregates(i) = e.aggregates(i-1);
end
e.aggregates(end) = [];
e.update_aggregates;

View File

@ -0,0 +1,26 @@
function[e] = select_aggregate(varargin)
e = varargin{1};
table = varargin{2};
event = varargin{3};
data = get(table, 'Data');
if length(event.Indices) > 1
if (event.Indices(2) == 1)
%% checkbutton is clicked
if isempty(data{event.Indices(1),1})
data{event.Indices(1),1} = 0;
end
data{event.Indices(1),1} = logical(~data{event.Indices(1),1});
end
set(table, 'Data',data);
end
e.plot_aggregates(table, event);

View File

@ -0,0 +1,36 @@
function[e] = setPlotOptions(varargin)
plotwindow = gcf;
plotwindow_id = get_plotwindow_id(plotwindow);
options = get(plotwindow, 'UserData')
e = varargin{1};
jEventData = varargin{2};
hListbox = varargin{3};
variables = {'raw', 'logtransformed', 'interpolated', 'filtered', 'blinks', 'markers', 'labels','baseline', 'baseline_corrected', 'deconvolution'};
items = get(jEventData, 'CheckedIndicies');
non_items = setdiff(0:length(variables)-1, items);
for i = 1:length(items)
eval(['options.' variables{items(i)+1} '=1;']);
end
for i = 1:length(non_items)
eval(['options.' variables{non_items(i)+1} '=0;']);
end
set(plotwindow, 'UserData', options);
subj_pop = findobj('Tag',['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag',['sess_pop.' plotwindow_id]);
trial_edit = findobj('Tag', ['trial_edit.' plotwindow_id]);
tmpsubj=get(subj_pop, 'Value');
if (iscell(tmpsubj)), selsubj = tmpsubj{1}; else selsubj = tmpsubj;end;
tmpsess=get(sess_pop, 'Value');
if (iscell(tmpsubj)), selsess = tmpsess{1}; else selsess = tmpsess;end;
tmptrial=get(trial_edit, 'String');
if (iscell(tmptrial)), seltrial = str2num(tmptrial{1}); else seltrial = str2num(tmptrial);end;
plot(e.subjects(selsubj).sessions(selsess).trials(seltrial), e.settings);

View File

@ -0,0 +1 @@
function[obj] = setTrialStart(pattern)

View File

@ -0,0 +1,23 @@
function[] = set_plot_sess(e)
plotwindow = gcf;
plotwindow_id = get_plotwindow_id(plotwindow);
subj_pop = findobj('Tag', ['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag', ['sess_pop.' plotwindow_id]);
trial_slider = findobj('Tag', ['trial_slider.' plotwindow_id]);
trial_edit = findobj('Tag', ['trial_edit.' plotwindow_id]);
trial=get(trial_slider, 'Value');
set(trial_edit, 'String', trial);
sess = get(sess_pop, 'Value');
subj = get(subj_pop, 'Value');
trial=round(get(trial_slider, 'Value'));
set(trial_slider, 'Value', trial);
plot(e.subjects(subj).sessions(sess).trials(trial));

View File

@ -0,0 +1,22 @@
function[] = set_plot_trial_edit(e)
plotwindow = e.handle;
subj_pop = findobj('Tag', 'subj_pop');
sess_pop = findobj('Tag', 'sess_pop');
trial_slider = findobj('Tag', 'trial_slider');
trial_edit = findobj('Tag', 'trial_edit');
trial=get(trial_edit, 'Value');
min_trial = get(trial_edit, 'Min');
max_trial = get(trial_edit, 'Max');
if ((trial >= min_trial) && (trial <= max_trial))
set(trial_slider, 'Value', trial);
else
display('Trial id does not exist');
end
plot(e.subjects(subj).sessions(sess).trials(trial));

View File

@ -0,0 +1,22 @@
function[] = set_plot_subject(e)
plotwindow = e.handle;
subj_pop = findobj('Tag', 'subj_pop');
sess_pop = findobj('Tag', 'sess_pop');
trial_slider = findobj('Tag', 'trial_slider');
trial_edit = findobj('Tag', 'trial_edit');
sel=get(subj_pop, 'Value');
for s = 1:length(e.subjects(sel).sessions);
if s > 1
sess_pop_string = [sess_pop_string '|' e.subjects(sel).sessions(s).name];
else
sess_pop_string = [e.subjects(sel).sessions(s).name];
end
sess_pop_vals = [sess_pop_vals s];
end
set(sess_pop, 'Value', 1);

View File

@ -0,0 +1,37 @@
function[] = set_plot_subject(e)
plotwindow = gcf;
plotwindow_id = get_plotwindow_id(plotwindow);
subj_pop = findobj('Tag', ['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag', ['sess_pop.' plotwindow_id]);
trial_slider = findobj('Tag', ['trial_slider.' plotwindow_id]);
trial_edit = findobj('Tag', ['trial_edit.' plotwindow_id]);
tmp=get(subj_pop, 'Value');
if (iscell(tmp))
sel = tmp{1};
else
sel = tmp;
end;
sess_pop_vals = []; sess_pop_string = '';
for s = 1:length(e.subjects(sel).sessions);
if s > 1
sess_pop_string = [sess_pop_string '|' e.subjects(sel).sessions(s).name];
else
sess_pop_string = [e.subjects(sel).sessions(s).name];
end
sess_pop_vals = [sess_pop_vals s];
end
set(sess_pop, 'Value', 1);
set(sess_pop, 'String', sess_pop_string);
sess = get(sess_pop, 'Value');
subj = get(subj_pop, 'Value');
trial=round(get(trial_slider, 'Value'));
plot(e.subjects(subj).sessions(sess).trials(trial));

View File

@ -0,0 +1,27 @@
function[] = set_plot_trial_edit(e)
plotwindow = gcf;
plotwindow_id = num2str(plotwindow);
subj_pop = findobj('Tag', ['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag', ['sess_pop.' plotwindow_id]);
trial_slider = findobj('Tag', ['trial_slider.' plotwindow_id]);
trial_edit = findobj('Tag', ['trial_edit.' plotwindow_id]);
trial=str2num(get(trial_edit, 'String'));
min_trial = get(trial_slider, 'Min');
max_trial = get(trial_slider, 'Max');
if ((trial >= min_trial) && (trial <= max_trial))
set(trial_slider, 'Value', trial);
else
display('Trial id does not exist');
%set(trial_slide, 'Value', min_trial);
end
sess = get(sess_pop, 'Value');
subj = get(subj_pop, 'Value');
plot(e.subjects(subj).sessions(sess).trials(trial));

View File

@ -0,0 +1,23 @@
function[] = set_plot_trial_slider(e)
plotwindow_id = get_plotwindow_id(gcf);
subj_pop = findobj('Tag', ['subj_pop.' plotwindow_id]);
sess_pop = findobj('Tag', ['sess_pop.' plotwindow_id]);
trial_slider = findobj('Tag', ['trial_slider.' plotwindow_id]);
trial_edit = findobj('Tag', ['trial_edit.' plotwindow_id]);
ts_val = get(trial_slider, 'Value');
if iscell(ts_val)
trial=round(ts_val{1});
else
trial=round(ts_val);
end
set(trial_edit, 'String', trial);
sess = get(sess_pop, 'Value');
subj = get(subj_pop, 'Value');
plot(e.subjects(subj).sessions(sess).trials(trial));

View File

@ -0,0 +1,47 @@
function[] = statistics(exp)
%
% Calculate pairwise TFCE statistics between aggregates
% based on permutation
%
%
for a = 1:length(exp.aggregates)
for b = setdiff(1:length(exp.aggregates), a)
%% retreive matrices for aggregates of comparison
[traces_a time_a] = exp.get_aggregate_data(a);
[traces_b time_b] = exp.get_aggregate_data(b);
%% TODO: Check time_a == time_b !
traces = [traces_a ; traces_b];
labels = [repmat(1, 1:size(traces_a,2)) repmat(2, 1:size(traces_b,2))];
%% calculate true difference:
true_signal = nanmean(traces_a) - nanmean(traces_b);
%% perform permutations
nperm = exp.settings.Statistics.NumberOfPermutations;
P = nan(size(traces_1,1), nperm);
for i = 1:nperm
labels_permuted = labels(randperm(length(labels)));
a_perm = find(labels_permuted==1); b_perm = find(labels_permuted==2);
P(:,i) = nanmean(traces(a_perm,:)) - nanmean(traces(b_perm,:));
end
hmin = 0; hmax = max(max(P));
%% perform TFCE
T = TFCEobj('D', P, 'hmax', hmax);
T.TFCECalc;
%% store results
exp.aggregates.statistics.TFCE(a,b).results.pvalues = T.Pvalues;
%% threshold FWE comparison
exp.aggregates.statistics.TFCE(a,b).results.pvalues = T.Pvalues;
end
end

View File

@ -0,0 +1,10 @@
function[e] = togglePlotOptions(e)
option_list = findobj('UserData', 'com.mathworks.mwswing.MJScrollPane');
visible = get(option_list, 'Visible');
if strcmp(visible, 'on')
set(option_list, 'Visible', 'off');
else
set(option_list, 'Visible', 'on');
end

View File

@ -0,0 +1,25 @@
function[e] = update_aggregates(e);
fig = gcf;
plotwindow_id = num2str(fig);
table = findobj('Tag','aggragate_table');
agg_strings = {};
for i = 1:length(e.aggregates)
agg_strings{i,1} = 1;
color_str = ['#' sprintf('%02s', dec2hex(e.aggregates(i).color(1)*255)) ...
sprintf('%02s', dec2hex(e.aggregates(i).color(2)*255)) ...
sprintf('%02s', dec2hex(e.aggregates(i).color(3)*255))]
agg_strings{i,2} = ['<html><li color=' color_str '><font color=#000000>'...
e.aggregates(i).name{1} ...
'</font></li></html>'];
agg_strings{i,3} = e.aggregates(i).error.name;
end
set(table, 'Data', agg_strings);
e = e.calculate_aggregates;
e = e.plot_aggregates(table, []);

View File

@ -0,0 +1,18 @@
classdef PDParser
properties
FilterSize = 100;
BlinkExtension = [10 10];
WorkingDir = [];
QualityThreshold = 50;
MaximumBlinkSize = 150; %% ms
BaselineCorrection = 0;
Experiment = [];
end
methods
function[] = import(varargin); end
function[] = importData(varargin); end
end
end

View File

@ -0,0 +1,25 @@
function[] = import(varargin)
if nargin ==1
if strcmp(class(varargin{1}, 'PDSession'));
end
if strcmp(class(varargin{1}, 'PDSubject'));
end
if strcmp(class(varargin{1}, 'PDExperiment'));
end
if strcmp(class(varargin{1}, 'string'));
try
[base file ext] = fileparts(varargin{1});
if strcmp(lower(ext), '.edf');
obj.readEDF(varargin{1});
end
if strcmp(lower(ext), '.asc');
obj.readASC(varargin{1});
end
end
end
end
end

View File

@ -0,0 +1,19 @@
function[] = importData(varargin)
if (nargin == 0)
if (isempty(obj.filename))
error('Filename has not been set')
end
else
obj.filename = varargin{1};
end
[base filename ext] = fileparts(obj.filename);
if strcmp(lower(ext), '.edf');
obj.readEDF;
end
if strcmp(lower(ext), '.asc');
obj.readASC;
end
end

BIN
PDToolkit/@PDSession/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,49 @@
classdef PDSession
properties
datafile
eye
settings
trials = PDTrial;
date
time
name
labels
samples
sampling_rate
events_
trial_start_pattern
trial_end_pattern
baseline_type
baseline_onset_pattern
baseline_offset_pattern
stimulus_onset_pattern
stimulus_offset_pattern
label_patterns
label_dependencies
end
methods
function[obj] = PDSession(varargin)
if nargin==0
error('Session requires a PDSubject')
else
obj.datafile = varargin{1};
obj.eye = 'left' %% default to left eye recording
[basedir obj.name ext] = fileparts(obj.datafile);
obj.importData(varargin{1});
obj = obj.setFramerate;
end
end
function readEDF(filename)
end
end
end

View File

@ -0,0 +1,27 @@
function[obj] = check_patterns(obj)
if isempty(obj.trial_start_pattern)
error('No text pattern for `trial start` was provided');
end
% if isempty(obj.trial_end_pattern)
% warning('No text pattern for `trial end` was provided : using start trial');
% obj = obj.setPattern('trial_end', obj.trial_start_pattern);
% end
if isempty(obj.stimulus_onset_pattern)
warning('No stimulus onset pattern was provided : using start trial');
obj.stimulus_onset_pattern = obj.trial_start_pattern;
end
if isempty(obj.stimulus_offset_pattern)
obj.stimulus_offset_pattern = obj.trial_end_pattern;
end
if isempty(obj.baseline_onset_pattern)
obj.baseline_offset_pattern = obj.trial_start_pattern;
end
if isempty(obj.baseline_offset_pattern)
obj.baseline_offset_pattern = obj.stimulus_onset_pattern;
end

View File

@ -0,0 +1,18 @@
function[obj] = deconvolve(obj, settings)
%% Perform pupil deconvolution for the entire session
if nargin ==1
selected_trials = 1:length(obj.trials)
else
selected_trials = settings.selection;
end
h = waitbar(0, 'Performing pupil deconvolution...');
for t = 1:length(selected_trials)
selected_trial = selected_trials(t)
obj.trials(selected_trial) = obj.trials(selected_trial).deconvolve(settings);
waitbar(t/length(selected_trials), h);
end

View File

@ -0,0 +1,20 @@
function[obj] = display_and_log(obj, varargin)
if nargin ==2
text = varargin{1};
truncate = varargin{2};
else
text = varargin{1};
truncate=0;
end
code = 'a+';
if truncate
code = 'w+';
end
display(sprintf(text));
fp = fopen('information.txt',code);
text = [text '\n'];
fprintf(fp, text);
fclose(fp);

View File

@ -0,0 +1,136 @@
function[pre_mat post_mat rel_time trial_ind] = getTimeLockedTrialMatrix(objs, varargin)
%% getTimeLockedTrialMatrix returns each trial trace shifted for a marker
% or event timestamp
%
% Usage
% [mat trial_ind] = PDSession.getTimeLockedTrialMatrix(event_code [,selection, eye, signal_type, corrected])
%
% - mat
% Matrix of n x l, n = number of trials, l = maximum length of all traces
% - trial_ind
% Vector containing the selected trials after quality
% thresholding
% - event_code
% Event code (or Label string that is matched.)
% - selection
% Vector of selected / requested trials%
% - eye
% 'left', 'right', or 'both' (default = 'left')
% - signal_type
% 'raw', 'interpolated', 'filtered' (default = 'filtered');
% - corrected
% 0 /1, use baseline corrected signals (default : 1)
%
% Examples:
%
% *) with one parameter : session.getTrialMatrix('stimulus start');
% *) with two parameters : session.getTrialMatrix('all', 'left');
% *) with three parameters : session.getTrialMatrix('all', 'left', 'interpolated');
% *) with four parameters : session.getTrialMatrix(1:10, 'right', 'interpolated', 1);
%
% Usage :
% function[mat trial_ind] = getTimeLockedTrialMatrix(obj, varargin)
%% determine input (this can be optimized...)
if nargin == 1
error('No event code provided')
end
if nargin == 2
event_code = varargin{1};
selection = [];
eye = 'left';
signal_type = 'filtered';
corrected = 1;
end
if nargin == 3
event_code = varargin{1};
selection = varargin{2};
eye = 'left';
signal_type = 'filtered';
corrected = 1;
end
if nargin == 4
event_code = varargin{1};
selection = varargin{2};
eye = varargin{3};
signal_type = 'filtered';
corrected = 1;
end
if nargin == 5
event_code = varargin{1};
selection = varargin{2};
eye = varargin{3};
signal_type = varargin{4};
corrected = 1;
end
if nargin == 6
event_code = varargin{1};
selection = varargin{2};
eye = varargin{3};
signal_type = varargin{4};
corrected = varargin{5};
end
if corrected == 1
data_field = 'baseline_corrected';
else
data_field = 'raw';
end
%%
for s = 1:length(objs)
obj = objs(s);
if isempty(selection)
selection = 1:length(obj.trials);
end
%% incorporate trial quality
q_objs = [obj.trials(selection).quality];
q_vals = cat(1, q_objs.(eye));
valid_trials = q_vals >= obj.settings.QualityThreshold;
trial_ind = find(valid_trials);
trials = [obj.trials(valid_trials).data];
t_objs = [trials.(eye)]; data_objs = [t_objs.(data_field)];
max_trial_length = 0;
indices = obj.trials.getIndexForEvent(event_code);
indices = indices(trial_ind);
%% determine the maximum length of pre and post trial
for i = 1:length(data_objs)
if max_trial_length < length(data_objs(i).(signal_type)(1:indices(i)));
max_trial_length_pre = length(data_objs(i).(signal_type)(1:indices(i)-1));
max_trial_length_post = length(data_objs(i).(signal_type)(indices(i):end));
end
end
%% predefine matrices (selected trials x max length)
pre_mat = nan(length(trial_ind), max_trial_length_pre);
post_mat = nan(length(trial_ind), max_trial_length_post);
%% cut the trials in pre and post marker
for t = 1:length(trials)
pre_trace = trials(t).(eye).(data_field).(signal_type)(1:indices(i)-1);
pre_mat(t,end-length(pre_trace)+1:end) = pre_trace;
post_trace = trials(t).(eye).(data_field).(signal_type)(indices(i):end);
post_mat(t,1:length(post_trace)) = post_trace;
end
rel_time = repmat(-length(pre_mat):length(post_mat)-1,length(trials),1);
end

View File

@ -0,0 +1,90 @@
function[mat trial_ind] = getTrialMatrix(obj, varargin)
%% getTrialMatrix returns traces of all selected trials in selection, surviving the Quality Threshold
%
% Usage
% [mat trial_ind] = PDSession.getTrialMatrix([selection, eye, signal_type, corrected])
%
% - mat
% Matrix of n x l, n = number of trials, l = maximum length of all traces
% - trial_ind
% Vector containing the selected trials after quality
% thresholding
% - selection
% Vector of selected / requested trials
% - eye
% 'left', 'right', or 'both' (default = 'left')
% - signal_type
% 'raw', 'interpolated', 'filtered' (default = 'filtered');
% - corrected
% 0 /1, use baseline corrected signals (default : 1)
%
% Examples:
%
% *) without parameters : session.getTrialMatrix;
% *) with one parameter : session.getTrialMatrix(1:10);
% *) with two parameters : session.getTrialMatrix('all', 'left');
% *) with three parameters : session.getTrialMatrix('all', 'left', 'interpolated');
% *) with four parameters : session.getTrialMatrix(1:10, 'right', 'interpolated', 1);
if nargin == 2
selection = varargin{1};
eye = 'left';
signal_type = 'filtered';
corrected = 1;
end
if nargin == 3
selection = varargin{1};
eye = varargin{2};
signal_type = 'filtered';
corrected = 1;
end
if nargin == 4
selection = varargin{1};
eye = varargin{2};
signal_type = varargin{3};
corrected = 1;
end
if corrected == 1
data_field = 'baseline_corrected';
else
data_field = 'raw';
end
if ~ismember(eye,{'left', 'right', 'both'});
eye = 'left';
end
if isempty(selection)
selection = 1:length(obj.trials);
end
%% Quality check
q_objs = [obj.trials(selection).quality];
q_vals = cat(1, q_objs.(eye));
valid_trials = q_vals >= obj.settings.QualityThreshold;
trial_ind = find(valid_trials);
trials = [obj.trials(valid_trials).data];
t_objs = [trials.(eye)]; data_objs = [t_objs.(data_field)];
max_trial_length = 0;
for i = 1:length(data_objs)
if max_trial_length < length(data_objs(i).(signal_type));
max_trial_length = length(data_objs(i).(signal_type));
end
end
%% define empty output matrix with zeros
mat = nan(length(valid_trials), max_trial_length);
for t = 1:length(trials)
trace = trials(t).(eye).(data_field).(signal_type);
mat(t,1:length(trace)) = trace;
end

View File

@ -0,0 +1,24 @@
function[obj] = importData(obj, varargin)
if (nargin == 1)
if (isempty(obj.filename))
error(' Filename has not been set')
end
else
obj.datafile = varargin{1};
end
[base filename ext] = fileparts(obj.datafile);
if strcmp(lower(ext), '.edf');
obj.readEDF;
end
if strcmp(lower(ext), '.asc');
obj.read_ASC;
end
if strcmp(lower(ext), '.gazedata');
obj.read_gazedata;
end
end

View File

@ -0,0 +1,450 @@
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 4 blinks filtered ( 5 missing data events); quality : 96 percent
*) 6 blinks filtered ( 6 missing data events); quality : 96 percent
*) 4 blinks filtered ( 6 missing data events); quality : 96 percent
*) 5 blinks filtered ( 6 missing data events); quality : 95 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 2 blinks filtered ( 4 missing data events); quality : 97 percent
*) 3 blinks filtered ( 3 missing data events); quality : 97 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 7 blinks filtered ( 8 missing data events); quality : 95 percent
*) 4 blinks filtered ( 5 missing data events); quality : 95 percent
*) 4 blinks filtered ( 6 missing data events); quality : 94 percent
*) 1 blinks filtered ( 2 missing data events); quality : 97 percent
*) 6 blinks filtered ( 7 missing data events); quality : 93 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 4 blinks filtered ( 6 missing data events); quality : 95 percent
*) 5 blinks filtered ( 7 missing data events); quality : 95 percent
*) 2 blinks filtered ( 4 missing data events); quality : 97 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 4 blinks filtered ( 6 missing data events); quality : 95 percent
*) 4 blinks filtered ( 6 missing data events); quality : 95 percent
*) 5 blinks filtered ( 6 missing data events); quality : 95 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 4 missing data events); quality : 96 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 0 blinks filtered ( 2 missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 3 blinks filtered ( 5 missing data events); quality : 95 percent
*) 9 blinks filtered (10 missing data events); quality : 90 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 4 blinks filtered ( 6 missing data events); quality : 95 percent
*) 4 blinks filtered ( 4 missing data events); quality : 97 percent
*) 3 blinks filtered ( 4 missing data events); quality : 97 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 0 blinks filtered ( 3 missing data events); quality : 97 percent
*) 3 blinks filtered ( 6 missing data events); quality : 95 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 4 blinks filtered ( 5 missing data events); quality : 95 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 97 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 4 blinks filtered ( 5 missing data events); quality : 95 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 2 blinks filtered ( 5 missing data events); quality : 95 percent
*) 3 blinks filtered ( 5 missing data events); quality : 96 percent
*) 1 blinks filtered ( 3 missing data events); quality : 98 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 2 blinks filtered ( 4 missing data events); quality : 95 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 3 missing data events); quality : 97 percent
*) 3 blinks filtered ( 3 missing data events); quality : 96 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 3 blinks filtered ( 5 missing data events); quality : 94 percent
*) 5 blinks filtered ( 7 missing data events); quality : 94 percent
*) 3 blinks filtered ( 3 missing data events); quality : 96 percent
*) 3 blinks filtered ( 4 missing data events); quality : 96 percent
*) 3 blinks filtered ( 4 missing data events); quality : 96 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 3 blinks filtered ( 3 missing data events); quality : 96 percent
*) 7 blinks filtered ( 9 missing data events); quality : 91 percent
*) 8 blinks filtered ( 9 missing data events); quality : 91 percent
*) 1 blinks filtered ( 2 missing data events); quality : 97 percent
*) 3 blinks filtered ( 5 missing data events); quality : 95 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 8 blinks filtered ( 9 missing data events); quality : 93 percent
*) 5 blinks filtered ( 7 missing data events); quality : 94 percent
*) 1 blinks filtered ( 2 missing data events); quality : 97 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 4 blinks filtered ( 4 missing data events); quality : 97 percent
*) 4 blinks filtered ( 5 missing data events); quality : 96 percent
*) 2 blinks filtered ( 4 missing data events); quality : 95 percent
*) 7 blinks filtered ( 8 missing data events); quality : 93 percent
*) 1 blinks filtered ( 2 missing data events); quality : 96 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 97 percent
*) 3 blinks filtered ( 6 missing data events); quality : 94 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 7 blinks filtered ( 8 missing data events); quality : 94 percent
*) 4 blinks filtered ( 5 missing data events); quality : 96 percent
*) 10 blinks filtered (12 missing data events); quality : 89 percent
*) 2 blinks filtered ( 5 missing data events); quality : 93 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 3 blinks filtered ( 4 missing data events); quality : 95 percent
*) 3 blinks filtered ( 5 missing data events); quality : 93 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 5 blinks filtered ( 8 missing data events); quality : 93 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 13 blinks filtered (14 missing data events); quality : 88 percent
*) 6 blinks filtered ( 7 missing data events); quality : 94 percent
*) 7 blinks filtered ( 9 missing data events); quality : 86 percent
*) 4 blinks filtered ( 6 missing data events); quality : 94 percent
*) 5 blinks filtered ( 7 missing data events); quality : 88 percent
*) 3 blinks filtered ( 6 missing data events); quality : 94 percent
*) 4 blinks filtered ( 6 missing data events); quality : 93 percent
*) 6 blinks filtered ( 8 missing data events); quality : 92 percent
*) 3 blinks filtered ( 6 missing data events); quality : 90 percent
*) 5 blinks filtered ( 7 missing data events); quality : 91 percent
*) 3 blinks filtered ( 5 missing data events); quality : 94 percent
*) 7 blinks filtered ( 8 missing data events); quality : 90 percent
*) 6 blinks filtered ( 8 missing data events); quality : 90 percent
*) 6 blinks filtered ( 7 missing data events); quality : 91 percent
*) 6 blinks filtered ( 7 missing data events); quality : 83 percent
*) 6 blinks filtered ( 8 missing data events); quality : 83 percent
*) 17 blinks filtered (18 missing data events); quality : 83 percent
*) 5 blinks filtered ( 6 missing data events); quality : 93 percent
*) 9 blinks filtered (11 missing data events); quality : 83 percent
*) 11 blinks filtered (13 missing data events); quality : 83 percent
*) 21 blinks filtered (21 missing data events); quality : 80 percent
*) 9 blinks filtered (11 missing data events); quality : 90 percent
*) 10 blinks filtered (12 missing data events); quality : 85 percent
*) 6 blinks filtered ( 8 missing data events); quality : 91 percent
*) 2 blinks filtered ( 5 missing data events); quality : 94 percent
*) 13 blinks filtered (15 missing data events); quality : 86 percent
*) 2 blinks filtered ( 5 missing data events); quality : 95 percent
*) 3 blinks filtered ( 5 missing data events); quality : 94 percent
*) 7 blinks filtered ( 8 missing data events); quality : 93 percent
*) 3 blinks filtered ( 6 missing data events); quality : 94 percent
*) 8 blinks filtered (10 missing data events); quality : 92 percent
*) 11 blinks filtered (11 missing data events); quality : 84 percent
*) 2 blinks filtered ( 4 missing data events); quality : 96 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 7 blinks filtered ( 9 missing data events); quality : 92 percent
*) 11 blinks filtered (12 missing data events); quality : 86 percent
*) 4 blinks filtered ( 7 missing data events); quality : 94 percent
*) 9 blinks filtered (10 missing data events); quality : 91 percent
*) 8 blinks filtered (10 missing data events); quality : 90 percent
*) 2 blinks filtered ( 5 missing data events); quality : 95 percent
*) 5 blinks filtered ( 8 missing data events); quality : 93 percent
*) 15 blinks filtered (17 missing data events); quality : 86 percent
*) 11 blinks filtered (12 missing data events); quality : 88 percent
*) 8 blinks filtered (10 missing data events); quality : 91 percent
*) 5 blinks filtered ( 7 missing data events); quality : 93 percent
*) 8 blinks filtered (10 missing data events); quality : 90 percent
*) 5 blinks filtered ( 7 missing data events); quality : 94 percent
*) 7 blinks filtered ( 8 missing data events); quality : 93 percent
*) 1 blinks filtered ( 5 missing data events); quality : 95 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 5 blinks filtered ( 7 missing data events); quality : 94 percent
*) 4 blinks filtered ( 7 missing data events); quality : 89 percent
*) 3 blinks filtered ( 6 missing data events); quality : 94 percent
*) 5 blinks filtered ( 6 missing data events); quality : 93 percent
*) 6 blinks filtered ( 8 missing data events); quality : 90 percent
*) 6 blinks filtered ( 7 missing data events); quality : 93 percent
*) 5 blinks filtered ( 7 missing data events); quality : 93 percent
*) 0 blinks filtered ( 2 missing data events); quality : 97 percent
*) 2 blinks filtered ( 5 missing data events); quality : 95 percent
*) 4 blinks filtered ( 6 missing data events); quality : 91 percent
*) 4 blinks filtered ( 6 missing data events); quality : 94 percent
*) 4 blinks filtered ( 7 missing data events); quality : 94 percent
*) 3 blinks filtered ( 5 missing data events); quality : 94 percent
*) 5 blinks filtered ( 7 missing data events); quality : 92 percent
*) 4 blinks filtered ( 7 missing data events); quality : 93 percent
*) 2 blinks filtered ( 3 missing data events); quality : 96 percent
*) 5 blinks filtered ( 6 missing data events); quality : 93 percent
*) 6 blinks filtered ( 7 missing data events); quality : 91 percent
*) 3 blinks filtered ( 5 missing data events); quality : 93 percent
*) 4 blinks filtered ( 6 missing data events); quality : 95 percent
*) 9 blinks filtered (10 missing data events); quality : 91 percent
*) 11 blinks filtered (13 missing data events); quality : 86 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 4 blinks filtered ( 7 missing data events); quality : 93 percent
*) 8 blinks filtered ( 9 missing data events); quality : 75 percent
*) 8 blinks filtered ( 9 missing data events); quality : 82 percent
*) 11 blinks filtered (12 missing data events); quality : 89 percent
*) 4 blinks filtered ( 6 missing data events); quality : 88 percent
*) 5 blinks filtered ( 7 missing data events); quality : 86 percent
*) 7 blinks filtered ( 8 missing data events); quality : 90 percent
*) 8 blinks filtered (10 missing data events); quality : 89 percent
*) 4 blinks filtered ( 6 missing data events); quality : 94 percent
*) 9 blinks filtered (10 missing data events); quality : 88 percent
*) 7 blinks filtered ( 9 missing data events); quality : 88 percent
*) 11 blinks filtered (13 missing data events); quality : 88 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 7 blinks filtered ( 7 missing data events); quality : 95 percent
*) 10 blinks filtered (10 missing data events); quality : 92 percent
*) 3 blinks filtered ( 6 missing data events); quality : 95 percent
*) 10 blinks filtered (12 missing data events); quality : 86 percent
*) 14 blinks filtered (14 missing data events); quality : 90 percent
*) 9 blinks filtered (11 missing data events); quality : 92 percent
*) 12 blinks filtered (13 missing data events); quality : 87 percent
*) 11 blinks filtered (12 missing data events); quality : 90 percent
*) 9 blinks filtered (11 missing data events); quality : 91 percent
*) 10 blinks filtered (13 missing data events); quality : 90 percent
*) 24 blinks filtered (24 missing data events); quality : 80 percent
*) 25 blinks filtered (25 missing data events); quality : 83 percent
*) 14 blinks filtered (15 missing data events); quality : 86 percent
*) 11 blinks filtered (12 missing data events); quality : 86 percent
*) 12 blinks filtered (13 missing data events); quality : 89 percent
*) 27 blinks filtered (27 missing data events); quality : 80 percent
*) 16 blinks filtered (16 missing data events); quality : 82 percent
*) 15 blinks filtered (15 missing data events); quality : 86 percent
*) 20 blinks filtered (21 missing data events); quality : 83 percent
*) 11 blinks filtered (12 missing data events); quality : 91 percent
*) 14 blinks filtered (14 missing data events); quality : 88 percent
*) 11 blinks filtered (13 missing data events); quality : 78 percent
*) 22 blinks filtered (22 missing data events); quality : 79 percent
*) 17 blinks filtered (17 missing data events); quality : 86 percent
*) 27 blinks filtered (27 missing data events); quality : 75 percent
*) 11 blinks filtered (12 missing data events); quality : 88 percent
*) 48 blinks filtered (48 missing data events); quality : 73 percent
*) 22 blinks filtered (22 missing data events); quality : 84 percent
*) 36 blinks filtered (36 missing data events); quality : 76 percent
*) 11 blinks filtered (13 missing data events); quality : 86 percent
*) 17 blinks filtered (17 missing data events); quality : 83 percent
*) 10 blinks filtered (11 missing data events); quality : 87 percent
*) 18 blinks filtered (18 missing data events); quality : 82 percent
*) 20 blinks filtered (21 missing data events); quality : 87 percent
*) 11 blinks filtered (11 missing data events); quality : 87 percent
*) 49 blinks filtered (49 missing data events); quality : 71 percent
*) 18 blinks filtered (19 missing data events); quality : 81 percent
*) 23 blinks filtered (23 missing data events); quality : 82 percent
*) 35 blinks filtered (35 missing data events); quality : 77 percent
*) 14 blinks filtered (14 missing data events); quality : 88 percent
*) 16 blinks filtered (16 missing data events); quality : 85 percent
*) 16 blinks filtered (16 missing data events); quality : 84 percent
*) 20 blinks filtered (21 missing data events); quality : 73 percent
*) 21 blinks filtered (21 missing data events); quality : 83 percent
*) 3 blinks filtered ( 4 missing data events); quality : 96 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 3 blinks filtered ( 4 missing data events); quality : 95 percent
*) 16 blinks filtered (17 missing data events); quality : 82 percent
*) 9 blinks filtered (10 missing data events); quality : 89 percent
*) 11 blinks filtered (11 missing data events); quality : 88 percent
*) 9 blinks filtered (10 missing data events); quality : 92 percent
*) 10 blinks filtered (11 missing data events); quality : 90 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 10 blinks filtered (10 missing data events); quality : 91 percent
*) 9 blinks filtered ( 9 missing data events); quality : 92 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 9 blinks filtered ( 9 missing data events); quality : 90 percent
*) 19 blinks filtered (19 missing data events); quality : 84 percent
*) 6 blinks filtered ( 6 missing data events); quality : 94 percent
*) 13 blinks filtered (14 missing data events); quality : 87 percent
*) 2 blinks filtered ( 5 missing data events); quality : 94 percent
*) 17 blinks filtered (18 missing data events); quality : 82 percent
*) 5 blinks filtered ( 5 missing data events); quality : 88 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 12 blinks filtered (13 missing data events); quality : 87 percent
*) 16 blinks filtered (16 missing data events); quality : 85 percent
*) 12 blinks filtered (13 missing data events); quality : 88 percent
*) 13 blinks filtered (13 missing data events); quality : 88 percent
*) 14 blinks filtered (15 missing data events); quality : 89 percent
*) 17 blinks filtered (17 missing data events); quality : 86 percent
*) 11 blinks filtered (13 missing data events); quality : 88 percent
*) 14 blinks filtered (14 missing data events); quality : 89 percent
*) 5 blinks filtered ( 6 missing data events); quality : 92 percent
*) 27 blinks filtered (27 missing data events); quality : 82 percent
*) 3 blinks filtered ( 5 missing data events); quality : 95 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 8 blinks filtered (10 missing data events); quality : 93 percent
*) 28 blinks filtered (29 missing data events); quality : 82 percent
*) 14 blinks filtered (15 missing data events); quality : 88 percent
*) 9 blinks filtered (10 missing data events); quality : 90 percent
*) 57 blinks filtered (57 missing data events); quality : 68 percent
*) 63 blinks filtered (63 missing data events); quality : 66 percent
*) 36 blinks filtered (36 missing data events); quality : 77 percent
*) 12 blinks filtered (13 missing data events); quality : 87 percent
*) 30 blinks filtered (30 missing data events); quality : 77 percent
*) 74 blinks filtered (74 missing data events); quality : 63 percent
*) 1 blinks filtered ( 2 missing data events); quality : 96 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 95 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 3 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 3 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 100 percent
*) 0 blinks filtered ( 3 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 100 percent
*) 1 blinks filtered ( 3 missing data events); quality : 98 percent
*) 1 blinks filtered ( 3 missing data events); quality : 96 percent
*) 2 blinks filtered ( 3 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) 4 blinks filtered ( 5 missing data events); quality : 96 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 3 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 100 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 5 blinks filtered ( 5 missing data events); quality : 96 percent
*) 7 blinks filtered ( 8 missing data events); quality : 91 percent
*) 2 blinks filtered ( 3 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 3 blinks filtered ( 4 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 2 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 4 blinks filtered ( 6 missing data events); quality : 96 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 3 blinks filtered ( 5 missing data events); quality : 97 percent
*) 1 blinks filtered ( 3 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 100 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 2 blinks filtered ( 3 missing data events); quality : 97 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 98 percent
*) 4 blinks filtered ( 4 missing data events); quality : 96 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 1 blinks filtered ( 1 missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) blinks filtered ( missing data events); quality : 99 percent
*) 0 blinks filtered ( 1 missing data events); quality : 99 percent
*) 1 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 0 blinks filtered ( 2 missing data events); quality : 98 percent
*) 6 blinks filtered ( 8 missing data events); quality : 93 percent
*) 11 blinks filtered (12 missing data events); quality : 90 percent
*) 9 blinks filtered (10 missing data events); quality : 90 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 12 blinks filtered (12 missing data events); quality : 89 percent
*) 4 blinks filtered ( 6 missing data events); quality : 93 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 6 blinks filtered ( 7 missing data events); quality : 92 percent
*) 5 blinks filtered ( 7 missing data events); quality : 93 percent
*) 7 blinks filtered ( 9 missing data events); quality : 92 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 11 blinks filtered (11 missing data events); quality : 82 percent
*) 16 blinks filtered (16 missing data events); quality : 85 percent
*) 7 blinks filtered ( 8 missing data events); quality : 90 percent
*) 9 blinks filtered (10 missing data events); quality : 89 percent
*) 8 blinks filtered (10 missing data events); quality : 89 percent
*) 9 blinks filtered (10 missing data events); quality : 92 percent
*) 9 blinks filtered ( 9 missing data events); quality : 92 percent
*) 11 blinks filtered (11 missing data events); quality : 90 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 11 blinks filtered (11 missing data events); quality : 88 percent
*) 8 blinks filtered ( 9 missing data events); quality : 92 percent
*) 10 blinks filtered (11 missing data events); quality : 88 percent
*) 14 blinks filtered (14 missing data events); quality : 82 percent
*) 12 blinks filtered (12 missing data events); quality : 85 percent
*) 11 blinks filtered (11 missing data events); quality : 86 percent
*) 13 blinks filtered (13 missing data events); quality : 86 percent
*) 14 blinks filtered (14 missing data events); quality : 82 percent
*) 15 blinks filtered (15 missing data events); quality : 81 percent
*) 8 blinks filtered ( 9 missing data events); quality : 77 percent
*) 13 blinks filtered (13 missing data events); quality : 85 percent
*) 13 blinks filtered (13 missing data events); quality : 83 percent
*) 10 blinks filtered (10 missing data events); quality : 84 percent
*) 9 blinks filtered (10 missing data events); quality : 87 percent
*) 11 blinks filtered (12 missing data events); quality : 87 percent
*) 5 blinks filtered ( 6 missing data events); quality : 90 percent
*) 18 blinks filtered (18 missing data events); quality : 78 percent
*) 6 blinks filtered ( 8 missing data events); quality : 88 percent
*) 10 blinks filtered (11 missing data events); quality : 88 percent
*) 11 blinks filtered (12 missing data events); quality : 88 percent
*) 8 blinks filtered ( 9 missing data events); quality : 90 percent
*) 9 blinks filtered ( 9 missing data events); quality : 87 percent
*) 12 blinks filtered (12 missing data events); quality : 78 percent
*) 9 blinks filtered ( 9 missing data events); quality : 86 percent
*) 12 blinks filtered (12 missing data events); quality : 87 percent
*) 12 blinks filtered (12 missing data events); quality : 85 percent
*) 8 blinks filtered (10 missing data events); quality : 89 percent
*) 5 blinks filtered ( 6 missing data events); quality : 93 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 11 blinks filtered (11 missing data events); quality : 89 percent
*) 14 blinks filtered (14 missing data events); quality : 83 percent
*) 9 blinks filtered (10 missing data events); quality : 78 percent
*) 10 blinks filtered (11 missing data events); quality : 87 percent
*) 7 blinks filtered ( 8 missing data events); quality : 90 percent
*) 20 blinks filtered (20 missing data events); quality : 79 percent
*) 10 blinks filtered (10 missing data events); quality : 89 percent
*) 6 blinks filtered ( 8 missing data events); quality : 92 percent
*) 7 blinks filtered ( 9 missing data events); quality : 91 percent
*) 5 blinks filtered ( 7 missing data events); quality : 93 percent
*) 7 blinks filtered ( 9 missing data events); quality : 89 percent
*) 4 blinks filtered ( 5 missing data events); quality : 94 percent
*) 5 blinks filtered ( 6 missing data events); quality : 93 percent
*) 4 blinks filtered ( 5 missing data events); quality : 94 percent
*) 6 blinks filtered ( 8 missing data events); quality : 92 percent
*) 11 blinks filtered (11 missing data events); quality : 86 percent
*) 6 blinks filtered ( 8 missing data events); quality : 88 percent
*) 3 blinks filtered ( 6 missing data events); quality : 92 percent
*) 9 blinks filtered (10 missing data events); quality : 87 percent
*) 5 blinks filtered ( 7 missing data events); quality : 92 percent
*) 11 blinks filtered (12 missing data events); quality : 88 percent
*) 9 blinks filtered (10 missing data events); quality : 89 percent
*) 5 blinks filtered ( 6 missing data events); quality : 94 percent
*) 7 blinks filtered ( 9 missing data events); quality : 90 percent
*) 5 blinks filtered ( 7 missing data events); quality : 93 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 9 blinks filtered (10 missing data events); quality : 88 percent
*) 5 blinks filtered ( 7 missing data events); quality : 94 percent
*) 6 blinks filtered ( 7 missing data events); quality : 93 percent
*) 7 blinks filtered ( 8 missing data events); quality : 92 percent
*) 8 blinks filtered (10 missing data events); quality : 90 percent
*) 8 blinks filtered (10 missing data events); quality : 90 percent
*) 6 blinks filtered ( 6 missing data events); quality : 90 percent
*) 10 blinks filtered (10 missing data events); quality : 90 percent
*) 16 blinks filtered (16 missing data events); quality : 77 percent
*) 14 blinks filtered (14 missing data events); quality : 83 percent
*) 11 blinks filtered (11 missing data events); quality : 90 percent
*) 9 blinks filtered ( 9 missing data events); quality : 89 percent
*) 14 blinks filtered (14 missing data events); quality : 86 percent
*) 7 blinks filtered ( 8 missing data events); quality : 91 percent

View File

@ -0,0 +1,99 @@
function[obj] = label(obj, params)
%% extract labels from all MSG events
%% Step 1: read pattern from label_pattern (the varying part)
for p = 1:length(obj.label_patterns)
[token remainder] = strtok(obj.label_patterns{p},'%');
match{p} = strtrim(token);
if isempty(match{p})
match{p} = strtrim(strtok(remainder));
end
end
%% allocate only MSG events
msg_ind = regexp(obj.events_, 'MSG');
ind = find(~cellfun(@isempty,msg_ind));
l_ind = 1;
if (exist('match', 'var'))
for m = 1:length(match)
%% match all messages at once
s = regexp(obj.events_(ind), match{m});
m_ind = find(~cellfun(@isempty,s));
% m_ind now contains all events, that contain the match
for pe = 1:length(m_ind);
event_ind = ind(m_ind(pe));
label_timestamp= sscanf(obj.events_{event_ind},'%*s %d %*s');
pos = s{m_ind(pe)} + length(match{m});
obj.labels(l_ind).time = label_timestamp;
obj.labels(l_ind).label = strtrim(obj.events_{event_ind}(pos:end));
obj.labels(l_ind).match = match{m};
obj.labels(l_ind).type = 'normal';
obj.labels(l_ind).color = [0.4 0.4 0.4];
l_ind = l_ind + 1;
end
end
end
%% hook all matches up to stimuli
for t = 1:length(obj.trials)
trial = obj.trials(t);
%% in case no labels are defined, continue..
if (isempty(obj.labels))
continue;
end
for l = 1:length(obj.labels)
label_timestamps(l) = obj.labels(l).time(1);
end
% labels are set before or during
earlier_labels = find(label_timestamps < trial.trial_end);
later_labels = find(label_timestamps > trial.trial_start);
% variable is set during trial:
common = intersect(earlier_labels, later_labels);
if isempty(params.ForcePrecursorLabels)
params.ForcePrecursorLabels{2} = 0;
end
if (~params.ForcePrecursorLabels{2} && ~isempty(common))
trial.labels = obj.labels(common);
else
% no variables set during, perhaps a precursor variable?
if ~isempty(earlier_labels)
if t > 1
%% check later than previous trials
previous_trial = obj.trials(t-1);
later_than_previous = find(label_timestamps >= previous_trial.trial_end);
precursors = intersect(earlier_labels, later_than_previous);
trial.labels = obj.labels(precursors);
else
trial.labels = obj.labels(earlier_labels);
end
end
end
%% assign variables to trial in field 'type'
for l = 1:length(trial.labels)
varname = regexprep(trial.labels(l).match,'\s' ,'_');
trial.type.(varname) = trial.labels(l).label;
end
obj.trials(t) = trial;
end

View File

@ -0,0 +1,11 @@
function[obj] = loadData(obj)
if (exist(obj.datafile, 'file'))
obj.readASC
else
error(sprintf('File not found: %s', obj.datafile));
end

View File

@ -0,0 +1,11 @@
function[obj] = loadData(obj)
if (exist(obj.datafile, 'file'))
obj = obj.load_data_from_text;
else
error(sprintf('File not found: %s', obj.datafile));
end

View File

@ -0,0 +1,86 @@
function[obj] = load_data_from_text(obj )
%% load data from the .asc file
datafile = obj.datafile;
samples=[];
events ={};
load_processed_data = 0;
[base file ext] = fileparts(datafile);
target_dir = [base filesep file '.matlab'];
if (exist(target_dir, 'dir') == 0)
mkdir(target_dir);
end
cd(target_dir);
obj.display_and_log(['\tParsing file : ' file], 1);
obj.display_and_log(['\tDate : ' datestr(now)], 0);
target_raw = [target_dir filesep file '_raw.mat'];
target_processed = [target_dir filesep file '_processed.mat'];
if exist([target_dir filesep file '_processed.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_processed));
file_contents = load(target_processed);
data = file_contents.data;
load_processed_data = 1;
obj.events_ = data.events;
obj.samples = data.samples;
elseif exist([target_dir filesep file '_raw.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_raw));
file_contents= load(target_raw);
data = file_contents.data;
obj.events_ = data.events;
obj.samples = data.samples;
else
lc=0;
fp = fopen(datafile,'r');
i=1; j=1; m=1;
data_flag = 0;
[status lines_txt] = system(['wc ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
lines = str2num(lines_txt);
progressbar = waitbar(0, 'Reading data file...');
samples = nan(lines, 4);
while(~feof(fp))
if(mod(lc, 1000) ==0)
display(sprintf('working on line %5d', lc));
fprintf(repmat(sprintf('\b'),1,21));
waitbar(lc / lines, progressbar, sprintf('working on line %d', lc));
end
line=fgetl(fp);
if (data_flag & regexp(line, '^[0-9]*'))
samples(i,:) = sscanf(line, '%d %f %f %f');
i=i+1;
else
events{j} = line;
j=j+1;
end
if regexp(line,'^SAMPLES')
data_flag = 1;
end
lc=lc+1;
end
fclose(fp)
obj.samples = samples;
obj.events_ = events;
save(target_raw, 'obj');
close(progressbar);
end
%if ~load_processed_data
% [data] = preprocess_samples(data,settings);
%end

View File

@ -0,0 +1,40 @@
function[mean] = mean(session, varargin)
%% options : '''Trials', [list of trials]}, ...
% '''Type'', {raw|interpolated|filtered}'
% '''BaselineCorrected''0/1'
% '''Marker'', marker id'
% '''Settings''' , settings object
params = struct('Trials', [], ...
'Type', 'none', ...
'BaselineCorrected', 1, ...
'Marker', 'stimulus onset',...
'Settings', []);
params = parseparams(varargin);
if isempty(params.Trials)
params.Trials = 1:length(sessions.trials);
end
if isstruct(params.Settings)
threshold = params.Settings.QualityThreshold;
quality_values = [ session.trials(Trials).quality ];
trials_to_kill = find(quality_values < threshold);
%exclude trials that fail the quality measure
params.Trials = setdiff(params.Trials, trials_to_kill);
end
for t = 1:length(params.Trials)
trial_id = params.Trials(t);
trial = session.trials(trial_id);
[times{t} traces{t}] = trial.getTrialDataShiftedForMarker(marker_id);
end
if nargin == 1

View File

@ -0,0 +1,33 @@
function[session] = patternBuilder(session)
pbfig = figure;
pbevents = figure;
jList = java.util.ArrayList;
j=0;
for i = 1:length(session.events_)
if (strmatch('MSG', session.events_{i}))
jList.add(j,['<html><font name="Verdana" size=1><b>' session.events_{i} '</b></font></html>']);
j=j+1;
end
end
jCBList = com.mathworks.mwswing.checkboxlist.CheckBoxList(jList);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCBList);
posfig = get(gcf, 'Position');
posfig(1) = 0;
set(pbevents, 'Position', posfig);
posfig(1) = posfig(3)+10;
set(pbfig, 'Position' , posfig);
[jhCBList,hContainer] = javacomponent(jScrollPane,[20,20,posfig(3)-40,posfig(4)-40],gcf);
set(jCBList, 'ValueChangedCallback', @session.plotTrialBasedonPattern);
set(jCBList, 'Tag', 'msg_events');
jCBModel = jCBList.getCheckModel;
jCBModel.uncheckAll;
jCBModel.checkIndex(1);
get(jCBList, 'Tag')

View File

@ -0,0 +1,14 @@
function[session] = plotTrialBasedonPattern(varargin)
jListBox = varargin{1};
jEventData = varargin{2};
hListbox = varargin{3};
jCBModel = get(jEventData, 'CheckModel');
numChecks = jCBModel.getCheckedCount;
activeIndex = get(hListbox, 'SelectedIndex');
if (numChecks > 2)
jCBModel.uncheckAll;
jcBModel.checkIndex(activeIndex);
end

View File

@ -0,0 +1,22 @@
function[obj] = preprocess(obj, settings)
if strcmp(settings.Preprocessing.Type, 'trial')
for t = 1:length(obj.trials)
obj.trials(t) = obj.trials(t).preprocess(settings);
end
else
%% Session based preprocessing
obj = obj.remove_blinks(settings);
% Smooth the data
obj = obj.smooth(settings);
% Calculate logtransformed data
obj = obj.logtransform;
for t = 1:length(obj.trials)
obj.trials(t) = obj.trials(t).correct_for_baseline(settings);
obj.trials(t) = obj.trials(t).calculate_statistics;
end
end

View File

@ -0,0 +1,101 @@
function[obj] = read_ASC(obj)
%% low level function to read in asc data from Eyelink eyetracker data
datafile = obj.datafile;
samples=[];
events ={};
load_processed_data = 0;
eye = 'left'; %% default assume left eye
[base file ext] = fileparts(datafile);
target_dir = [base filesep file '.matlab'];
if (exist(target_dir, 'dir') == 0)
mkdir(target_dir);
end
cd(target_dir);
display(['Parsing file : ' file]);
%display_and_log(['Parsing file : ' file], 1);
%display_and_log(['Date : ' datestr(now)], 0);
target_raw = [target_dir filesep file '_raw.mat'];
target_processed = [target_dir filesep file '_processed.mat'];
settings.target_raw = target_raw;
settings.target_processed = target_processed;
if exist([target_dir filesep file '_processed.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_processed));
file_contents = load(target_processed);
obj = file_contents.obj;
%data = file_contents.data;
load_processed_data = 1;
elseif exist([target_dir filesep file '_raw.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_raw));
file_contents= load(target_raw);
data = file_contents.data;
else
lc=0;
fp = fopen(datafile,'r');
i=1; j=1; m=1;
data_flag = 0;
if (isunix)
cmd = ['wc ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}'];
cmd = regexprep(cmd,'\(', '\\('); cmd = regexprep(cmd,'\)', '\\)');
[status lines_txt] = system(cmd);
[status events_txt] = system(['grep -c "^[0-9*" ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
else
[status lines_txt] = system(['find /c ' datafile]);
end
lines = str2num(lines_txt);
nevents = str2num(events_txt);
progressbar = waitbar(0, 'Reading data file...');
samples = nan(lines, 4);
events = cell(1, nevents);
while(~feof(fp))
if(mod(lc, 1000) ==0)
% display(sprintf('working on line %d', lc));
waitbar(lc / lines, progressbar, sprintf('Reading data file ... : %d %%', round(100*(lc / lines))));
end
line=fgetl(fp);
if (data_flag & regexp(line, '^[0-9]*'))
samples(i,:) = sscanf(line, '%d %f %f %f %*s');
i=i+1;
else
events{j} = line;
j=j+1;
end
if regexp(line,'^SAMPLES')
data_flag = 1;
end
if regexp(line,'^START')
eye = sscanf(line, '%*s %*s %s %*s');
end
lc=lc+1;
end
fclose(fp);
data.samples = samples;
data.events = events;
data.eye = lower(eye);
save(target_raw, 'data');
close(progressbar);
end

View File

@ -0,0 +1,93 @@
function[obj] = readASC(obj)
%% low level function to read in asc data from Tobii eyetracker data
datafile = obj.datafile;
samples=[];
events ={};
load_processed_data = 0;
[base file ext] = fileparts(datafile);
target_dir = [base filesep file '.matlab'];
if (exist(target_dir, 'dir') == 0)
mkdir(target_dir);
end
cd(target_dir);
display(['Parsing file : ' file]);
%display_and_log(['Parsing file : ' file], 1);
%display_and_log(['Date : ' datestr(now)], 0);
target_raw = [target_dir filesep file '_raw.mat'];
target_processed = [target_dir filesep file '_processed.mat'];
settings.target_raw = target_raw;
settings.target_processed = target_processed;
if exist([target_dir filesep file '_processed.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_processed));
file_contents = load(target_processed);
data = file_contents.data;
load_processed_data = 1;
elseif exist([target_dir filesep file '_raw.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_raw));
file_contents= load(target_raw);
data = file_contents.data;
else
lc=0;
fp = fopen(datafile,'r');
i=1; j=1; m=1;
data_flag = 0;
if (isunix)
[status lines_txt] = system(['wc ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
[status events_txt] = system(['grep -c "^[0-9*" ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
else
[status lines_txt] = system(['find /c ' datafile]);
end
lines = str2num(lines_txt);
nevents = str2num(events_txt);
progressbar = waitbar(0, 'Reading data file...');
samples = nan(lines, 4);
events = cell(1, nevents);
header =fgetl(fp);
params = strsplit(header, '\t');
pupil_params = find(~cellfun(@isempty,strfind(params, 'Pupil')));
while(~feof(fp))
if(mod(lc, 1000) ==0)
% display(sprintf('working on line %d', lc));
waitbar(lc / lines, progressbar, sprintf('Reading data file ... : (%f)', round(100*(lc / lines))));
end
line=fgetl(fp);
pattern = ['%*d %*d %*d %d ' repmat('%*f ', 1, pupil_params(1)-5) '%f %*s']
if (data_flag & regexp(line, '^[0-9]*'))
samples(i,:) = sscanf(line, '%*d %*d %*d %d %f %*s');
i=i+1;
else
events{j} = line;
j=j+1;
end
if regexp(line,'^SAMPLES')
data_flag = 1;
end
lc=lc+1;
end
fclose(fp)
data.samples = samples;
data.events = events;
save(target_raw, 'data');
close(progressbar);
end

View File

@ -0,0 +1,94 @@
function[obj] = readASC(obj)
%% low level function to read in asc data from Tobii eyetracker data
datafile = obj.datafile;
samples=[];
events ={};
load_processed_data = 0;
[base file ext] = fileparts(datafile);
target_dir = [base filesep file '.matlab'];
if (exist(target_dir, 'dir') == 0)
mkdir(target_dir);
end
cd(target_dir);
display(['Parsing file : ' file]);
%display_and_log(['Parsing file : ' file], 1);
%display_and_log(['Date : ' datestr(now)], 0);
target_raw = [target_dir filesep file '_raw.mat'];
target_processed = [target_dir filesep file '_processed.mat'];
settings.target_raw = target_raw;
settings.target_processed = target_processed;
if exist([target_dir filesep file '_processed.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_processed));
file_contents = load(target_processed);
data = file_contents.data;
load_processed_data = 1;
elseif exist([target_dir filesep file '_raw.mat'], 'file');
display(sprintf('*) Loading data from file : %s', target_raw));
file_contents= load(target_raw);
data = file_contents.data;
else
lc=0;
fp = fopen(datafile,'r');
i=1; j=1; m=1;
data_flag = 0;
if (isunix)
[status lines_txt] = system(['wc ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
[status events_txt] = system(['grep -c "^[0-9*" ' regexprep(datafile,' ', '\\ ') '|awk ''{print $1''}']);
else
[status lines_txt] = system(['find /c ' datafile]);
end
lines = str2num(lines_txt);
nevents = str2num(events_txt);
progressbar = waitbar(0, 'Reading data file...');
samples = nan(lines, 4);
events = cell(1, nevents);
header =fgetl(fp);
params = strsplit(header, '\t');
pupil_params = strfind(param
while(~feof(fp))
if(mod(lc, 1000) ==0)
% display(sprintf('working on line %d', lc));
waitbar(lc / lines, progressbar, sprintf('Reading data file ... : (%f)', round(100*(lc / lines))));
end
line=fgetl(fp);
if (data_flag & regexp(line, '^[0-9]*'))
samples(i,:) = sscanf(line, '%d %f %f %f %*s');
i=i+1;
else
events{j} = line;
j=j+1;
end
if regexp(line,'^SAMPLES')
data_flag = 1;
end
lc=lc+1;
end
fclose(fp)
data.samples = samples;
data.events = events;
save(target_raw, 'data');
close(progressbar);
end

View File

@ -0,0 +1,234 @@
function[objs] = rebuild(objs, params);
%% PDSession.rebuild
%
% based on patterns parse the datafile and create trials
%
i=1; i1=1;i2=1;i3=1;
progressbar = waitbar(0, 'Parsing trial data...','Visible', 'off');
p= get(progressbar, 'Position'); p(2)=p(2)+100;
set(progressbar,'Position', p, 'Color', [1 1 1]);
t = get(get(progressbar, 'Children'), 'Title');
set(t, 'FontSize', 15, 'FontWeight', 'bold', 'FontName', 'Tahoma');
set(progressbar,'Visible','on');
for o = 1:length(objs)
obj = objs(o);
new_trial = PDTrial;
obj = obj.check_patterns;
dependencies.trial_start= [];
dependencies.trial_end = [];
dependencies.baseline_onset = [];
dependencies.baseline_offset = [];
dependencies.stimulus_onset = [];
dependencies.stimulus_offset = [];
%% fill in all relative pattern timings :
%% TODO : add previous relative items inhere
if iscell(obj.trial_start_pattern),
ind = length(dependencies);
eval(['dependencies.' obj.trial_start_pattern{2} ' = {''trial_start'' ' num2str(obj.trial_start_pattern{1}) '};']);
end
if iscell(obj.trial_end_pattern),
ind = length(dependencies);
eval(['dependencies.' obj.trial_end_pattern{2} '{' num2str(ind) '} = {''trial_end'' ' num2str(obj.trial_end_pattern{1}) '};']);
end
if iscell(obj.baseline_onset_pattern),
%display('Dependency found for baseline onset pattern');
eval(['ind = size(dependencies.' obj.baseline_onset_pattern{2} ', 2) +1;']);
eval(['dependencies.' obj.baseline_onset_pattern{2} '{' num2str(ind) '} = {''baseline_onset'' ' num2str(obj.baseline_onset_pattern{1}) '};']);
end
if iscell(obj.baseline_offset_pattern),
%display('Dependency found for baseline offset pattern');
eval(['ind = size(dependencies.' obj.baseline_offset_pattern{2} ', 2) +1;']);
eval(['dependencies.' obj.baseline_offset_pattern{2} '{' num2str(ind) '} = {''baseline_offset'' ' num2str(obj.baseline_offset_pattern{1}) '};']);
end
if iscell(obj.stimulus_onset_pattern),
eval(['ind = size(dependencies.' obj.stimulus_onset_pattern{2} ', 2) +1;']);
eval(['dependencies.' obj.stimulus_onset_pattern{2} '{' num2str(ind) '} = {''stimulus_onset'' ' num2str(obj.stimulus_onset_pattern{1}) '};']);
end
if iscell(obj.stimulus_offset_pattern),
eval(['ind = size(dependencies.' obj.stimulus_offset_pattern{2} ', 2) +1;']);
eval(['dependencies.' obj.stimulus_offset_pattern{2} '{' num2str(ind) '} = {''stimulus_offset'' ' num2str(obj.stimulus_offset_pattern{1}) '};']);
end
%% go through all events
msg_indices = strmatch('MSG',obj.events_);
%% these checks can be performed outside of the for-loop
itsp = ischar(obj.trial_start_pattern);
itep = ischar(obj.trial_end_pattern);
ibon = ischar(obj.baseline_onset_pattern);
ibof = ischar(obj.baseline_offset_pattern);
ison = ischar(obj.stimulus_onset_pattern);
isof = ischar(obj.stimulus_offset_pattern);
dep_ts = ~isempty(dependencies.trial_start);
dep_te = ~isempty(dependencies.trial_end);
dep_bon = ~isempty(dependencies.baseline_onset);
dep_bof = ~isempty(dependencies.baseline_offset);
dep_son = ~isempty(dependencies.stimulus_onset);
dep_sof = ~isempty(dependencies.stimulus_offset);
ii=1;
for e_i = 1:length(msg_indices) %1:length(obj.events_)
e = msg_indices(e_i);
%% a new trial marker has been found
if (itsp && ~isempty(regexp(obj.events_{e}, obj.trial_start_pattern)))
%% if trial_start has been set, a new trial starts
if ~isempty(new_trial.trial_start)
%% reset trial_end to new trial_start
if (strcmp(obj.trial_start_pattern, obj.trial_end_pattern) == 1)
time = sscanf(obj.events_{e},'%*s %d %*s %*s');
new_trial.trial_end = time(1);
end
trial_samples = intersect(find(obj.samples(:,1) > new_trial.trial_start), ...
find(obj.samples(:,1) < new_trial.trial_end));
new_trial.time = obj.samples(trial_samples, 1);
new_trial.data.(obj.eye).uncorrected.raw = obj.samples(trial_samples, 4);
obj.trials(i) = new_trial;
new_trial = PDTrial;
i=i+1;
if (mod(i,10)==0) % updating waitbar is very time consuming
waitbar(e_i/length(msg_indices), progressbar, sprintf('Session: %s - Parsing data for trial %d...', obj.name, i));
end
end
%% no previous trial was defined
time = sscanf(obj.events_{e},'%*s %d %*s %*s');
new_trial.trial_start = time(1); %% disregard optional numbers in the message
if dep_ts
for db = 1:length(dependencies.trial_start)
dependency = dependencies.trial_start{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.trial_start) ' + ' num2str(dependency{2}) ';']);
end
end
end
%% a new baseline marker (onset) has been found
if (ibon && ~isempty(regexp(obj.events_{e}, obj.baseline_onset_pattern)))
new_trial.baseline_onset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_bon
for db = 1:length(dependencies.baseline_onset)
dependency = dependencies.baseline_onset{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.baseline_onset) ' + ' num2str(dependency{2}) ';']);
end
end
end
%% a new baseline marker (offset) has been found
if (ibof && ~isempty(regexp(obj.events_{e}, obj.baseline_offset_pattern)))
new_trial.baseline_offset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_bof
for db = 1:length(dependencies.baseline_offset)
dependency = dependencies.baseline_offset{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.baseline_offset) ' + ' num2str(dependency{2}) ';']);
end
end
end
%% a new stimulus onset marker has been found
if (ison && ~isempty(regexp(obj.events_{e}, obj.stimulus_onset_pattern)))
new_trial.stimulus_onset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_son
for db = 1:length(dependencies.stimulus_onset)
dependency = dependencies.stimulus_onset{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.stimulus_onset) ' + ' num2str(dependency{2}) ';']);
end
end
end
%% a new stimulus offset marker has been found
if (isof && ~isempty(regexp(obj.events_{e}, obj.stimulus_offset_pattern)))
new_trial.stimulus_offset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_sof
for db = 1:length(dependencies.stimulus_offset)
dependency = dependencies.stiulus_offset{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.stimulus_offset) ' + ' num2str(dependency{2}) ';']);
end
end
end
%% a new trial end marker has been found
if ~isempty(new_trial.trial_end)
else
%% if trial_start == trial_end matching, skip the current line
if (strcmp(obj.trial_start_pattern, obj.trial_end_pattern) == 1)
continue;
end
if (itep && ~isempty(regexp(obj.events_{e}, obj.trial_end_pattern)))
end_time = sscanf(obj.events_{e},'%*s %d %*s %*s');
new_trial.trial_end = end_time(1); % disregard numbers in message
if dep_te
for db = 1:length(dependencies.trial_end)
dependency = dependencies.trial_end{db};
eval(['new_trial.' dependency{1} ' = ' num2str(new_trial.trial_end) ' + ' num2str(dependency{2}) ';']);
end
end
if (isempty(new_trial.trial_start))
warning('Trial end detected, but no previous Trial start has been found : skipping trial');
end
%% [trialdata_i quality_i qc_i blink_list_i] = preprocess_trial(data.samples(total_trial_ind,:), settings, sprintf('Trial %2d',i));
end
end
end
%% add the final trial
if (~isempty(new_trial.trial_start) & ~isempty(new_trial.trial_end))
trial_samples = intersect(find(obj.samples(:,1) > new_trial.trial_start), ...
find(obj.samples(:,1) < new_trial.trial_end));
new_trial.time = obj.samples(trial_samples, 1);
new_trial.data.(obj.eye).uncorrected.raw = obj.samples(trial_samples, 4);
obj.trials(i) = new_trial;
end
close(progressbar);
obj = label(obj, params);
% data.trialdata.indices = trial_indices;
% data.trialdata.indices_description = {'Fixation6s starting','Stimulus Presentation','Fixation15s starting','Fixation15s ending'};
% data.baseline.start = baseline_start;
% data.baseline.end = baseline_end;
% baseline = [];
% for b = 1: length(data.baseline.data)
% baseline = [baseline data.baseline.data{b}];
% end
% cumulative = cumsum(hist(baseline, 10000));
%%turning_points = find(diff(cumulative) > 1000);
%%data.baseline.cumulative = cumulative;
%%data.baseline.mean = mean(data.baseline.cumulative(1:turning_points(1)));
objs(o) = obj;
end

View File

@ -0,0 +1,269 @@
function[obj] = rebuildMulti(obj);
%% assertions:
i=1; i1=1;i2=1;i3=1;
progressbar = waitbar(0, 'Parsing trial data...','Visible', 'off');
p= get(progressbar, 'Position'); p(2)=p(2)+100;
set(progressbar,'Position', p, 'Color', [1 1 1]);
t = get(get(progressbar, 'Children'), 'Title');
set(t, 'FontSize', 15, 'FontWeight', 'bold', 'FontName', 'Tahoma');
set(progressbar,'Visible','on');
new_trial = PDTrial;
obj = obj.check_patterns;
dependencies.trial_start= [];
dependencies.trial_end = [];
dependencies.baseline_onset = [];
dependencies.baseline_offset = [];
dependencies.stimulus_onset = [];
dependencies.stimulus_offset = [];
current_pattern.trial_start_pattern = 1;
current_pattern.trial_end_pattern = 1;
current_pattern.stimulus_onset_pattern = 1;
current_pattern.stimulus_offset_pattern = 1;
current_pattern.baseline_onset_pattern = 1;
current_pattern.baseline_offset_pattern = 1;
%% fill in all relative pattern timings :
for i = 1:length(obj.trial_start_pattern)
if iscell(obj.trial_start_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.trial_start_pattern(i).pattern{2} ' = {''trial_start'' ' num2str(obj.trial_start_pattern(i).pattern{1}) '};']);
end
end
for i = 1:length(obj.trial_end_pattern)
if iscell(obj.trial_end_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.trial_end_pattern(i).pattern{2} ' = {''trial_end'' ' num2str(obj.trial_end_pattern(i).pattern{1}) '};']);
end
end
for i = 1:length(obj.baseline_onset_pattern)
if iscell(obj.baseline_onset_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.baseline_onset_pattern(i).pattern{2} ' = {''baseline_onset'' ' num2str(obj.baseline_onset_pattern(i).pattern{1}) '};']);
end
end
for i = 1:length(obj.baseline_offset_pattern)
if iscell(obj.baseline_offset_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.baseline_offset_pattern(i).pattern{2} ' = {''baseline_offset'' ' num2str(obj.baseline_offset_pattern(i).pattern{1}) '};']);
end
end
for i = 1:length(obj.stimulus_onset_pattern)
if iscell(obj.stimulus_onset_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.stimulus_onset_pattern(i).pattern{2} ' = {''stimulus_onset'' ' num2str(obj.stimulus_onset_pattern(i).pattern{1}) '};']);
end
end
for i = 1:length(obj.stimulus_offset_pattern)
if iscell(obj.stimulus_offset_pattern(i).pattern),
eval(['dependencies(' num2str(i) ').' obj.stimulus_offset_pattern(i).pattern{2} ' = {''stimulus_onset'' ' num2str(obj.stimulus_offset_pattern(i).pattern{1}) '};']);
end
end
%% go through all events
msg_indices = strmatch('MSG',obj.events_);
% tmp = sscanf(obj.events_{e}, '%*s %d %*s');
% data.msg_events(i,1) = tmp(1);
% data.msg_events(i,2) = e;
% i3=i3+1;
% end
%% these checks can be performed outside of the for-loop
itsp = ischar(obj.trial_start_pattern(current_pattern.trial_start).pattern);
itep = ischar(obj.trial_end_pattern(current_pattern.trial_end).pattern;
ibon = ischar(obj.baseline_onset_pattern(current_pattern.baseline_onest).pattern;
ibof = ischar(obj.baseline_offset_pattern(current_pattern.baseline_offset).pattern;
ison = ischar(obj.stimulus_onset_pattern(current_pattern.stimulus_onset).pattern);
isof = ischar(obj.stimulus_offset_pattern(current_pattern.stimulus_offset).pattern);
dep_ts = ~isempty(dependencies(current_pattern.trial_start).trial_start);
dep_te = ~isempty(dependencies(current_pattern.trial_end).trial_end);
dep_bon = ~isempty(dependencies(current_pattern.baseline_onset).baseline_onset);
dep_bof = ~isempty(dependencies(current_pattern.baseline_offset).baseline_offset);
dep_son = ~isempty(dependencies(current_pattern.stimulus_onset).stimulus_onset);
dep_sof = ~isempty(dependencies(current_pattern.stimulus_offset).stimulus_offset);
ii=1;
previous_trial_e_i = 1;
%for e_i = 1:length(msg_indices) %1:length(obj.events_)
while e_i <= length(msg_indices);
e = msg_indices(e_i);
%% a new trial marker has been found
if (itsp && ~isempty(regexp(obj.events_{e}, obj.trial_start_pattern(current_pattern.trial_start).pattern)))
rescan_trial = 0;
if isempty(new_trial.trial_end)
current_pattern.trial_end = current_pattern.trial_end + 1;
itsp = ischar(obj.trial_start_pattern(current_pattern.trial_start).pattern);
dep_ts = ~isempty(dependencies(current_pattern.trial_start).trial_start);
if current_pattern.trial_end <= length(obj.trial_start_pattern)
rescan_trial = 1;
end
end
if isempty(new_trial.stimulus_onset)
current_pattern.stimulus_onset = current_pattern.stimulus_onset + 1;
ison = ischar(obj.stimulus_onset_pattern(current_pattern.stimulus_onset).pattern);
dep_son = ~isempty(dependencies(current_pattern.stimulus_onset).stimulus_onset);
if current_pattern.stimulus_onset <= length(obj.stimulus_onset_pattern)
rescan_trial = 1;
end
end
if isempty(new_trial.stimulus_offset)
current_pattern.stimulus_offset = current_pattern.stimulus_offset + 1;
isof = ischar(obj.stimulus_offset_pattern(current_pattern.stimulus_offset).pattern);
dep_sof = ~isempty(dependencies(current_pattern.stimulus_offset).stimulus_offset);
if current_pattern.stimulus_offset <= length(obj.stimulus_offset_pattern)
rescan_trial = 1;
end
end
if isempty(new_trial.baseline_offset)
current_pattern.baseline_offset = current_pattern.baseline_offset + 1;
ibof = ischar(obj.baseline_offset_pattern(current_pattern.baseline_offset).pattern;
dep_bof = ~isempty(dependencies(current_pattern.baseline_offset).baseline_offset
if current_pattern.baseline_offset <= length(obj.baseline_offset_pattern)
rescan_trial = 1;
end
end
if isempty(new_trial.baseline_onset)
current_pattern.baseline_onset = current_pattern.baseline_onset + 1;
ibon = ischar(obj.baseline_onset_pattern(current_pattern.baseline_onest).pattern;
dep_bof = ~isempty(dependencies(current_pattern.baseline_offset).baseline_offset);
if current_pattern.baseline_onset <= length(obj.baseline_onset_pattern)
rescan_trial = 1;
end
end
if (rescan_trial)
e_i = previous_trial_e_i;
continue;
end
%% if trial_start has been set, a new trial starts
if ~isempty(new_trial.trial_start)
trial_samples = intersect(find(obj.samples(:,1) > new_trial.trial_start), ...
find(obj.samples(:,1) < new_trial.trial_end));
new_trial.time = obj.samples(trial_samples, 1);
new_trial.data.uncorrected.raw = obj.samples(trial_samples, 4);
obj.trials(i) = new_trial;
new_trial = PDTrial;
previous_trial_e_i = e_i;
i=i+1;
if (mod(i,10)==0) % updating waitbar is very time consuming
waitbar(e_i/length(msg_indices), progressbar, sprintf('Session: %s - Parsing data for trial %d...', obj.name, i));
end
end
new_trial.trial_start = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_ts
eval(['new_trial.' dependencies(current_pattern.trial_start).trial_start{1} ' = ' num2str(new_trial.trial_start) ' + ' num2str(dependencies(current_pattern.trial_start).trial_start{2}) ';']);
end
end
%% a new baseline marker (offset) has been found
if (ibon && ~isempty(regexp(obj.events_{e}, obj.baseline_onset_pattern(current_pattern.baseline_onset).pattern)))
new_trial.baseline_onset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_bon
eval(['new_trial.' dependencies(current_pattern.baseline_onset).baseline_onset{1} ' = ' num2str(new_trial.baseline_onset) ' + ' num2str(dependencies(current_pattern.baseline_onset).baseline_onset{2}) ';']);
end
end
%% a new baseline marker (offset) has been found
if (ibof && ~isempty(regexp(obj.events_{e}, obj.baseline_offset_pattern(current_pattern.baseline_offset).pattern)))
new_trial.baseline_offset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_bof
eval(['new_trial.' dependencies((current_pattern.baseline_onset).baseline_offset{1} ' = ' num2str(new_trial.baseline_offset) ' + ' num2str(dependencies(current_pattern.baseline_onset).baseline_offset{2}) ';']);
end
end
%% a new stimulus onset marker has been found
if (ison && ~isempty(regexp(obj.events_{e}, obj.stimulus_onset_pattern(current_pattern.stimulus_onset).pattern)))
new_trial.stimulus_onset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_son
eval(['new_trial.' dependencies(current_pattern.stimulus_onset).stimulus_onset{1} ' = ' num2str(new_trial.stimulus_onset) ' + ' num2str(dependencies(current_pattern.stimulus_onset).stimulus_onset{2}) ';']);
end
end
%% a new stimulus offset marker has been found
if (isof && ~isempty(regexp(obj.events_{e}, obj.stimulus_offset_pattern(current_pattern.stimulus_offset).pattern)))
new_trial.stimulus_offset = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_bof
eval(['new_trial.' dependencies(current_pattern.stimulus_offset).stimulus_offset{1} ' = ' num2str(new_trial.stimulus_offset) ' + ' num2str(dependencies(current_pattern.stimulus_offset).stimulus_offset{2}) ';']);
end
end
%% a new trial end marker has been found
if ~isempty(new_trial.trial_end)
else
if (itep && ~isempty(regexp(obj.events_{e}, obj.trial_end_pattern(current_pattern.trial_end).pattern)))
new_trial.trial_end = sscanf(obj.events_{e},'%*s %d %*s %*s');
if dep_te
eval(['new_trial.' dependencies(current_pattern.trial_end).trial_end ' = ' num2str(new_trial.time) ' + ' num2str(dependencies(current_pattern.trial_end).trial_end{2}) ';']);
end
if (isempty(new_trial.trial_start))
warning('Trial end detected, but no previous Trial start has been found : skipping trial');
end
%% [trialdata_i quality_i qc_i blink_list_i] = preprocess_trial(data.samples(total_trial_ind,:), settings, sprintf('Trial %2d',i));
end
end
end
%% add the final trial
trial_samples = intersect(find(obj.samples(:,1) > new_trial.trial_start), ...
find(obj.samples(:,1) < new_trial.trial_end));
new_trial.time = obj.samples(trial_samples, 1);
new_trial.data.uncorrected.raw = obj.samples(trial_samples, 4);
obj.trials(i) = new_trial;
close(progressbar);
obj = label(obj);
% data.trialdata.indices = trial_indices;
% data.trialdata.indices_description = {'Fixation6s starting','Stimulus Presentation','Fixation15s starting','Fixation15s ending'};
% data.baseline.start = baseline_start;
% data.baseline.end = baseline_end;
% baseline = [];
% for b = 1: length(data.baseline.data)
% baseline = [baseline data.baseline.data{b}];
% end
% cumulative = cumsum(hist(baseline, 10000));
%%turning_points = find(diff(cumulative) > 1000);
%%data.baseline.cumulative = cumulative;
%%data.baseline.mean = mean(data.baseline.cumulative(1:turning_points(1)));

View File

@ -0,0 +1,6 @@
function[obj] = removeDuplicateLabels(obj)
for t = 1:length(obj.trials)
obj.trials(t) = obj.trials(t).removeDuplicateLabels;
end

View File

@ -0,0 +1,76 @@
fun
tion[obj] = remove_blinks(obj, settings)
%% session based removal of blinks
data_column = 4;
eyes = fieldnames(obj.data);
for e = 1:length(eyes)
eye = eyes{e};
signal = obj.data.(eye).uncorrected.raw;
%no data available for eye
if isempty(signal)
continue
end
%% Kill the missing datapoints
missing = find(obj.time == signal);
signal(missing) = NaN;
%% store original signal for reference
obj.data.(eye).uncorrected.raw = signal;
obj.blink_count.(eye) = 0;
obj.missing_data_count.(eye) = 0;
%% Kill the blinks (pupil dilation dip)
nans = find(isnan(signal));
%% Count the NaNs before extending them.
nans=find(isnan(signal));
dnans = diff(nans);
missing_data_list = find(dnans>1);
missing_data_count = 0;
if ~isempty(missing_data_list)
blink_list(:,1) = nans(missing_data_list);
blink_list(:,2) = dnans(missing_data_list);
blink_list(:,3) = dnans(missing_data_list) < settings.MaximumBlinkSize;
obj.blink_count.(eye) = length(find(blink_list(:,3)));
obj.missing_data_count.(eye) = length(missing_data_list);
obj.blinks.(eye) = blink_list;
end
%% Extend the NaNs
for n = 1:length(nans)
window = [nans(n)-settings.BlinkExtension(1):nans(n)+settings.BlinkExtension(2)];
window(find(window<1)) = []; %% kill the negative indices for early blinks
signal(window) = NaN;
end
if isempty(obj.blink_count.(eye))
obj.blink_count.(eye) = 0;
end
if isempty(obj.missing_data_count.(eye))
obj.missing_data_count.(eye) = 0;
end
%% determine quality;
obj.quality.(eye) = 100 - (length(find(isnan(signal))) / length(signal)*100);
obj.valid = 1;
if (obj.quality.(eye) < settings.QualityThreshold)
obj.display_and_log(sprintf('\t*) %2d blinks filtered (%2d missing data events); quality : %2d percent -> Trial excluded\n', obj.blink_count.(eye), obj.missing_data_count.(eye),round(obj.quality.(eye))));
obj.valid.(eye) = 0;
else
obj.display_and_log(sprintf('\t*) %2d blinks filtered (%2d missing data events); quality : %2d percent', obj.blink_count.(eye), obj.missing_data_count.(eye),round(obj.quality.(eye))));
end
%% Interpolate NaNs
signal= obj.inpaint_nans(signal);
obj.data.(eye).uncorrected.interpolated = signal;
end

View File

@ -0,0 +1,100 @@
function[obj] = setFailSafePatternRelativeToPattern(obj, relativeTotype,type, timing)
%% Specify a new marker/pattern relative in time to an existing pattern
% time should be milliseconds (ms).
if ~isnumeric(timing)
error('Timing is not numeric');
end
ton_codings = {'trial onset','trial on', 'start trial', 'trial start', 'trial_start'};
toff_codings = {'trial offset','trial off', 'end trial', 'trial end', 'trial_end'};
son_codings = {'stimulus onset','stimulus on', 'soa', 'stim on', 'stim_on'};
soff_codings = {'stimulus offset','stimulus off', 'stim off', 'stim_off'};
bon_codings = {'baseline on', 'baseline start', 'baseline onset', 'bl on', 'bl'};
boff_codings = {'baseline off', 'baseline end', 'baseline offset', 'bl off'};
%% check whether the type exists, otherwise no failsafe is possible
ton = ismember(lower(type), ton_codings);
toff = ismember(lower(type), toff_codings);
son = ismember(lower(type), son_codings);
soff = ismember(lower(type), soff_codings);
bon = ismember(lower(type), bon_codings);
boff = ismember(lower(type), boff_codings);
type_list = [ton toff son soff bon boff];
existing_type_ind = find(type_list==1);
if isempty(existing_type_ind)
error('No correct type entered');
else
err=0;
switch typeexisting_type_ind_ind
case 1
if (isempty(obj.trial_start_pattern)), err=1; else target = 'trial_start'; end
case 2
if (isempty(obj.trial_end_pattern)), err=1; else target = 'trial_end'; end
case 3
if (isempty(obj.stimulus_onset_pattern)), err=1; else target = 'stimulus_onset'; end
case 4
if (isempty(obj.stimulus_offset_pattern)), err=1; else target = 'stimulus_offset'; end
case 5
if (isempty(obj.baseline_onset_pattern)), err=1; else target = 'baseline_onset'; end
case 6
if (isempty(obj.baseline_offset_pattern)), err=1; else target = 'baseline_offset'; end
end
end
if err
error('Failsafe for empty type is not allowed');
end
%% check for valid relativeTotype
ton = ismember(lower(relativeTotype), ton_codings);
toff = ismember(lower(relativeTotype), toff_codings);
son = ismember(lower(relativeTotype), son_codings);
soff = ismember(lower(relativeTotype), soff_codings);
bon = ismember(lower(relativeTotype), bon_codings);
boff = ismember(lower(relativeTotype), boff_codings);
types = [ton toff son soff bon boff];
type_ind = find(types==1);
if isempty(type_ind)
error('No correct type entered');
else
err=0;
switch type_ind
case 1
if (isempty(obj.trial_start_pattern)), err=1; else target = 'trial_start'; end
case 2
if (isempty(obj.trial_end_pattern)), err=1; else target = 'trial_end'; end
case 3
if (isempty(obj.stimulus_onset_pattern)), err=1; else target = 'stimulus_onset'; end
case 4
if (isempty(obj.stimulus_offset_pattern)), err=1; else target = 'stimulus_offset'; end
case 5
if (isempty(obj.baseline_onset_pattern)), err=1; else target = 'baseline_onset'; end
case 6
if (isempty(obj.baseline_offset_pattern)), err=1; else target = 'baseline_offset'; end
end
end
if err
error('Dependent type has not been defined');
end
if (ismember(lower(type), ton_codings)) obj.trial_start_pattern = {timing target}; end
if (ismember(lower(type), toff_codings)) obj.trial_end_pattern = {timing target}; end
if (ismember(lower(type), son_codings)) obj.stimulus_onset_pattern = {timing target}; end
if (ismember(lower(type), soff_codings)) obj.stimulus_onset_pattern = {timing target}; end
if (ismember(lower(type), bon_codings)) obj.baseline_onset_pattern = {timing target}; end
if (ismember(lower(type), boff_codings)) obj.baseline_offset_pattern = {timing target}; end

View File

@ -0,0 +1,16 @@
function[obj] = setFramerate(obj)
if exist(obj.datafile, 'file')
datafile = regexprep(obj.datafile, ' ','\\ ');
[status sampling_rate_str] = system(['grep FRAMERATE ' datafile '|awk ''{print $4}''']);
if ischar(sampling_rate_str)
obj.sampling_rate = str2num(sampling_rate_str);
end
%% display(sprintf('\t\tFramerate : %3.2f Hz', obj.sampling_rate));
end

View File

@ -0,0 +1,35 @@
function[objs] = setLabel(objs, pattern)
%% define possible coding styles of markers
if (~ischar(pattern))
error('Pattern must be character array')
end
%% check for existing patterns
for o = 1:length(objs)
obj = objs(o);
for l = 1:length(obj.label_patterns)
if strcmp(obj.label_patterns{l}, pattern)
display('Label already specified.');
return;
end
end
if isempty(obj.label_patterns)
obj.label_patterns{1} = pattern;
else
if iscell(obj.label_patterns);
for i = 1:length(obj.label_patterns)
obj.label_patterns{i} = obj.label_patterns{i};
end
obj.label_patterns{i+1} = pattern;
end
end
objs(o) = obj;
end

View File

@ -0,0 +1,17 @@
function[obj] = setLabelRelativeToLabel(objs, target, name, time)
%% define possible coding styles of markers
if (~ischar(name))
error('Pattern must be character array')
end
%% lookup label_pattern:
label_ind = find(~cellfun(@isempty,regexp(obj.label_patterns, target)));
if isempty(item)
error(sprintf('Target label is unknown: %s', target));
end
e.subjects.sessions.label_dependencies{label_ind} = {name time};

View File

@ -0,0 +1,17 @@
function[obj] = setLabelRelativeToPattern(objs, target, name, time)
%% define possible coding styles of markers
if (~ischar(name))
error('Pattern must be character array')
end
%% lookup label_pattern:
label_ind = find(~cellfun(@isempty,regexp(obj.label_patterns, target)));
if isempty(item)
error(sprintf('Target label is unknown: %s', target));
end
e.subjects.sessions.label_dependencies{label_ind} = {name time};

View File

@ -0,0 +1,50 @@
function[objs] = setPattern(objs, type, pattern)
%% define possible coding styles of markers
ton_codings = {'trial onset','trial on', 'start trial', 'trial start', 'trial_start'};
toff_codings = {'trial offset','trial off', 'end trial', 'trial end', 'trial_end'};
son_codings = {'stimulus onset','stimulus on', 'soa', 'stim on', 'stim_on', 'stimulus start', 'stim_start'};
soff_codings = {'stimulus offset','stimulus off', 'stim off', 'stim_off', 'stim end', 'stim_end'};
bon_codings = {'baseline on', 'baseline start', 'baseline onset', 'bl on', 'bl'};
boff_codings = {'baseline off', 'baseline end', 'baseline offset', 'bl off'};
if (~ischar(pattern))
error('Pattern must be character array')
end
for i = 1:length(objs)
obj = objs(i);
%% trial onset
if (ismember(lower(type), ton_codings))
obj.trial_start_pattern = pattern;
end
if (ismember(lower(type), toff_codings))
obj.trial_end_pattern = pattern;
end
%% stimulus onset
if (ismember(lower(type), son_codings))
obj.stimulus_onset_pattern = pattern;
end
%% stimulus offset
if (ismember(lower(type), soff_codings))
obj.stimulus_offset_pattern = pattern;
end
%% baseline onset
if (ismember(lower(type), bon_codings))
obj.baseline_onset_pattern = pattern;
end
%% baseline offset
if (ismember(lower(type), boff_codings))
obj.baseline_offset_pattern = pattern;
end
objs(i) = obj;
end

View File

@ -0,0 +1,47 @@
function[obj] = setPatternMulti(obj, type, pattern)
%% define possible coding styles of markers
ton_codings = {'trial onset','trial on', 'start trial', 'trial start', 'trial_start'};
toff_codings = {'trial offset','trial off', 'end trial', 'trial end', 'trial_end'};
son_codings = {'stimulus onset','stimulus on', 'soa', 'stim on', 'stim_on'};
soff_codings = {'stimulus offset','stimulus off', 'stim off', 'stim_off'};
bon_codings = {'baseline on', 'baseline start', 'baseline onset', 'bl on', 'bl'};
boff_codings = {'baseline off', 'baseline end', 'baseline offset', 'bl off'};
if (ismember(lower(type), ton_codings))
ci = length(obj.trial_start_pattern) +1;
obj.trial_start_pattern(ci).pattern = pattern;
end
if (ismember(lower(type), toff_codings))
ci = length(obj.trial_end_pattern) +1;
obj.trial_end_pattern(ci).pattern = pattern;
end
%% stimulus onset
if (ismember(lower(type), son_codings))
ci = length(obj.stimulus_onset_pattern) +1;
obj.stimulus_onset_pattern(ci).pattern = pattern;
end
%% stimulus offset
if (ismember(lower(type), soff_codings))
ci = length(obj.stimulus_offset_pattern) +1;
obj.stimulus_offset_pattern(ci).pattern = pattern;
end
%% baseline onset
if (ismember(lower(type), bon_codings))
ci = length(obj.baseline_onset_pattern) +1;
obj.baseline_onset_pattern(ci).pattern = pattern;
end
%% baseline offset
if (ismember(lower(type), boff_codings))
ci = length(obj.baseline_offset_pattern) +1;
obj.baseline_offset_pattern(ci).pattern = pattern;
end

View File

@ -0,0 +1,68 @@
function[objs] = setPatternRelativeToPattern(objs, relativeTotype,type, timing)
%% Specify a new marker/pattern relative in time to an existing pattern
% time should be milliseconds (ms).
if ~isnumeric(timing)
error('Timing is not numeric');
end
ton_codings = {'trial onset','trial on', 'start trial', 'trial start', 'trial_start'};
toff_codings = {'trial offset','trial off', 'end trial', 'trial end', 'trial_end'};
son_codings = {'stimulus onset','stimulus on', 'soa', 'stim on', 'stim_on'};
soff_codings = {'stimulus offset','stimulus off', 'stim off', 'stim_off'};
bon_codings = {'baseline on', 'baseline start', 'baseline onset', 'bl on', 'bl'};
boff_codings = {'baseline off', 'baseline end', 'baseline offset', 'bl off'};
ton = ismember(lower(relativeTotype), ton_codings);
toff = ismember(lower(relativeTotype), toff_codings);
son = ismember(lower(relativeTotype), son_codings);
soff = ismember(lower(relativeTotype), soff_codings);
bon = ismember(lower(relativeTotype), bon_codings);
boff = ismember(lower(relativeTotype), boff_codings);
types = [ton toff son soff bon boff];
type_ind = find(types==1);
for i = 1:length(objs)
obj = objs(i);
if isempty(type_ind)
error('No correct type entered');
else
err=0;
switch type_ind
case 1
if (isempty(obj.trial_start_pattern)), err=1; else target = 'trial_start'; end
case 2
if (isempty(obj.trial_end_pattern)), err=1; else target = 'trial_end'; end
case 3
if (isempty(obj.stimulus_onset_pattern)), err=1; else target = 'stimulus_onset'; end
case 4
if (isempty(obj.stimulus_offset_pattern)), err=1; else target = 'stimulus_offset'; end
case 5
if (isempty(obj.baseline_onset_pattern)), err=1; else target = 'baseline_onset'; end
case 6
if (isempty(obj.baseline_offset_pattern)), err=1; else target = 'baseline_offset'; end
end
end
if err
error('Dependent type has not been defined');
end
if (ismember(lower(type), ton_codings)) obj.trial_start_pattern = {timing target}; end
if (ismember(lower(type), toff_codings)) obj.trial_end_pattern = {timing target}; end
if (ismember(lower(type), son_codings)) obj.stimulus_onset_pattern = {timing target}; end
if (ismember(lower(type), soff_codings)) obj.stimulus_onset_pattern = {timing target}; end
if (ismember(lower(type), bon_codings)) obj.baseline_onset_pattern = {timing target}; end
if (ismember(lower(type), boff_codings)) obj.baseline_offset_pattern = {timing target}; end
objs(i) = obj;
end

View File

@ -0,0 +1,7 @@
function[obj] = setSettings(obj, settings)
obj.settings = settings;
for t = 1:length(obj.trials)
obj.trials(t) = obj.trials(t).setSettings(settings);
end

View File

@ -0,0 +1,4 @@
function[obj] = setTrialStart(obj, pattern);
obj.trials = [];

View File

@ -0,0 +1,12 @@
function[obj] = smooth(obj, settings)
%% Session based smoothing
eyes = fieldnames(obj.data);
for e = 1:length(eyes)
eye = eyes{e};
if ~isempty(obj.data.(eye).uncorrected.interpolated)
obj.data.(eye).uncorrected.filtered = conv(obj.data.(eye).uncorrected.interpolated, ones(1,settings.FilterSize), 'same') / settings.FilterSize;
end
end

View File

@ -0,0 +1,38 @@
classdef PDSettings
properties
%% how to calculate the baseline value
BaselineCorrection
BaselineCorrectionPercentile
%% what type
BaselineType
FilterSize
BlinkExtension
MaximumBlinkSize
QualityThreshold
Statistics
baseline = struct('start_pattern', [], 'end_pattern',[], 'dependencies',[]);
trial = struct('start_pattern', [], 'end_pattern',[], 'dependencies',[]);
stimulus = struct('start_pattern', [],'end_pattern',[], 'dependencies',[]);
labels = struct('pattern',[], 'dependency', [], 'name',[]);
baselinecorrection_types = {'None',...
'Average', ...
'Min', ...
'Percentile', ...
'Offset (fitted line)'};
dependencies = struct;
Logfile;
end
end

View File

@ -0,0 +1,31 @@
function[obj] = load(obj, varargin)
%% Load settings from file
% this can be
% a) PDExperiment file (*_PDExp.mat)
% b) PDSettings file (*_PDSet.mat)
if nargin == 1
[fromfile fromdir]= uigetfile;
source = [fromdir filesep fromfile];
if (strfind(source,'_PDExp'))
exp_obj = load(source)
obj_tmp = exp_obj.e.settings;
if (strcmp(class(obj_tmp), 'PDSettings'))
obj = obj_tmp;
else
fields = fieldnames(obj_tmp);
for f = 1:length(fields)
obj.(fields{f}) = obj_tmp.(fields{f});
end
end
return
end
if (strfind(source, '_PDSet.mat'))
obj = load(source);
return
end
warning(sprintf('Could not load settings from file : %s', source));
end

View File

@ -0,0 +1,41 @@
classdef PDSubject
properties
index
sessions
settings
name
date
time
covariates
end
methods
function[obj] = PDSubject(varargin)
if nargin ==0
display('Select data for this subject:');
files = cellstr(uigetfile({'*.ASC;*.asc', 'Converted Eyelink text files (*.ASC)';...
'*.EDF;*.edf', 'Original Eyelink data files (*.EDF)'}, ...
'Select data for this subject', 'MultiSelect', 'on'));
for i = 1:length(files)
session = PDSession(files{i});
obj.sessions = session;
end
end
if nargin == 1
display(sprintf('Selecting sessions based on all files in: %s', varargin{1}));
obj.sessions = obj.findAllfiles(varargin{1});
if ~isempty(obj.index)
obj.name = sprintf('Subject %d', obj.index );
else
[folder topmostfolder] = fileparts(varargin{1});
obj.name = topmostfolder;
end
end
end
end
end

View File

@ -0,0 +1,53 @@
function[sessions] = findAllfiles(obj, folder)
cd(folder);
files = dir;
i=1;
sessions = PDSession(''); % create empty session
for s =1:length(files)
if (strcmp(files(s).name, '.') || strcmp(files(s).name, '..'))
continue;
end
if files(s).isdir
new_sessions = obj.findAllfiles([folder filesep files(s).name]);
for i = 1:length(new_sessions)
if ((length(sessions) ==1) && isempty(sessions(1).datafile))
sessions(length(sessions)) = new_sessions(i);
else
sessions(i + length(sessions)) = new_sessions(i);
end
end
else
[base file ext] = fileparts(files(s).name);
if strcmp(lower(ext), '.asc')
display(sprintf('\tFile found for Subject: %s', file));
if ((length(sessions) ==1) && isempty(sessions(1).datafile))
sessions(1) = PDSession([folder filesep files(s).name]);
else
sessions(end+1) = PDSession([folder filesep files(s).name]);
end
i=i+1;
end
if strcmp(lower(ext), '.gazedata')
display(sprintf('\tFile found for Subject: %s', file));
if ((length(sessions) ==1) && isempty(sessions(1).datafile))
sessions(1) = PDSession([folder filesep files(s).name]);
else
sessions(end+1) = PDSession([folder filesep files(s).name]);
end
i=i+1;
end
end
end
%% do not return empty objects
if ((length(sessions) ==1) && isempty(sessions(1).datafile))
sessions = [];
end

View File

@ -0,0 +1,10 @@
function[mats trial_ind] = getTrialMatrices(objs, varargin)
%% for all subjects, get all trials
for i = 1:length(objs)
for s = 1:length(objs(i).sessions);
[mats{i,s} trial_ind{i,s}] = objs(i).sessions(s).getTrialMatrix(varargin);
end
end

View File

@ -0,0 +1,9 @@
function[objs] = loadData(objs)
for i = 1:length(objs)
for s = 1:length(objs(i).sessions)
objs(i).sessions(s) = objs(i).sessions(s).loadData();
end
end

View File

@ -0,0 +1,6 @@
function[obj] = preprocess(obj, settings)
for s = 1:length(obj.sessions)
obj.sessions(s) = obj.sessions(s).preprocess(settings);
end
end

View File

@ -0,0 +1,14 @@
function[objs] = rebuild(objs, varargin)
p = inputParser;
addOptional(p, 'ForcePrecursorLabels',0);
p.parse(varargin);
params = p.Results;
for o = 1:length(objs)
for s = 1:length(objs(o).sessions);
objs(o).sessions(s) = objs(o).sessions(s).rebuild(params);
end
end

View File

@ -0,0 +1,5 @@
function[obj] = removeDuplicateLabels(obj)
for s = 1:length(obj.sessions)
obj.sessions(s) = obj.sessions(s).removeDuplicateLabels;
end

View File

@ -0,0 +1,8 @@
function[objs] = setFailSafePatternRelativeToPattern(objs, relativeTotype,type, timing)
%% more info should be written here
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
objs(o).sessions(s) = objs(o).sessions(s).setFailSafePatternRelativeToPattern(relativeTotype,type,timing);
end
end

View File

@ -0,0 +1,12 @@
function[objs] = setLabel(objs, type, pattern)
if nargin ==2
pattern = type;
end
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
% ignore type for now
objs(o).sessions(s) = objs(o).sessions(s).setLabel(pattern);
end
end

View File

@ -0,0 +1,12 @@
function[objs] = setLabelRelativeToLabel(objs, target, pattern, time)
if nargin ==2
pattern = type;
end
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
% ignore type for now
objs(o).sessions(s) = objs(o).sessions(s).setLabelRelativeToLabel(type, pattern);
end
end

View File

@ -0,0 +1,8 @@
function[objs] = setPattern(objs, type, pattern)
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
objs(o).sessions(s) = objs(o).sessions(s).setPattern(type, pattern);
end
end

View File

@ -0,0 +1,8 @@
function[objs] = setPatternMulti(objs, type, pattern)
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
objs(o).sessions(s) = objs(o).sessions(s).setPatternMulti(type, pattern);
end
end

View File

@ -0,0 +1,8 @@
function[objs] = setPatternRelativeToPattern(objs, relativeTotype,type, timing)
%% more info should be written here
for o = 1:length(objs)
for s = 1:length(objs(o).sessions)
objs(o).sessions(s) = objs(o).sessions(s).setPatternRelativeToPattern(relativeTotype,type,timing);
end
end

View File

@ -0,0 +1,7 @@
function[obj] = setSettings(obj, settings)
obj.settings = settings;
for s = 1:length(obj.sessions)
obj.sessions(s) = obj.sessions(s).setSettings(settings);
end

View File

@ -0,0 +1,30 @@
function[] = summary(obj, level)
%% summary of PDSubject at a certain level
%% level 0 : global info
%% level 1 : more detail
if nargin ==1
level =0;
end
display(sprintf('Summary for %d subjects:', length(obj)));
display(repmat('_',1,50));
for s = 1:length(obj)
display(sprintf('Subject: %s (%d sessions)', obj(s).name, length(obj(s).sessions)));
for p = 1:length(obj(s).sessions)
display(sprintf('\to) Session %d: %d trial(s)', p, length(obj(s).sessions(p).trials)));
if (level > 0)
for t = 1:length(obj(s).sessions(p).trials)
display(sprintf('\t\t*) trial %3d :\t%10d samples', t, length(obj(s).sessions(p).trials(t).data.uncorrected.raw)));
end
end
end
end

View File

@ -0,0 +1,16 @@
function[] = summary(obj)
display(sprintf('Summary for %d subjects:', length(obj)));
display(repmat('_',1,50));
for s = 1:length(obj)
display(sprintf('\tSubject: %s', obj(s).name));
display(sprintf('\t%d sessions:', length(obj(s).sessions)));
for p = 1:length(obj(s).sessions)
display(sprintf('\tSession %d: %d trial(s)', p, length(obj(s).sessions(p).trials)));
end
end

View File

@ -0,0 +1,47 @@
classdef PDTrial
properties
session
time
data
trial_start
trial_end
baseline_onset
baseline_offset
baseline
stimulus_onset
stimulus_offset
markers
labels
quality
valid
type
stats %% q1, q2,q3, fit, etc.
blink_count
missing_data_count
blinks
% required for plotting
settings
% pupil deconvolution
deconvolution
end
methods
function[obj] = PDTrial(varargin)
data = struct('raw', [], 'interpolated', [],'filtered',[], 'logtransformed',[],'baseline',[]);
eye = struct('uncorrected', data,'baseline_corrected', data);
obj.data = struct('left', eye,'right', eye);
end
end
end

View File

@ -0,0 +1,66 @@
function[trials] = calculate_statistics(trials)
item_struct = struct('time', [], 'value', []);
stats_struct = struct('max', item_struct, ...
'mean', [], ...
'median', [], ...
'mode', [], ...
'std', [], ...
'q1', [],...
'q2', [],...
'q3', [],...
'auc', []);
for t = 1:length(trials)
trial = trials(t);
eyes = fieldnames(trial.data);
for e = 1:length(eyes)
try
eye = eyes{e};
trial.stats.(eye) = stats_struct;
signal = trial.data.(eye).baseline_corrected.filtered;
if isempty(signal)
continue;
end
% only relevant after stimulus onset
trial_after_so = trial.data.(eye).baseline_corrected.filtered(find(trial.time > trial.stimulus_onset));
trial_before_so = trial.data.(eye).baseline_corrected.filtered(find(trial.time <= trial.stimulus_onset));
% calculate stats from trial trace
max_after_so = max(trial_after_so);
max_ind = length(trial_before_so) + find(trial_after_so==max_after_so);
delta_t = trial.time(max_ind(1)) - trial.stimulus_onset;
mean_after_so = mean(trial_after_so);
std_after_so = std(trial_after_so);
mode_after_so = mode(trial_after_so);
median_after_so = median(trial_after_so);
q1 = prctile(trial_after_so, 25);
q2 = median_after_so;
q3 = prctile(trial_after_so, 75);
% store values in trial
trial.stats.(eye).max.value = max_after_so;
trial.stats.(eye).max.time = delta_t;
trial.stats.(eye).median = median_after_so;
trial.stats.(eye).mean = mean_after_so;
trial.stats.(eye).std = std_after_so;
trial.stats.(eye).mode = mode_after_so;
trial.stats.(eye).q1 = q1;
trial.stats.(eye).q2 = q2;
trial.stats.(eye).q3 = q3;
trial.stats.(eye).auc = trapz(trial_after_so);
catch
warning('No statistics generated for trial');
end
end
% store trial back in array
trials(t) = trial;
end
end

View File

@ -0,0 +1,28 @@
function[obj] = correct_for_baseline(obj, settings)
%% correction for baseline measure
% The actual baseline is calculated in getBaseline
eyes = fieldnames(obj.data);
for e = 1:length(eyes)
eye = eyes{e};
signals = fieldnames(obj.data.(eye).uncorrected);
baseline = getBaseline(obj, settings);
obj.baseline = baseline;
for i = 1:length(signals)
signal = getfield(obj.data.(eye).uncorrected, signals{i});
if (~isnan(baseline))
%% apply the correction
corrected_signal = (signal - baseline) / baseline;
else
%% no correction is applied
corrected_signal = signal;
end
obj.data.(eye).baseline_corrected = setfield(obj.data.(eye).baseline_corrected, signals{i}, corrected_signal);
end
end

View File

@ -0,0 +1,32 @@
function[obj] = deconvolve(obj, settings)
%% Perform pupil deconvolution based on the methods
% described in Wierda et al PNAS 2012
o=optimset;
o.MaxFunEvals = 10000;
o.MaxIter = 10000;
fs = 50; % Hz downsampling
y = obj.data.baseline_corrected.interpolated;
t_orig = obj.time;
nt = round((t_orig(end) - t_orig(1)) / (1000/fs));
t_ds = linspace(t_orig(1), t_orig(end), nt);
yq = interp1(t_orig, y, t_ds);
obj.deconvolution.time = t_ds;
obj.deconvolution.input = yq;
init_params = [ 1 zeros(1,length(obj.labels)-1) ];
init_slope = (obj.deconvolution.input(end) -obj.deconvolution.input(1)) / length(t_ds);
%% perform search with initial params : slope = 0; pulse weight 1
final_params = fminsearch(@obj.evaluate_model, [init_slope init_params], o);
obj.deconvolution.params = final_params;
obj.deconvolution.output = obj.prf_convolve(obj.stick_model(final_params(2:end)),final_params(1));

Some files were not shown because too many files have changed in this diff Show More