init
This commit is contained in:
parent
1edacb997d
commit
d2cf032fab
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
Loading…
x
Reference in New Issue
Block a user