init
This commit is contained in:
BIN
PDToolkit/.DS_Store
vendored
Normal file
BIN
PDToolkit/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
PDToolkit/@PDExperiment/.DS_Store
vendored
Normal file
BIN
PDToolkit/@PDExperiment/.DS_Store
vendored
Normal file
Binary file not shown.
87
PDToolkit/@PDExperiment/PDExperiment.m
Normal file
87
PDToolkit/@PDExperiment/PDExperiment.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
108
PDToolkit/@PDExperiment/add_aggregate.m
Normal file
108
PDToolkit/@PDExperiment/add_aggregate.m
Normal 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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
45
PDToolkit/@PDExperiment/askForBaseline.m
Normal file
45
PDToolkit/@PDExperiment/askForBaseline.m
Normal 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
|
||||||
|
|
||||||
17
PDToolkit/@PDExperiment/buildExperiment.m
Normal file
17
PDToolkit/@PDExperiment/buildExperiment.m
Normal 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;
|
||||||
155
PDToolkit/@PDExperiment/build_averages.m
Normal file
155
PDToolkit/@PDExperiment/build_averages.m
Normal 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');
|
||||||
|
|
||||||
104
PDToolkit/@PDExperiment/calculate_aggregate.m
Normal file
104
PDToolkit/@PDExperiment/calculate_aggregate.m
Normal 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;
|
||||||
|
|
||||||
7
PDToolkit/@PDExperiment/calculate_aggregates.m
Normal file
7
PDToolkit/@PDExperiment/calculate_aggregates.m
Normal 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
|
||||||
6
PDToolkit/@PDExperiment/consolidateSettings.m
Normal file
6
PDToolkit/@PDExperiment/consolidateSettings.m
Normal 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
|
||||||
51
PDToolkit/@PDExperiment/enable_selection_edit.m
Normal file
51
PDToolkit/@PDExperiment/enable_selection_edit.m
Normal 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);
|
||||||
69
PDToolkit/@PDExperiment/evaluate_selection.m
Normal file
69
PDToolkit/@PDExperiment/evaluate_selection.m
Normal 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);
|
||||||
189
PDToolkit/@PDExperiment/export_data.m
Normal file
189
PDToolkit/@PDExperiment/export_data.m
Normal 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
|
||||||
|
|
||||||
224
PDToolkit/@PDExperiment/export_stats.m
Normal file
224
PDToolkit/@PDExperiment/export_stats.m
Normal 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
|
||||||
|
|
||||||
18
PDToolkit/@PDExperiment/getIndexFromSubjectName.m
Normal file
18
PDToolkit/@PDExperiment/getIndexFromSubjectName.m
Normal 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
|
||||||
7
PDToolkit/@PDExperiment/get_aggregate_data.m
Normal file
7
PDToolkit/@PDExperiment/get_aggregate_data.m
Normal 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
|
||||||
|
|
||||||
38
PDToolkit/@PDExperiment/get_trials_based_on_label.m
Normal file
38
PDToolkit/@PDExperiment/get_trials_based_on_label.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
22
PDToolkit/@PDExperiment/info.m
Normal file
22
PDToolkit/@PDExperiment/info.m
Normal 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
|
||||||
141
PDToolkit/@PDExperiment/information.txt
Normal file
141
PDToolkit/@PDExperiment/information.txt
Normal 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
|
||||||
802
PDToolkit/@PDExperiment/multiWaitbar.m
Normal file
802
PDToolkit/@PDExperiment/multiWaitbar.m
Normal 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
|
||||||
41
PDToolkit/@PDExperiment/onClickPlotAxes.m
Normal file
41
PDToolkit/@PDExperiment/onClickPlotAxes.m
Normal 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);
|
||||||
12
PDToolkit/@PDExperiment/onDataPointClick.m
Normal file
12
PDToolkit/@PDExperiment/onDataPointClick.m
Normal 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'};
|
||||||
154
PDToolkit/@PDExperiment/plot.m
Normal file
154
PDToolkit/@PDExperiment/plot.m
Normal 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;
|
||||||
9
PDToolkit/@PDExperiment/plot_aggregate.m
Normal file
9
PDToolkit/@PDExperiment/plot_aggregate.m
Normal 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);
|
||||||
28
PDToolkit/@PDExperiment/plot_aggregates.m
Normal file
28
PDToolkit/@PDExperiment/plot_aggregates.m
Normal 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
|
||||||
18
PDToolkit/@PDExperiment/preprocess.m
Normal file
18
PDToolkit/@PDExperiment/preprocess.m
Normal 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
|
||||||
6
PDToolkit/@PDExperiment/removeDuplicateLabels.m
Normal file
6
PDToolkit/@PDExperiment/removeDuplicateLabels.m
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
function[obj] = removeDuplicateLabels(obj)
|
||||||
|
|
||||||
|
|
||||||
|
for s = 1:length(obj.subjects)
|
||||||
|
obj.subjects(s) = obj.subjects(s).removeDuplicateLabels;
|
||||||
|
end
|
||||||
16
PDToolkit/@PDExperiment/remove_aggregate.m
Normal file
16
PDToolkit/@PDExperiment/remove_aggregate.m
Normal 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;
|
||||||
26
PDToolkit/@PDExperiment/select_aggregate.m
Normal file
26
PDToolkit/@PDExperiment/select_aggregate.m
Normal 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);
|
||||||
|
|
||||||
|
|
||||||
36
PDToolkit/@PDExperiment/setPlotOptions.m
Normal file
36
PDToolkit/@PDExperiment/setPlotOptions.m
Normal 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);
|
||||||
1
PDToolkit/@PDExperiment/setTrialStart.m
Normal file
1
PDToolkit/@PDExperiment/setTrialStart.m
Normal file
@@ -0,0 +1 @@
|
|||||||
|
function[obj] = setTrialStart(pattern)
|
||||||
23
PDToolkit/@PDExperiment/set_plot_sess.m
Normal file
23
PDToolkit/@PDExperiment/set_plot_sess.m
Normal 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));
|
||||||
|
|
||||||
22
PDToolkit/@PDExperiment/set_plot_session_trial_edit.m
Normal file
22
PDToolkit/@PDExperiment/set_plot_session_trial_edit.m
Normal 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));
|
||||||
22
PDToolkit/@PDExperiment/set_plot_subj.m
Normal file
22
PDToolkit/@PDExperiment/set_plot_subj.m
Normal 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);
|
||||||
|
|
||||||
37
PDToolkit/@PDExperiment/set_plot_subject.m
Normal file
37
PDToolkit/@PDExperiment/set_plot_subject.m
Normal 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));
|
||||||
|
|
||||||
|
|
||||||
27
PDToolkit/@PDExperiment/set_plot_trial_edit.m
Normal file
27
PDToolkit/@PDExperiment/set_plot_trial_edit.m
Normal 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));
|
||||||
|
|
||||||
23
PDToolkit/@PDExperiment/set_plot_trial_slider.m
Normal file
23
PDToolkit/@PDExperiment/set_plot_trial_slider.m
Normal 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));
|
||||||
47
PDToolkit/@PDExperiment/statistics.m
Normal file
47
PDToolkit/@PDExperiment/statistics.m
Normal 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
|
||||||
10
PDToolkit/@PDExperiment/togglePlotOptions.m
Normal file
10
PDToolkit/@PDExperiment/togglePlotOptions.m
Normal 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
|
||||||
25
PDToolkit/@PDExperiment/update_aggregates.m
Normal file
25
PDToolkit/@PDExperiment/update_aggregates.m
Normal 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, []);
|
||||||
18
PDToolkit/@PDParser/PDParser.m
Normal file
18
PDToolkit/@PDParser/PDParser.m
Normal 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
|
||||||
25
PDToolkit/@PDParser/import.m
Normal file
25
PDToolkit/@PDParser/import.m
Normal 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
|
||||||
19
PDToolkit/@PDParser/importData.m
Normal file
19
PDToolkit/@PDParser/importData.m
Normal 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
BIN
PDToolkit/@PDSession/.DS_Store
vendored
Normal file
Binary file not shown.
49
PDToolkit/@PDSession/PDSession.m
Normal file
49
PDToolkit/@PDSession/PDSession.m
Normal 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
|
||||||
27
PDToolkit/@PDSession/check_patterns.m
Normal file
27
PDToolkit/@PDSession/check_patterns.m
Normal 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
|
||||||
|
|
||||||
18
PDToolkit/@PDSession/deconvolve.m
Normal file
18
PDToolkit/@PDSession/deconvolve.m
Normal 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
|
||||||
20
PDToolkit/@PDSession/display_and_log.m
Normal file
20
PDToolkit/@PDSession/display_and_log.m
Normal 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);
|
||||||
136
PDToolkit/@PDSession/getTimeLockedTrialMatrix.m
Normal file
136
PDToolkit/@PDSession/getTimeLockedTrialMatrix.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
90
PDToolkit/@PDSession/getTrialMatrix.m
Normal file
90
PDToolkit/@PDSession/getTrialMatrix.m
Normal 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
|
||||||
24
PDToolkit/@PDSession/importData.m
Normal file
24
PDToolkit/@PDSession/importData.m
Normal 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
|
||||||
450
PDToolkit/@PDSession/information.txt
Normal file
450
PDToolkit/@PDSession/information.txt
Normal 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
|
||||||
99
PDToolkit/@PDSession/label.m
Normal file
99
PDToolkit/@PDSession/label.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
11
PDToolkit/@PDSession/load.m
Normal file
11
PDToolkit/@PDSession/load.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
11
PDToolkit/@PDSession/loadData.m
Normal file
11
PDToolkit/@PDSession/loadData.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
86
PDToolkit/@PDSession/load_data_from_text.m
Normal file
86
PDToolkit/@PDSession/load_data_from_text.m
Normal 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
|
||||||
|
|
||||||
40
PDToolkit/@PDSession/mean.m
Normal file
40
PDToolkit/@PDSession/mean.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
33
PDToolkit/@PDSession/patternBuilder.m
Normal file
33
PDToolkit/@PDSession/patternBuilder.m
Normal 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')
|
||||||
|
|
||||||
|
|
||||||
14
PDToolkit/@PDSession/plotTrialBasedonPattern.m
Normal file
14
PDToolkit/@PDSession/plotTrialBasedonPattern.m
Normal 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
|
||||||
22
PDToolkit/@PDSession/preprocess.m
Normal file
22
PDToolkit/@PDSession/preprocess.m
Normal 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
|
||||||
101
PDToolkit/@PDSession/read_ASC.m
Normal file
101
PDToolkit/@PDSession/read_ASC.m
Normal 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
|
||||||
93
PDToolkit/@PDSession/read_gazedata.m
Normal file
93
PDToolkit/@PDSession/read_gazedata.m
Normal 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
|
||||||
94
PDToolkit/@PDSession/read_gazedata.m~
Normal file
94
PDToolkit/@PDSession/read_gazedata.m~
Normal 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
|
||||||
234
PDToolkit/@PDSession/rebuild.m
Normal file
234
PDToolkit/@PDSession/rebuild.m
Normal 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
|
||||||
269
PDToolkit/@PDSession/rebuildMulti.m
Normal file
269
PDToolkit/@PDSession/rebuildMulti.m
Normal 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)));
|
||||||
|
|
||||||
6
PDToolkit/@PDSession/removeDuplicateLabels.m
Normal file
6
PDToolkit/@PDSession/removeDuplicateLabels.m
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
function[obj] = removeDuplicateLabels(obj)
|
||||||
|
|
||||||
|
|
||||||
|
for t = 1:length(obj.trials)
|
||||||
|
obj.trials(t) = obj.trials(t).removeDuplicateLabels;
|
||||||
|
end
|
||||||
76
PDToolkit/@PDSession/remove_blinks.m
Normal file
76
PDToolkit/@PDSession/remove_blinks.m
Normal 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
|
||||||
100
PDToolkit/@PDSession/setFailSafePatternRelativeToPattern.m
Normal file
100
PDToolkit/@PDSession/setFailSafePatternRelativeToPattern.m
Normal 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
|
||||||
16
PDToolkit/@PDSession/setFramerate.m
Normal file
16
PDToolkit/@PDSession/setFramerate.m
Normal 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
|
||||||
|
|
||||||
35
PDToolkit/@PDSession/setLabel.m
Normal file
35
PDToolkit/@PDSession/setLabel.m
Normal 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
|
||||||
17
PDToolkit/@PDSession/setLabelRelativeToLabel.m
Normal file
17
PDToolkit/@PDSession/setLabelRelativeToLabel.m
Normal 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};
|
||||||
|
|
||||||
|
|
||||||
17
PDToolkit/@PDSession/setLabelRelativeToPattern.m
Normal file
17
PDToolkit/@PDSession/setLabelRelativeToPattern.m
Normal 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};
|
||||||
|
|
||||||
|
|
||||||
50
PDToolkit/@PDSession/setPattern.m
Normal file
50
PDToolkit/@PDSession/setPattern.m
Normal 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
|
||||||
|
|
||||||
47
PDToolkit/@PDSession/setPatternMulti.m
Normal file
47
PDToolkit/@PDSession/setPatternMulti.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
68
PDToolkit/@PDSession/setPatternRelativeToPattern.m
Normal file
68
PDToolkit/@PDSession/setPatternRelativeToPattern.m
Normal 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
|
||||||
7
PDToolkit/@PDSession/setSettings.m
Normal file
7
PDToolkit/@PDSession/setSettings.m
Normal 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
|
||||||
4
PDToolkit/@PDSession/setTrialStart.m
Normal file
4
PDToolkit/@PDSession/setTrialStart.m
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
function[obj] = setTrialStart(obj, pattern);
|
||||||
|
|
||||||
|
obj.trials = [];
|
||||||
|
|
||||||
12
PDToolkit/@PDSession/smooth.m
Normal file
12
PDToolkit/@PDSession/smooth.m
Normal 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
|
||||||
|
|
||||||
38
PDToolkit/@PDSettings/PDSettings.m
Normal file
38
PDToolkit/@PDSettings/PDSettings.m
Normal 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
|
||||||
31
PDToolkit/@PDSettings/load.m
Normal file
31
PDToolkit/@PDSettings/load.m
Normal 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
|
||||||
41
PDToolkit/@PDSubject/PDSubject.m
Normal file
41
PDToolkit/@PDSubject/PDSubject.m
Normal 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
|
||||||
53
PDToolkit/@PDSubject/findAllfiles.m
Normal file
53
PDToolkit/@PDSubject/findAllfiles.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
10
PDToolkit/@PDSubject/getTrialMatrices.m
Normal file
10
PDToolkit/@PDSubject/getTrialMatrices.m
Normal 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
|
||||||
9
PDToolkit/@PDSubject/loadData.m
Normal file
9
PDToolkit/@PDSubject/loadData.m
Normal 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
|
||||||
|
|
||||||
6
PDToolkit/@PDSubject/preprocess.m
Normal file
6
PDToolkit/@PDSubject/preprocess.m
Normal 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
|
||||||
14
PDToolkit/@PDSubject/rebuild.m
Normal file
14
PDToolkit/@PDSubject/rebuild.m
Normal 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
|
||||||
5
PDToolkit/@PDSubject/removeDuplicateLabels.m
Normal file
5
PDToolkit/@PDSubject/removeDuplicateLabels.m
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
function[obj] = removeDuplicateLabels(obj)
|
||||||
|
|
||||||
|
for s = 1:length(obj.sessions)
|
||||||
|
obj.sessions(s) = obj.sessions(s).removeDuplicateLabels;
|
||||||
|
end
|
||||||
@@ -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
|
||||||
12
PDToolkit/@PDSubject/setLabel.m
Normal file
12
PDToolkit/@PDSubject/setLabel.m
Normal 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
|
||||||
12
PDToolkit/@PDSubject/setLabelRelativeToLabel.m
Normal file
12
PDToolkit/@PDSubject/setLabelRelativeToLabel.m
Normal 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
|
||||||
8
PDToolkit/@PDSubject/setPattern.m
Normal file
8
PDToolkit/@PDSubject/setPattern.m
Normal 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
|
||||||
8
PDToolkit/@PDSubject/setPatternMulti.m
Normal file
8
PDToolkit/@PDSubject/setPatternMulti.m
Normal 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
|
||||||
8
PDToolkit/@PDSubject/setPatternRelativeToPattern.m
Normal file
8
PDToolkit/@PDSubject/setPatternRelativeToPattern.m
Normal 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
|
||||||
7
PDToolkit/@PDSubject/setSettings.m
Normal file
7
PDToolkit/@PDSubject/setSettings.m
Normal 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
|
||||||
30
PDToolkit/@PDSubject/summary.m
Normal file
30
PDToolkit/@PDSubject/summary.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
PDToolkit/@PDSubject/untitled.m
Normal file
16
PDToolkit/@PDSubject/untitled.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
47
PDToolkit/@PDTrial/PDTrial.m
Normal file
47
PDToolkit/@PDTrial/PDTrial.m
Normal 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
|
||||||
|
|
||||||
|
|
||||||
66
PDToolkit/@PDTrial/calculate_statistics.m
Normal file
66
PDToolkit/@PDTrial/calculate_statistics.m
Normal 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
|
||||||
28
PDToolkit/@PDTrial/correct_for_baseline.m
Normal file
28
PDToolkit/@PDTrial/correct_for_baseline.m
Normal 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
|
||||||
|
|
||||||
32
PDToolkit/@PDTrial/deconvolve.m
Normal file
32
PDToolkit/@PDTrial/deconvolve.m
Normal 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
Reference in New Issue
Block a user