init
This commit is contained in:
		
							
								
								
									
										
											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, []); | ||||
		Reference in New Issue
	
	Block a user